joz*_*yqk 5 python multithreading signals tkinter
Ctrl-C/SIGTERM/SIGINT 似乎被 tkinter 忽略。通常可以通过回调再次捕获它。这似乎不起作用,所以我想我应该在另一个线程中运行 tkinter ,因为它的mainloop() 是一个无限循环和 block。实际上我也想这样做以在单独的线程中从标准输入读取。即使在此之后,Ctrl-C 仍然不会被处理,直到我关闭窗口。这是我的 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)
Run Code Online (Sandbox Code Playgroud)
结果:
这是怎么回事?如何让终端中的 Ctrl-C 关闭应用程序?
更新:按照建议添加 poll,在主线程中工作,但在另一个线程中启动时没有帮助......
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()
Run Code Online (Sandbox Code Playgroud)
这是一个在窗口或命令行中捕获 control c 的工作示例。这是用 3.7.2 进行测试的,这似乎比其他解决方案更简单。我几乎感觉自己失去了一些东西。
import tkinter as TK
import signal
def hello():
print("Hello")
root = TK.Tk()
TK.Button(root, text="Hi", command=(hello)).pack( )
def handler(event):
root.destroy()
print('caught ^C')
def check():
root.after(500, check) # time in ms.
# the or is a hack just because I've shoving all this in a lambda. setup before calling main loop
signal.signal(signal.SIGINT, lambda x,y : print('terminal ^C') or handler(None))
# this let's the terminal ^C get sampled every so often
root.after(500, check) # time in ms.
root.bind_all('<Control-c>', handler)
root.mainloop()
Run Code Online (Sandbox Code Playgroud)
由于您的 tkinter 应用程序在另一个线程中运行,因此您不需要在主线程中设置信号处理程序,只需在语句后使用以下代码块app.start()
:
import time
while app.is_alive():
try:
time.sleep(0.5)
except KeyboardInterrupt:
app.root.destroy()
break
Run Code Online (Sandbox Code Playgroud)
然后,您可以使用Ctrl-C引发KeyboardInterrupt
异常来关闭 tkinter 应用程序并中断 while 循环。如果您关闭 tkinter 应用程序,while 循环也将终止。
请注意,上述代码仅适用于 Python 2(如您Tkinter
在代码中使用的那样)。
归档时间: |
|
查看次数: |
8311 次 |
最近记录: |