用python中的tkinter从顶层窗口关闭主窗口

用python中的tkinter从顶层窗口关闭主窗口,python,python-3.x,tkinter,Python,Python 3.x,Tkinter,这是我的第一个问题,我不熟悉python和这个网站 我正在设计一个与数据库交互的应用程序。我添加了一个“关闭”按钮,我想打开一个新窗口,询问“关闭程序?”和两个按钮:是和否。单击“否”时,新窗口关闭。单击“是”时,两个窗口都将关闭 我让我的代码工作,但我很肯定有一个更好或更聪明的方式做它 为了让它正常工作,我必须在“close_window”方法中编写“root.destroy()”,但我确信有一种更聪明的方法,可以通过使用python所有功能的“self.master.destroy()”获得

这是我的第一个问题,我不熟悉python和这个网站

我正在设计一个与数据库交互的应用程序。我添加了一个“关闭”按钮,我想打开一个新窗口,询问“关闭程序?”和两个按钮:是和否。单击“否”时,新窗口关闭。单击“是”时,两个窗口都将关闭

我让我的代码工作,但我很肯定有一个更好或更聪明的方式做它

为了让它正常工作,我必须在“close_window”方法中编写“root.destroy()”,但我确信有一种更聪明的方法,可以通过使用python所有功能的“self.master.destroy()”获得相同的结果。我在下面展示了代码的简化版本

提前谢谢

阿方索

from tkinter import *

class Window():

    def __init__(self, main):
        self.main = main

        self.b5=Button(self.main, text="Action 1", width=12)
        self.b5.grid(row=0, column=1)

        self.b5=Button(self.main, text="Action 2", width=12)
        self.b5.grid(row=0, column=2)

        self.b6=Button(self.main, text="Close", width=12, command=self.new_window)
        self.b6.grid(row=0, column=3)

    def new_window(self):
        self.newWindow = Toplevel(self.main)
        self.app = Demo2(self.newWindow)

    def close_window(self):
        root.destroy()


class Demo2:
    def __init__(self, master):
        self.master = master
        self.frame = Frame(self.master)

        self.l1=Label(self.frame, text="Close the program?")
        self.l1.grid(row=0, column=0, columnspan=2)

        self.b1=Button(self.frame, text="Yes", command=self.yes_com)
        self.b1.grid(row=1, column=0)

        self.b1=Button(self.frame, text="No", command=self.no_com)
        self.b1.grid(row=1, column=1)

        self.frame.pack()

    def yes_com(self):
        self.master.destroy()
        Window.close_window(self)

    def no_com(self):
        self.master.destroy()


def main():
    global root
    root = Tk()
    app = Window(root)
    root.mainloop()

if __name__ == '__main__':
    main()

您只需使用
messagebox
模块提供的标准对话框即可

具体来说,它提供了
askyesno
对话框,负责打开/关闭新窗口,如果用户单击
Yes
,则返回
True
;如果用户单击
No
,则返回
False
。然后,如果用户简单地使用
self.main.destroy()
(无需将
root
声明为
global
),就可以使用
if
-语句关闭窗口

注释

  • “标准”对话框中的“是/否”按钮是本地化的,这意味着它们将被转换为计算机设置所使用的语言
  • 如果您查看一下
    消息框
    模块,就会发现还有其他标准对话框。在本例中,我将使用
    askyescancel
    ,它的使用方式完全相同,但似乎更具语义

  • 皮尔·保罗的答案是正确的,但为了科学起见,以下是对你问题的直接回答:

    def yes_com(self):
        self.master.master.destroy() # <this class instance>.<toplevel instance>.<Tk instance>.destroy()
    

    使用
    sys.exit()
    可以;仅使用普通的
    exit()
    quit()
    取决于安装情况,因此您不应该在代码中使用它。普通版本是在REPL中使用的。对不起,我对您的代码做了一个快速的假设。你好,乔纳森,谢谢你的建议
    sys.exit()
    工作正常并关闭所有内容。我这里有一个问题,有人告诉我,销毁tkinter窗口比
    quit()
    exit()
    更好。你觉得怎么样
    self.master.main.destroy()
    无法工作,出现以下错误:
    self.master.main.destroy()AttributeError:'Toplevel'对象没有属性'main'
    知道原因吗?我想了解连接两个类的方式。再次感谢你的帮助<代码>self.master.master.destroy()有效。谢谢你的解释性评论。谢谢皮尔·保罗。messagebox模块正是我所需要的。如果我可能会问,如果我已经使用tkinter import*导入整个tkinter库,为什么我需要tkinter import messagebox中的
    ?再次感谢你的帮助@阿方索:那是因为从my_package import*
    导入的
    并不导入
    my_module
    中的所有内容,而只导入该软件包决定导出的内容。在这种情况下,
    messagebox
    不会自动导入,因为
    tkinter
    模块没有显式导出它,因此您必须手动执行。要获得更深入的解释,请查看,它解决了相同的问题,但在这种情况下,模块是
    ttk
    ,而不是
    messagebox
    。感谢您的回答!
    def yes_com(self):
        self.master.master.destroy() # <this class instance>.<toplevel instance>.<Tk instance>.destroy()
    
    import sys
    
    def yes_com(self):
        sys.exit()