初始化 tkinter 类的父级/主控是什么?

2024-02-27

Note

示例代码是一个删节版本,但可以运行基本功能。请重点关注class MainWindow(tk.Frame)

问题

什么样的object可以起到parent or master for tkinter class初始化?

我的例子,看示例代码,为什么不能通过self as parent to ProjectInfo(...) or ConfirmItems(...) in class MainWindow(tk.Frame)?如果使用它会弹出一个空窗口self代替self.parent.

参考

这个问题源于我的评论构建 tkinter 应用程序的最佳方式 https://stackoverflow.com/a/17470842,这意味着它无法通过self as parent.

我想在讨论之后提出一个新问题。

import tkinter as tk
from tkinter import messagebox
from collections import OrderedDict

class ProjectInfo(tk.Frame):
    def __init__(self, parent, controller, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent
        self.controller = controller
        self.widgets_init()

    def widgets_init(self):
        tk.Label(self,
                    text = "Rock Controller!",
                    width = 10,
                    anchor = "w",
                    justify = "left").grid(row = 0, column = 0)
        tk.Label(self,
                    text = "Input Name: ").grid(row = 1, column = 0)
        self.entry = tk.Entry(self)
        self.entry.grid(row = 1, column = 1)

class ConfirmItems(tk.Frame):
    def __init__(self, parent, frames, controller, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent
        self.frames = frames
        self.controller = controller
        self.widgets_init()

    def update_entries(self):
        self.controller.project_info.name = self.controller.project_info.entry.get()

    def update_frames(self):
        self.message = 'Click Cancel go back to reset!\n'
        for key, values in self.frames.items():
            for v in values:
                x = getattr(key, v)
                self.message += v + ': ' + str(x) + '\n'

    def show_settings(self):
        answer = tk.messagebox.askokcancel("Check Settings", self.message)
        if answer in ["yes", 1]:
            self.quit()

    def combine_funcs(self, *funcs):
        def combined_func(*args, **kwargs):
            for f in funcs:
                f(*args, **kwargs)
        return combined_func

    def widgets_init(self):
        self.cancel = tk.Button(self,
                                text = "Cancel",
                                command = self.quit)
        self.cancel.grid(row = 0, column = 0)

        self.submit = tk.Button(self,
                                text = "Submit",
                                command = self.combine_funcs(
                                                            self.update_entries,
                                                            self.update_frames,
                                                            self.show_settings))
                                # command = lambda:[self.update_frames(), self.show_settings()]
        self.submit.grid(row = 0, column = 1)

class MainWindow(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        super().__init__(parent, *args, **kwargs)
        self.parent = parent
        self.controller = self

        self.project_info = ProjectInfo(self.parent, self.controller)
        self.project_info.grid(row = 0)
        self.widgets_init()

        self.confirm_items = ConfirmItems(self.parent, self.frames, self.controller)
        self.confirm_items.grid(row = 1)

    def widgets_init(self):
        self.dict_list = [(self.project_info, ('name',))]
        self.frames = OrderedDict(self.dict_list)

def main():
    root = tk.Tk()
    root.title("Welcome to Controller World!")
    root.geometry("300x300")
    gui = MainWindow(root)
    root.mainloop()

if __name__ == "__main__":
    main()

什么样的对象可以充当 tkinter 类初始化的父对象或主对象的角色?

任何 tkinter 小部件都可以扮演父窗口或主窗口的角色,尽管大多数情况下它是根窗口、顶级窗口或框架。

就我而言,请参阅示例代码,为什么不能将 self 作为父级传递给类 MainWindow(tk.Frame) 中的 ProjectInfo(...) 或 ConfirmItems(...) ?

您的代码中没有任何内容阻止您通过self作为家长。

如果使用 self 而不是 self.parent,它会弹出一个空窗口。

在使用的情况下self作为父母ProjectInfo, self指的是实例MainWindow。我看不到你在哪里打电话pack or grid就那个例子而言。如果父级不可见,则其子级也不可见。

你需要打电话pack or grid on the gui多变的。由于它被设计为根窗口中唯一的小部件,pack最有意义。

def main():
    ...
    gui = MainWindow(root)
    gui.pack(side="top", fill="both", expand=True)
    ...

作为一般经验法则,如果您有一个继承自某个小部件的类并且它创建了其他小部件,那么这些小部件应该始终是self或其后代之一,而不是其亲生父母。让一个类将子部件放入其父部件中完全违背了继承的目的tk.Frame.

继承的全部要点tk.Frame是创建一个行为与标准小部件完全相同的新类。您可以将其添加到其他小部件中pack or place or grid,它有一些标准选项,例如borderwidth and relief,并且是完全独立的。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

初始化 tkinter 类的父级/主控是什么? 的相关文章

随机推荐