簡體   English   中英

Tkinter類結構(每幀類)與小部件復制有關

[英]Tkinter Class structure (class per frame) issue with duplicating widgets

我一直在嘗試將OOP與Tkinter一起使用-我正在慢慢到達那里(我認為)...

我想構建一個結構,其中每個框架都由其自己的類處理,包括其所有小部件和功能。 也許我是從錯誤的角度出發的,但這對我來說是最合乎邏輯的。 -隨時告訴我您是否同意!

我知道為什么會發生問題-當我調用每個類時,我的__init__每次都會運行並構建相關的小部件,無論它們是否已存在於框架中。 但是,我能想到的唯一方法是在主類GUI_Start__init__中構建每個框架。 -盡管這看起來像是一個雜亂無章的解決方案。

有沒有辦法實現一種結構,使每個類都負責自己的功能和小部件,但不必每次都構建框架?

請參閱以下問題的最小示例:

from Tkinter import *

class GUI_Start:

    def __init__(self, master):
        self.master = master
        self.master.geometry('300x300')
        self.master.grid_rowconfigure(0, weight=1)
        self.master.grid_columnconfigure(0, weight=1)
        self.win_colour = '#D2B48C'
        self.frames = {}

        for window in ['win1', 'win2']:
            frame = Frame(self.master, bg=self.win_colour, bd=10, relief=GROOVE)
            frame.grid(row=0, column=0, sticky='news')
            setattr(self, window, frame)
            self.frames[window] = frame

        Page_1(self.frames)

    def Next_Page(self, frames, controller):
        controller(frames)


class Page_1(GUI_Start):

    def __init__(self, master):
        self.master = master
        self.master['win1'].tkraise()

        page1_label = Label(self.master['win1'], text='PAGE 1')
        page1_label.pack(fill=X)

        page1_button = Button(self.master['win1'], text='Visit Page 2...', command=lambda: self.Next_Page(self.master, Page_2))
        page1_button.pack(fill=X, side=BOTTOM)


class Page_2(GUI_Start):

    def __init__(self, master):
        self.master = master
        self.master['win2'].tkraise()

        page2_label = Label(self.master['win2'], text='PAGE 2')
        page2_label.pack(fill=X)

        page2_button = Button(self.master['win2'], text='Back to Page 1...', command=lambda: self.Next_Page(self.master, Page_1))
        page2_button.pack(fill=X, side=BOTTOM)


root = Tk()
gui = GUI_Start(root)
root.mainloop()

隨意批評結構,因為我可能嘗試從錯誤的角度進行研究!

任何反饋將不勝感激! 路加

使用類的重點是將一堆行為封裝為一個單元。 對象不應該修改自身之外的任何內容。 至少,不是通過簡單地創建對象,而是可以使用具有副作用的方法。

我認為,創建“頁面”的正確方法是從Frame繼承。 屬於“頁面”的所有小部件都必須具有對象本身作為其父對象。 例如:

class PageOne(tk.Frame):
    def __init__(self, parent):
        # use the __init__ of the superclass to create the actual frame
        tk.Frame.__init__(self, parent)

        # all other widgets use self (or some descendant of self)
        # as their parent

        self.label = tk.Label(self, ...)
        self.button = tk.Button(self, ...)
        ...

完成后,可以將此類的實例視為單個窗口小部件:

root = tk.Tk()
page1 = PageOne(root)
page1.pack(fill="both", expand=True)

如果您的所有頁面都有共同點(例如,頁眉或頁腳),您還可以創建一個基類Page ,並讓您的實際頁面繼承自該類。

class Page(tk.Frame):
    def __init__(self, parent):
        tk.Frame.__init__(self, parent)
        <code common to all pages goes here>

class PageOne(Page):
    def __init__(self, parent):
        # initialize the parent class
        Page.__init__(self, parent)

        <code unique to page one goes here>

您在這里對OOP的使用不是很合邏輯。 您的主程序在GUI_start類中。 如果您的頁面是從GUI_start繼承的,則基本上您會使用創建的每個頁面實例創建一個全新的程序。 您應該改從Frame繼承,因為Bryan Oakley在評論中指出了我們的觀點。 這是您所發布內容的某種修復版本。 布萊恩(Bryan)創作的第一張仍然更好。

from Tkinter import *

class GUI_Start:

    def __init__(self, master):
        self.master = master
        self.master.geometry('300x300')
        self.master.grid_rowconfigure(0, weight=1)
        self.master.grid_columnconfigure(0, weight=1)
        self.win_colour = '#D2B48C'
        self.current_page=0

        self.pages = []
        for i in range(5):
            page = Page(self.master,i+1)
            page.grid(row=0,column=0,sticky='nsew')
            self.pages.append(page)

        for i in range(2):
            page = Page_diff(self.master,i+1)
            page.grid(row=0,column=0,sticky='nsew')
            self.pages.append(page)

        self.pages[0].tkraise()

        def Next_Page():
            next_page_index = self.current_page+1
            if next_page_index >= len(self.pages):
                next_page_index = 0
            print(next_page_index)
            self.pages[next_page_index].tkraise()
            self.current_page = next_page_index

        page1_button = Button(self.master, text='Visit next Page',command = Next_Page)
        page1_button.grid(row=1,column=0)



class Page(Frame):

    def __init__(self,master,number):
        super().__init__(master,bg='#D2B48C')
        self.master = master
        self.master.tkraise()

        page1_label = Label(self, text='PAGE '+str(number))
        page1_label.pack(fill=X,expand=True)



class Page_diff(Frame):

    def __init__(self,master,number):
        super().__init__(master)
        self.master = master
        self.master.tkraise()

        page1_label = Label(self, text='I am different PAGE '+str(number))
        page1_label.pack(fill=X)



root = Tk()
gui = GUI_Start(root)
root.mainloop()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM