【问题标题】:How to modify `Text` of the parent from the children level in Tkinter (Python)如何在Tkinter(Python)中从子级修改父级的“文本”
【发布时间】:2025-12-17 18:15:02
【问题描述】:

我有一个app.py 文件,其中正在调用主类App(Tk)。在其中我创建了三个孩子,其中两个是相关的(在图像的中间和右侧):

    self.active_module = main_module.MainModule(self.main)
    self.active_module.grid(column=1,row=0)

    self.preview = Text(self.main,state='disabled',width=50)
    self.preview.grid(column=2,row=0,sticky=E)

active_module 是一个 ttk.Notebook 与多个 ttk.Frame 并分隔为一个 main_module.py 文件。其中一个框架的组合框具有不同的值...

...问题是如何在更改组合框值时修改 preview 文本? 为清楚起见,我还附上了图像:

相关部分代码如下:

app.py

class App(Tk):
    def __init__(self):
        super().__init__()

        [...]

        self.active_module = main_module.MainModule(self.main)
        self.active_module.grid(column=1,row=0)

        self.preview = Text(self.main,state='disabled',width=50)
        self.preview.grid(column=2,row=0,sticky=E)

ma​​in_module.py

class MainModule(ttk.Notebook):
    def __init__(self,parent):
        super().__init__(parent)

        self.add(General(self),text="General")

class General(ttk.Frame):
    def __init__(self,parent):
        super().__init__(parent)

        self.runtype_label = ttk.Label(self,text="Runtype:")
        self.runtype_label.grid(column=0,row=0,sticky=W)
        self.runtype_combobox = ttk.Combobox(self,state="readonly",values=("1","2","3"),width=9)
        self.runtype_combobox.grid(column=1,row=0,sticky=W)
        #self.runtype_combobox.bind('<<ComboboxSelected>>',self.runtype_choice)

【问题讨论】:

  • 您可以将回调引用传递给MainModule,然后将此回调传递给General
  • 我试图通过 self.preview 传递 __init__ 和构造函数来做到这一点,但不起作用
  • 也许如果你更新你的问题以显示你的代码不起作用和任何错误消息,有人可以帮助修复它。
  • 也许您没有在 __init__ 方法中将父级存储为类变量? self.parent = parent。然后类中的其他方法可以使用对父对象的引用。

标签: python user-interface tkinter


【解决方案1】:

您可以将回调传递给MainModule 类,然后将此回调传递给General 类。

app.py

class App(Tk):
    def __init__(self):
        super().__init__()

        self.main = Frame(self)
        self.main.pack()

        # pass callback to MainModule class
        self.active_module = main_module.MainModule(self.main, self.insert_text) 
        self.active_module.grid(column=1, row=0)

        self.preview = Text(self.main, state='disabled', width=50)
        self.preview.grid(column=2, row=0, sticky=E)

    def insert_text(self, text):
        self.preview.config(state='normal')
        self.preview.insert('end', f'{text}\n')
        self.preview.config(state='disabled')

ma​​in_module.py

class MainModule(ttk.Notebook):
    def __init__(self, parent, callback):
        super().__init__(parent)

        # pass callback to 'General' class
        self.add(General(self, callback), text="General")

class General(ttk.Frame):
    def __init__(self, parent, callback):
        super().__init__(parent)

        self.runtype_label = ttk.Label(self, text="Runtype:")
        self.runtype_label.grid(column=0, row=0, sticky=W)
        self.runtype_combobox = ttk.Combobox(self, state="readonly", values=("1","2","3"), width=9)
        self.runtype_combobox.grid(column=1, row=0, sticky=W)
        # call the callback whenever item is selected
        self.runtype_combobox.bind('<<ComboboxSelected>>', lambda e: callback(self.runtype_combobox.get()))

【讨论】:

  • 非常感谢。看起来不错。但是,问题在某种程度上很重要,因为这是会干扰preview 内容的众多复选框之一。例如,初始状态为:Default text。当我单击General 选项卡中的复选框时,preview 将变为:APFD。当我在其他选项卡中单击另一个选项卡时,它会变为:APFD def2。另一方面,当我取消选中General 中的那个时,只会出现def2。我知道这更多的是关于插入和删除的操作,但是这些复选框如何以多种方式绑定到preview
  • @farmaceut 问题中从未提及此类情况,我的回答是基于提供的信息。但是,如果您了解其中的逻辑,则可以根据您的情况对其进行修改。
  • 确实如此。忘了说!我刚刚实施了您发送给我的内容。我对 lambda 不是很好,但我觉得它是如何工作的,并且肯定会根据需要对其进行修改。非常感谢 :) 现在我只需要管理它以在更改时删除文本