Python、tkinter、复杂对话框和代码结构

Python、tkinter、复杂对话框和代码结构,python,tkinter,dialog,code-structure,Python,Tkinter,Dialog,Code Structure,当实现复杂的对话框(即,带有大约10个或更多小部件的对话框,特别是当在多个帧或类似帧中排列时),创建需要许多tkinter调用,并且当代码保存在单个方法中时,代码可能变得越来越复杂(难以读取和维护)。通常,短函数/方法比长函数/方法更可取 我目前限制方法长度的方法是将属于对话框中某个组的所有小部件的创建封装到一个方法(父\u框架,其他\u选项),该方法返回顶级小部件,如下所示: import tkinter as tk class Dialog: def __init__(self,

当实现复杂的对话框(即,带有大约10个或更多小部件的对话框,特别是当在多个帧或类似帧中排列时),创建需要许多tkinter调用,并且当代码保存在单个方法中时,代码可能变得越来越复杂(难以读取和维护)。通常,短函数/方法比长函数/方法更可取

我目前限制方法长度的方法是将属于对话框中某个组的所有小部件的创建封装到一个
方法(父\u框架,其他\u选项)
,该方法返回顶级小部件,如下所示:

import tkinter as tk

class Dialog:
    def __init__(self, master):
        self.__master = master
        self.create_gui(master)

    def create_gui(self, frame, title = None):
        if title:  frame.title(title)

        group_a = self.create_group_a(frame)
        group_a.grid(row=0, column=0, sticky="nsew")

        group_b = self.create_group_b(frame)
        group_b.grid(row=1, column=0, sticky="nsew")

        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        frame.rowconfigure(1, weight=1)

    def create_group_a(self, frame):
        inner_frame = tk.LabelFrame(frame, text="Label")
        text = self.create_text_with_scrollbar(inner_frame)
        text.pack(fill="both")
        return inner_frame

    def create_group_b(self, frame):
        button = tk.Button(frame, text="Button")
        return button

    def create_text_with_scrollbar(self, frame):
        text_frame = tk.Frame(frame)
        text_frame.grid_rowconfigure(0, weight=1)
        text_frame.grid_columnconfigure(0, weight=1)

        text = tk.Text(text_frame)
        text.grid(row=0, column=0, sticky="nsew")

        scrollbar = tk.Scrollbar(text_frame, command=text.yview)
        scrollbar.grid(row=0, column=1, sticky="nsew")
        text['yscrollcommand'] = scrollbar.set

        return text_frame


if __name__ == "__main__":
    master = tk.Tk()
    Dialog(master)
    tk.mainloop()
class MainFrame(Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self.first_sub = FirstSubFrame(self)
        self.second_sub = SecondSubFrame(self)

        self.first_sub.grid()
        self.second_sub.grid()


class FirstSubFrame(Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self.possibly_another_subframe = PossibleOtherFrame(self)
        self.awesome_button = tkinter.Button()

        self.possibly_another_subframe.grid()
        self.awesome_button.grid()

...

在这种情况下,是否有关于代码结构的具体指导方针?有人对如何更好地构造这样的代码有什么建议吗?

我通常做的是为每个组编写一个新类。 这些类从框架继承。 最终结果如下所示:

import tkinter as tk

class Dialog:
    def __init__(self, master):
        self.__master = master
        self.create_gui(master)

    def create_gui(self, frame, title = None):
        if title:  frame.title(title)

        group_a = self.create_group_a(frame)
        group_a.grid(row=0, column=0, sticky="nsew")

        group_b = self.create_group_b(frame)
        group_b.grid(row=1, column=0, sticky="nsew")

        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        frame.rowconfigure(1, weight=1)

    def create_group_a(self, frame):
        inner_frame = tk.LabelFrame(frame, text="Label")
        text = self.create_text_with_scrollbar(inner_frame)
        text.pack(fill="both")
        return inner_frame

    def create_group_b(self, frame):
        button = tk.Button(frame, text="Button")
        return button

    def create_text_with_scrollbar(self, frame):
        text_frame = tk.Frame(frame)
        text_frame.grid_rowconfigure(0, weight=1)
        text_frame.grid_columnconfigure(0, weight=1)

        text = tk.Text(text_frame)
        text.grid(row=0, column=0, sticky="nsew")

        scrollbar = tk.Scrollbar(text_frame, command=text.yview)
        scrollbar.grid(row=0, column=1, sticky="nsew")
        text['yscrollcommand'] = scrollbar.set

        return text_frame


if __name__ == "__main__":
    master = tk.Tk()
    Dialog(master)
    tk.mainloop()
class MainFrame(Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self.first_sub = FirstSubFrame(self)
        self.second_sub = SecondSubFrame(self)

        self.first_sub.grid()
        self.second_sub.grid()


class FirstSubFrame(Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self.possibly_another_subframe = PossibleOtherFrame(self)
        self.awesome_button = tkinter.Button()

        self.possibly_another_subframe.grid()
        self.awesome_button.grid()

...

我希望这有帮助。

我通常做的是为每个小组写一个新的类。 这些类从框架继承。 最终结果如下所示:

import tkinter as tk

class Dialog:
    def __init__(self, master):
        self.__master = master
        self.create_gui(master)

    def create_gui(self, frame, title = None):
        if title:  frame.title(title)

        group_a = self.create_group_a(frame)
        group_a.grid(row=0, column=0, sticky="nsew")

        group_b = self.create_group_b(frame)
        group_b.grid(row=1, column=0, sticky="nsew")

        frame.columnconfigure(0, weight=1)
        frame.rowconfigure(0, weight=1)
        frame.rowconfigure(1, weight=1)

    def create_group_a(self, frame):
        inner_frame = tk.LabelFrame(frame, text="Label")
        text = self.create_text_with_scrollbar(inner_frame)
        text.pack(fill="both")
        return inner_frame

    def create_group_b(self, frame):
        button = tk.Button(frame, text="Button")
        return button

    def create_text_with_scrollbar(self, frame):
        text_frame = tk.Frame(frame)
        text_frame.grid_rowconfigure(0, weight=1)
        text_frame.grid_columnconfigure(0, weight=1)

        text = tk.Text(text_frame)
        text.grid(row=0, column=0, sticky="nsew")

        scrollbar = tk.Scrollbar(text_frame, command=text.yview)
        scrollbar.grid(row=0, column=1, sticky="nsew")
        text['yscrollcommand'] = scrollbar.set

        return text_frame


if __name__ == "__main__":
    master = tk.Tk()
    Dialog(master)
    tk.mainloop()
class MainFrame(Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self.first_sub = FirstSubFrame(self)
        self.second_sub = SecondSubFrame(self)

        self.first_sub.grid()
        self.second_sub.grid()


class FirstSubFrame(Frame):
    def __init__(self, *args, **kwargs):
        super().__init__(self, *args, **kwargs)
        self.possibly_another_subframe = PossibleOtherFrame(self)
        self.awesome_button = tkinter.Button()

        self.possibly_another_subframe.grid()
        self.awesome_button.grid()

...

我希望这有帮助。

谢谢!Brian Oakley还从中的Tkinter类继承了他的类。然而,对于他的回答(来自Shule)有一条评论指出,在某些情况下,最好不要继承框架等,而是拥有一个框架成员。我的直觉告诉我同样的道理,但我无法解释原因。这也是当初提出这个问题的原因之一。我会更新问题。不,我不会更新问题。“是否从tkinter类继承”这个问题本身就是一个已经讨论过的话题,例如:这里:。谢谢!Brian Oakley还从中的Tkinter类继承了他的类。然而,对于他的回答(来自Shule)有一条评论指出,在某些情况下,最好不要继承框架等,而是拥有一个框架成员。我的直觉告诉我同样的道理,但我无法解释原因。这也是当初提出这个问题的原因之一。我会更新问题。不,我不会更新问题。“是否从tkinter类继承”这个问题本身就是一个已经讨论过的主题,例如,这里:。