tkinter:将初始化参数传递给子类自定义小部件?

tkinter: Pass Initialization Parameters to A Subclassed Custom Widget?

我一直在尝试在 tkinter 中创建一个自定义小部件,没什么特别的,只是一个包含一个条目和两个标签的框架。我希望标签和框架能够访问父应用程序的 StringVars(即两个标签的文本变量,以及条目文本变量)。我认为通过将这些名称作为关键字参数传递给初始化方法应该相当简单,但我 运行 遇到了麻烦。这是我的代码:

import tkinter as tk
import tkinter.ttk as ttk

class EntryFrame(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)

        self.title = kwargs.get('title')
        title = tk.Label(self, text=self.title)
        unit = tk.Label(self, text='(Unit)')
        self.entryVar = tk.StringVar()
        entry = tk.Entry(self, textvariable=self.entryVar)

        title.grid(row=0, column=0, sticky='es')
        unit.grid(row=0, column=1, sticky='ws')
        entry.grid(row=1, column=0, columnspan=2, padx=3, pady=3, sticky='n')

class TestApplication(tk.Frame):
    def __init__(self, master=None, *args, **kwargs):
        tk.Frame.__init__(self, master=None, *args, **kwargs)
        self.master=master
        self.grid(row=0, column=0)

        entryFrame  = EntryFrame(self, title='Title')
        entryFrame.grid(row=0, column=0)

root = tk.Tk()
Application = TestApplication(root)
root.mainloop()

我 运行 遇到了一个问题,我实际上无法将任何其他内容传递给我的新小部件,因为它使用 tk.Frame 进行初始化,似乎 在初始化时需要 tk.frame 属性。我实际上不能给它 args 或 kwargs。

如果我尝试不同的方法:

class EntryBox(self):
    def __init__(self, parent, *args, **kwargs):

        self.frame = tk.Frame(self)
        self.title = tk.Label(self, text='Title')
        self.unit = tk.Label(self, text='(Unit)')
        self.entryVar = tk.StringVar()
        entry = tk.Entry(self, textvariable=self.EntryVar)

        title.grid(row=0, column=0, sticky='es')
        unit.grid(row=0, column=1, sticky='es')
        entry.grid(row=1, column=0, columnspan=2, padx=3, pady=3, sticky='n')

class 抛出关于自身未定义的错误。

编辑:

代码示例 2 的更好示例:

class EntryBox():
    def __init__(self, parent, *args, **kwargs):

        self.title=kwargs.pop('title')
        self.frame = tk.Frame(parent)
        self.frame.grid(row=0, column=0)
        self.title = tk.Label(self.frame, text=self.title)
        self.unit = tk.Label(self.frame, text='(Unit)')
        self.entryVar = tk.StringVar()


        self.entry = tk.Entry(self.frame)

        self.title.grid(row=0, column=0, sticky='es')
        self.unit.grid(row=0, column=1, sticky='es')
        self.entry.grid(row=1, column=0, columnspan=2, padx=3, pady=3, sticky='n')

试试这样的东西:

def __init__(self, parent, title, **kwargs):        
    tk.Frame.__init__(self, parent, **kwargs)
    self.title = title   

换句话说,避免将自定义参数传递给超类。

或者您可以在调用超类的 __init__ 之前执行 self.title = kwargs.pop('title')

您的第二个代码示例简直令人困惑 - 在 class EntryBox(self): 中,您期望 'self' 是什么?