干净地退出 Python Tkinter 应用程序,同时在“之后”循环中的按钮上使用“wait_variable”函数

Posted

技术标签:

【中文标题】干净地退出 Python Tkinter 应用程序,同时在“之后”循环中的按钮上使用“wait_variable”函数【英文标题】:Exit Python Tkinter app cleanly while also using "wait_variable" function on a button in an "after" loop 【发布时间】:2021-12-23 07:03:45 【问题描述】:

我有一个类似这个帖子的问题:Exit program within a tkinter class

我对这个问题的变体涉及在按钮上使用wait_variable 来控制应用程序中的“前进”,但也允许应用程序干净地关闭

请参阅下面的代码:

# To see output unbuffered:
#   python -u delete_win_test.py

import tkinter as tk
from tkinter import *


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

        # Close the app when the window's X is pressed
        self.protocol("WM_DELETE_WINDOW", self.closing)

        # When this var is set to 1, the move function can continue
        self.var = tk.IntVar()

        # Close the app if the button is pressed
        button = tk.Button(self, text="Exit",
                           command=self.destroy)
        button.place(relx=.5, rely=.5, anchor="c")

        # Step forward
        self.step_button = tk.Button(self, text="Step",
                                     command=lambda: self.var.set(1))
        self.step_button.place(relx=.5, rely=.75, anchor="c")

    def move(self):
        print("doing stuff")  # simulates stuff being done
        self.step_button.wait_variable(self.var)
        self.after(0, self.move)

    def closing(self):
        self.destroy()


app = GUI()
app.move()
app.mainloop()
窗口显示正确 “向前迈进”有效,因为单击按钮时“正在做的事情”会打印到终端 同时按 X 或使用“退出”按钮退出窗口都有效

问题: Python 应用永远不会从终端退出,需要关闭终端。

如何让 Python 程序干净地退出,这样用户就不需要关闭并重新打开一个新的终端窗口?

动画等相关参考资料:

使用 self.after 的动画:moving circle using tkinter 按钮等待:Making Tkinter wait untill button is pressed 原“退出”代码:Exit program within a tkinter class

更新(解决方案):

(归功于下面的两个响应答案)

         # Close the app if the button is pressed
         button = tk.Button(self, text="Exit",
-                           command=self.destroy)
+                           command=self.closing)
         button.place(relx=.5, rely=.5, anchor="c")
 
         # Step forward
...
     def closing(self):
         self.destroy()
+        self.var.set("")
+        exit(0)

这允许原生窗口的“X”关闭窗口 Tk 按钮关闭窗口同时仍然在终端中干净地关闭 Python 应用程序。。 p>

【问题讨论】:

为什么不在closing 方法中将self.var 设置为一个特殊的int,如果设置了这个特殊的int,就不要继续使用move?使用if statement 无论如何都可以解决这个问题,而且对你来说应该不会太难解决。 嗨@Atlas435,我明白你对self.var 的意思,但是你能解释一下if statement 的意思吗?这是单独的解决方案还是与self.var 相关? 【参考方案1】:

您的closing 函数需要设置变量以使应用停止等待。

def closing(self):
    self.destroy()
    self.var.set("")

【讨论】:

嗨,布莱恩,感谢您的回复,但这对我不起作用。即使窗口关闭(使用 X 或关闭按钮),Python 应用程序仍然不会在终端中干净地退出。在 Windows Git Bash 和 Mac OSX 上测试。 @masao:这很奇怪。它适用于我在 OSX 上。 您好,Bryan,这是我的环境:tk==0.1.0toml==0.10.2 Python 版本:Python 3.9.4这符合您的环境吗? 解决方案贴在原帖中!非常感谢!【参考方案2】:

在关闭函数中,需要调用exit退出程序。

def closing(self):
    self.destroy() #closes tkinkter window
    exit(0) #exits program

【讨论】:

谢谢!我将此与其他答案结合起来,找到了解决方案(见原帖)!

以上是关于干净地退出 Python Tkinter 应用程序,同时在“之后”循环中的按钮上使用“wait_variable”函数的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 Ctrl+C 输入干净地退出 QProcess?

最近学习过的Python和tkinter,我想知道这段代码是否干净

结合 Tkinter 和 win32ui 使 Python 在退出时崩溃

markdown 奇怪的是“git没有干净地退出(退出代码1)”

拦截 Tkinter“退出”命令?

从 Perl 线程中干净地退出