Я пытаюсь закрыть первое окно, когда открывается второе окно. Оба окна закрываются, или первое окно закрывается, а второе окно никогда не открывается.
В этом вопросе есть аналогичная проблема, но она была решена путем обращения к импортированным библиотекам: Tkinter открывает второе окно, когда закрывается первое
Вот мой код, взятый отсюда https://www.pythontutorial.net/tkinter/tkinter-toplevel/
import tkinter as tk
from tkinter import ttk
class Window(tk.Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.geometry('300x100')
self.title('Toplevel Window')
ttk.Button(self,
text='Close',
command=self.destroy).pack(expand=True)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('300x200')
self.title('Main Window')
# place a button on the root window
ttk.Button(self,
text='Open a window',
command=self.open_window).pack(expand=True)
def open_window(self):
window = Window(self)
window.grab_set()
self.destroy()
if __name__ == "__main__":
app = App()
app.mainloop()
Я добавил self.destroy() в функцию def open_window(self). Но оно не закрывает окно, созданное этим классом: class App(tk.Tk).
Если вы не поняли, дело в том, что вы забыли () для вызова функции.
Спасибо @jasonharper и @Barmar. Добавление ( ) уничтожит первое окно, но теперь второе окно никогда не откроется. Плюс, почему ( ) не нужен при закрытии второго окна кнопкой в class Window? Это окно прекрасно закрывается без ( ).
Добавление () в конец ссылки на функцию приведет к выполнению этой функции. command=self.destroy передаст ссылку на функцию опции command кнопки, поэтому при нажатии кнопки функция будет выполнена.






По вашему замыслу вам нужно будет каким-то образом начать основной цикл второго окна. Раньше я сталкивался с этой проблемой, и мне показалось, что наиболее полезным было сначала запустить оба окна, а затем закрыть их, когда они не были нужны до и после того, как они были показаны, а также запустить метод .update() в обоих окнах, чтобы они работали одновременно. Не расстраивайтесь, убранные окна не означают свернутые окна, и конечный пользователь не может легко получить к ним доступ, но они легко доступны вам с помощью метода .deiconify. Что касается уничтожения окон, я обнаружил, что в tkinter в Python это очень и очень привередливо.
Итак, в вашем случае:
import tkinter as tk
from tkinter import ttk
class Window(tk.Toplevel):
def __init__(self, parent):
super().__init__(parent)
self.parent = parent
self.geometry('300x100')
self.title('Toplevel Window')
self.withdraw()
ttk.Button(self,
text='Close',
command=self.parent.destroy).pack(expand=True)
class App(tk.Tk):
def __init__(self):
super().__init__()
self.geometry('300x200')
self.title('Main Window')
def bar(self, window_unwithdraw_fn):
# place a button on the root window
ttk.Button(self,
text='Open a window',
command=window_unwithdraw_fn).pack(expand=True)
if __name__ == "__main__":
app = App()
window = Window(app)
def foobar():
window.deiconify()
window.grab_set()
app.withdraw()
app.bar(foobar)
while True:
app.update()
window.update()
Обратите внимание на пару вещей:
self.parent.destroy в Window, поскольку это может иметь некоторые неожиданные последствия, такие как некорректное поведение виджетов.App или Window, а только отзывает их до тех пор, пока не будет нажата кнопка окончательного закрытия.Window должно быть просто деиконизировать его и удалить текущее окно self в какая-то новая foo() функция.iconify() работает аналогично .withdraw()
Вам придется написать
self.destroy(), чтобы эта строка действительно что-то сделала.