使用 Ctrl-C 退出 tkinter 应用程序并捕获 SIGINT [英] Exiting a tkinter app with Ctrl-C and catching SIGINT

查看:35
本文介绍了使用 Ctrl-C 退出 tkinter 应用程序并捕获 SIGINT的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Ctrl-C/SIGTERM/SIGINT 似乎被 tkinter 忽略了.通常它可以通过回调再次捕获.这似乎不起作用,所以我想我会运行 tkinter 在另一个线程中,因为它的 mainloop() 是一个无限循环并阻塞.我实际上也想这样做以在单独的线程中从 stdin 读取.即使在此之后,Ctrl-C 仍然不会被处理,直到我关闭窗口.这是我的 MWE:

Ctrl-C/SIGTERM/SIGINT seem to be ignored by tkinter. Normally it can be captured again with a callback. This doesn't seem to be working, so I thought I'd run tkinter in another thread since its mainloop() is an infinite loop and blocks. I actually also want to do this to read from stdin in a separate thread. Even after this, Ctrl-C is still not processed until I close the window. Here's my MWE:

#! /usr/bin/env python
import Tkinter as tk
import threading
import signal
import sys

class MyTkApp(threading.Thread):
    def run(self):
        self.root = tk.Tk()
        self.root.mainloop()

app = MyTkApp()
app.start()

def signal_handler(signal, frame):
    sys.stderr.write("Exiting...\n")

    # think only one of these is needed, not sure
    app.root.destroy()
    app.root.quit()

signal.signal(signal.SIGINT, signal_handler)

结果:

  • 运行应用
  • 终端中的 Ctrl-C(什么也没发生)
  • 关闭窗口
  • 正在退出..."被打印出来,我收到一个关于循环已经退出的错误.

这里发生了什么,如何让终端中的 Ctrl-C 关闭应用程序?

What's going on here and how can I make Ctrl-C from the terminal close the app?

更新:添加投票按照建议,在主线程中工作,但在另一个线程中启动时没有帮助...

Update: Adding a poll, as suggested, works in the main thread but does not help when started in another thread...

class MyTkApp(threading.Thread):
    def poll(self):
        sys.stderr.write("poll\n")
        self.root.after(50, self.poll)

    def run(self):
        self.root = tk.Tk()
        self.root.after(50, self.poll)
        self.root.mainloop()

推荐答案

由于你的 tkinter 应用程序运行在另一个线程中,所以你不需要在主线程中设置信号处理程序,只需使用以下代码块即可app.start() 语句:

Since your tkinter app is running in another thread, you do not need to set up the signal handler in the main thread and just use the following code block after the app.start() statement:

import time

while app.is_alive():
    try:
        time.sleep(0.5)
    except KeyboardInterrupt:
        app.root.destroy()
        break

然后您可以使用 Ctrl-C 引发 KeyboardInterrupt 异常以关闭 tkinter 应用程序并中断 while 循环.如果您关闭 tkinter 应用程序,while 循环也将终止.

You can then use Ctrl-C to raise the KeyboardInterrupt exception to close the tkinter app and break the while loop. The while loop will also be terminated if you close your tkinter app.

请注意,上述代码仅适用于 Python 2(因为您在代码中使用了 Tkinter).

Note that the above code is working only in Python 2 (as you use Tkinter in your code).

这篇关于使用 Ctrl-C 退出 tkinter 应用程序并捕获 SIGINT的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆