首页 > 解决方案 > 不将“主”传递给小部件有什么影响?

问题描述

当我在 GUI 上工作时,我遇到了由于类型提示而导致循环导入的问题,并且提供的答案有效,但它开始污染源代码,因为每个小部件类都导入它需要实例化的类,并且每个实例化的小部件都需要导入调用者,以便它可以输入提示:

# navbar.py

import tkinter as tk
from filemenu import FileMenu

class NavBar(tk.Menu):

    def __init__(self, parent: tk.Tk, **kwargs) -> None:
        super().__init__(parent, **kwargs)
        self.add_cascade(label='File', menu=FileMenu(self, tearoff=False))


# filemenu.py

import tkinter as tk
from typing import TYPE_CHECKING:
    from navbar import NavBar
# from navbar import NavBar  # using this causes cyclic import failure

class FileMenu(tk.Menu):

    def __init__(self, parent: 'NavBar', **kwargs) -> None:
        super().__init__(parent, **kwargs)
        self.add_command(label='Settings', command=self.open_settings)

    def open_settings(self) -> None:

        print(self.master.__class__)

该类NavBar实例化一个FileMenu类,因此模块必须 import FileMenu。问题出现在filemenu.py参数__init__parent键入为父小部件的地方,在这种情况下是一个NavBar实例。为了做到这一点,navbar.py必须从导入和循环导入开始。

但是,我尝试了一个Menu带有下拉菜单的选项:

# navbar.py

import tkinter as tk
from filemenu import FileMenu

class NavBar(tk.Menu):

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.add_cascade(label='File', menu=FileMenu(tearoff=False))


# filemenu.py

import tkinter as tk

class FileMenu(tk.Menu):

    def __init__(self, *args, **kwargs) -> None:
        super().__init__(*args, **kwargs)
        self.add_command(label='Settings', command=self.open_settings)

    def open_settings(self) -> None:

        print(self.master.__class__)

# main.py

import tkinter as tk

from navbar import NavBar

if __name__ == '__main__':
    root = tk.Tk()
    root.configure(menu=NavBar())
    root.mainloop()

打开一个带有下拉菜单的窗口,该菜单tk.Tk()self.master.__class__.

不传递master参数会有影响吗?effbot 文档将其显示master=None为大多数(如果不是全部)小部件,因此是可选的。

标签: pythontkinter

解决方案


不传递主参数是否有影响?

小部件存在于树状层次结构中。除了根小部件之外的每个小部件都必须有一个父小部件(或有时称为小部件)。如果您不提供父级,则根窗口将用作父级。除了非常简单的程序外,这通常不是正确的做法。


推荐阅读