我希望能够在打开Tkinter消息框(或类似消息)并等待用户输入时处理信号。
如何使调用处理程序并退出程序?
这是我尝试过的。触发信号时,消息框保持打开状态。
import signal
import sys
from tkinter import messagebox
def handler(signum, frame):
print("STOP!")
sys.exit(1)
signal.signal(signal.SIGINT, handler)
messagebox.showinfo("This is a message box", "This is a message")
答案 0 :(得分:2)
使用“顶级”窗口创建您自己的消息框,并使用“绑定”处理案例。
from tkinter import *
from tkinter import messagebox
def handler(frame):
print("STOP!")
sys.exit(1)
root = Tk()
top = Toplevel(root)
top.title("About this application...")
top.bind('<Control-c>', handler)
msg = Message(top, text="###################")
msg.pack()
button = Button(top, text="Dismiss", command=top.destroy)
button.pack()
root.mainloop()
from tkinter import *
from tkinter import messagebox
def handler(frame):
print("STOP!")
sys.exit(1)
root = Tk()
root.geometry("{0}x{1}".format(root.winfo_screenwidth()-3, root.winfo_screenheight()-3))
top = Toplevel(root, takefocus=True)
top.title("This is a message box")
w = top.winfo_reqwidth()
h = top.winfo_reqheight()
ws = top.winfo_screenwidth()
hs = top.winfo_screenheight()
x = (ws/2) - (w/2)
y = (hs/2) - (h/2)
top.geometry('%dx%d+%d+%d' % (300, 100, x, y))
top.attributes("-topmost", True)
top.bind('<Control-c>', handler)
lbl = Label(top, text="This is a message...")
lbl.pack(expand=True, fill='x')
button = Button(top, text="OK", command=top.destroy)
button.focus_set()
button.pack(pady=2)
root.mainloop()
答案 1 :(得分:2)
如@ varadaraju-g所建议,此处最好的方法似乎是从头开始创建消息框。绑定键盘事件不符合我的要求,因此我需要使用信号。
然后关键是要确保在我们进入主循环时实际上已处理了这些信号。 This answer引述Guido是关键,解释了使用after()定期调用虚拟函数如何启用信号处理。
import signal
from tkinter import *
def handler(sig, frame):
print("STOP!")
sys.exit(1)
def show_message_box(title, text):
root = Tk()
root.withdraw()
top = Toplevel(root)
top.title(title)
msg = Message(top, text=text)
msg.pack()
button = Button(top, text="Dismiss", command=root.destroy)
button.pack()
def signal_check():
root.after(50, signal_check)
root.after(50, signal_check)
top.protocol("WM_DELETE_WINDOW", root.quit)
root.mainloop()
print("End of dialog")
signal.signal(signal.SIGINT, handler)
signal.signal(signal.SIGTERM, handler)
show_message_box(title="message box", text="hello world")
答案 2 :(得分:0)
如果您的程序引用了Tk()
实例,例如root = Tk()
,则调用root.destroy()
而不是sys.exit(1)
:
import signal
from tkinter import Tk, messagebox
def handler(signum, frame):
print("STOP!")
#sys.exit(1)
root.destroy()
signal.signal(signal.SIGINT, handler)
root = Tk()
messagebox.showinfo("This is a message box", "This is a message")