在 tkinter 中,如何将继承的 class 变量的值插入 Label 小部件?

In tkinter, how can I insert the value of an inherited class variable into a Label widget?

我遇到的问题与标签小部件有关。在链接的代码中,Text 小部件和 Button 小部件的测试都获取了继承的值并正确显示它。

您可以在 class PageTwo

中找到相关标签小部件

我试图在 Label 中继承和显示的变量是第一个 class.

中设置的“num”变量

目标是获取该变量,在另一个 class 中设置值,然后稍后在 Label 小部件中显示新设置的值。

我已尝试将 Label 设置为在 f 字符串中将变量直接显示为 str 值,并在 PageTwo 中设置局部变量以获取 TestClass.num[= 的值12=]

相关代码示例为:

import tkinter as tk


class TestClass(tk.Tk):
    num = None

    def __init__(self, *args, **kwargs):
        tk.Tk.__init__(self, *args, **kwargs)

        tk.Tk.wm_title(self, "Game")

        container = tk.Frame(self)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}

        for F in (PageOne, PageTwo):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(PageOne)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = tk.Label(self,
                         text="Make a selection",
                         wraplength=450, justify='center')
        label.pack(padx=10, pady=10)

        TestClass.num = tk.StringVar()
        tk.Radiobutton(self, text="1", variable=TestClass.num, value="1", ).pack()
        tk.Radiobutton(self, text="2", variable=TestClass.num, value="2", ).pack()
        tk.Radiobutton(self, text="3", variable=TestClass.num, value="3", ).pack()

        view_selection = tk.Button(self, text="test selection", command=lambda: print(TestClass.num.get()))
        view_selection.pack()

        next_page = tk.Button(self, text="Next Page",
                              command=lambda: controller.show_frame(PageTwo))
        next_page.pack(pady=10, padx=10)


class PageTwo(tk.Frame):
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        # label = tk.Label(self, text=TestClass.num.get()
        label = tk.Label(self, text=f"The number should show up here -> {TestClass.num.get()}  <- ")
        label.pack()

        text1 = tk.Text(self)
        text1.pack()

        see_num = tk.Button(self, text="View Number",
                            command=lambda: text1.insert('1.0', TestClass.num.get()))
        see_num.pack(pady=10, padx=10)


app = TestClass()
app.mainloop()

我已经遇到控制器的这种用法有一段时间了,但从来没有真正知道这个想法是从哪里来的。无论如何,在这里我看到问题实际上可能出在程序流程中(当您使用 F(container, self) 实例化时,您正在执行 class 的 __init__,因此已经设置了值。

当您 select 单选按钮中的每个项目时,您希望标签的值能够适当地自行编辑。因此,我认为静态变量更合适(访问另一个 class 中的小部件),您可以使用 command 触发回调。

您还需要修复 Radiobutton 三态问题 ,方法是为 StringVar 提供不同的初始值,使其不等于 [ Radiobutton 的 =17=] 或为每个单选按钮提供不同的 tristatevalue 或使用不使用此 tristatevalue.

ttk.Radiobutton

所以要对 PageTwo 进行的更改是创建一些静态变量:

class PageTwo(tk.Frame):
    label = ''
    text = ''
    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)

        PageTwo.text = "The number should show up here ->  {}  <- " # {} so we can `format` it to be whatever text we want, later
        PageTwo.label = tk.Label(self, text=self.text.format(''))
        PageTwo.label.pack()
        ...
        ...

并且在PageOne中,您需要为Radiobutton设置一个command,每次更改选项时都会调用它。

class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        ...
        ...
        TestClass.num = tk.StringVar(value=' ')
        command = lambda *args: PageTwo.label.config(text=PageTwo.text.format(TestClass.num.get()))
        tk.Radiobutton(self, text="1", variable=TestClass.num, value="1",command=command).pack()
        tk.Radiobutton(self, text="2", variable=TestClass.num, value="2",command=command).pack()
        tk.Radiobutton(self, text="3", variable=TestClass.num, value="3",command=command).pack()
        ...
        ...

另一种我认为可能的方法是创建一个函数来创建小部件,并在页面应该显示时加载它。