Python tkinter 关闭第一个窗口,同时打开第二个窗口

问题描述 投票:0回答:1

我试图在第二个窗口打开时关闭第一个窗口。第一个窗口无法关闭,并且没有错误信息。

这个问题有类似的问题,但通过解决导入的库解决了: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)

python class tkinter
1个回答
0
投票

根据您的设计,您需要以某种方式开始第二个窗口的主循环。之前遇到这个问题,我发现最有帮助的是首先启动两个窗口,然后在显示之前和之后不需要它们时withdraw它们,并在两个窗口上运行

.update()
方法以保持它们同时运行。不要沮丧,撤回的窗口并不意味着最小化的窗口,最终用户不容易访问它们,但您可以使用
.deiconify
方法轻松访问它们。至于销毁 Windows,我发现在 python 的 tkinter 中,这是非常非常挑剔的。

所以,就你而言:

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()

注意以下几点:

  • 一旦所有窗口都被销毁,tcl 解释器不会退出,因此 python 解释器也不会退出。您可以使用 .quit() 方法,但这取决于您想要的
  • 这是一个快速草图,用于显示底层逻辑如何工作,由您决定使其适合您的项目结构,因此您可以将一些内容移入或移出 __init__() 方法,或者创建新类等等
  • 这可行,如果你想弄乱聚焦的窗口,我建议检查 win32gui 或相应操作系统的 GUI 库
  • 我还没有完全充实这个小代码片段,所以虽然它按照您在帖子中描述的方式运行,但要小心
    self.parent.destroy
    中的实现
    Window
    ,因为它可能会产生一些意想不到的后果,例如小部件行为不正常
  • 如上所述,这不会破坏您的App
    Window
    只会撤回它们,直到单击最终关闭按钮为止
  • 最后,我不确定在单击第二个窗口的关闭按钮后第一个窗口是否应该再次打开,但如果应该的话,应该很简单,而不是在
  • Window
     中销毁父窗口,将其取消图标并撤回当前窗口, 
    self
    ,在一些新的
    foo()
    功能中
© www.soinside.com 2019 - 2024. All rights reserved.