В моем реальном программном обеспечении у меня есть главное меню (главное окно) и другие (окна верхнего уровня), которые пользователь может открыть с помощью некоторых виджетов, размещенных в главном. похоже, работает, главное окно может открывать другие окна верхнего уровня, но я увидел действительно большую проблему. когда я открываю более одного окна для одного и того же меню, все они, кроме последнего, всегда теряли информацию, помещенную в их виджеты (в моем случае виджеты Entry и ComboBox). начнем с простого примера:

from tkinter import *
from tkinter import ttk

class MainWindow:
    def __init__(self):
    
        # load a "SecondWindow" object:
        self.obj=SecondWindow(self)
        
        # main window's gui:
        self.parent=Tk()
        self.parent.geometry("300x280+360+200")
        self.parent.title("main window")
        self.parent.configure(background="#f0f0f0")
        
        self.OkButton=ttk.Button(self.parent, text="open the second window", width=26, command=lambda:self.obj.GUI())
        self.OkButton.place(x=20, y=20)

        self.parent.mainloop() 
    
class SecondWindow:
    def __init__(self, mw):
        self.mw=mw
    
    def GUI(self):
        self.window=Toplevel(self.mw.parent)
        self.window.geometry("300x180+360+200")
        self.window.title("second window")
        self.window.configure(background="#f0f0f0")
            
        self.MenuSV=StringVar()
        self.MenuSV.set("test test test")
        self.MenuComboBox=ttk.Combobox(self.window, state="readonly", values=("ciao", "hola", "hello", "Salut"), textvariable=self.MenuSV)
        self.MenuComboBox.place(x=20, y=20)
        
        self.window.mainloop()

# start the program:
if __name__ == "__main__":
    my_gui=MainWindow()

Этот код работает как моя настоящая программа. перед тем, как открыть главное окно, загружается объект SecondWindow (его основной компонент - функция графического интерфейса). когда вы открываете второе окно только один раз (используя загруженный ранее объект SeconWindow), все в порядке, никаких проблем, но если вы открываете другое, первое теряет информацию, размещенную в его виджетах. Почему?

enter image description here

Я действительно не понимаю этого странного поведения. как я могу решить проблему?

0
TurboC 15 Фев 2021 в 05:42

1 ответ

Лучший ответ

Поскольку вы создали только один экземпляр SecondWindow() внутри MainWindow, поэтому всякий раз, когда выполняется GUI() из SecondWindow, self.MenuSV будет переназначен другой экземпляр {{X5} }, поэтому ранее созданный экземпляр StringVar() не имеет ссылки на переменную и собирает мусор.

Вы можете создать новый экземпляр SecondWindow() при каждом нажатии кнопки:

class MainWindow:
    def __init__(self):
    
        # load a "SecondWindow" object:
        #self.obj=SecondWindow(self)
        
        # main window's gui:
        self.parent=Tk()
        self.parent.geometry("300x280+360+200")
        self.parent.title("main window")
        self.parent.configure(background="#f0f0f0")
        
        self.OkButton=ttk.Button(self.parent, text="open the second window", width=26,
                                 command=lambda:SecondWindow(self).GUI()) # create new instance of SecondWindow here
        self.OkButton.place(x=20, y=20)

        self.parent.mainloop() 

Или оставьте ссылку на self.MenuSV внутри SecondWindow:

class SecondWindow:
    def __init__(self, mw):
        self.mw=mw
    
    def GUI(self):
        self.window=Toplevel(self.mw.parent)
        self.window.geometry("300x180+360+200")
        self.window.title("second window")
        self.window.configure(background="#f0f0f0")
            
        self.MenuSV=StringVar()
        self.MenuSV.set("test test test")
        self.MenuComboBox=ttk.Combobox(self.window, state="readonly", values=("ciao", "hola", "hello", "Salut"), textvariable=self.MenuSV)
        self.MenuComboBox.place(x=20, y=20)
        self.MenuComboBox.MenuSV = self.MenuSV  # keep a reference
        
        self.window.mainloop()
3
acw1668 15 Фев 2021 в 03:00