当Tkinter messagebox等待用户响应时,在Python中处理信号

问题描述 投票:-1回答:3

我希望能够在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")
python tkinter signals
3个回答
2
投票

使用Toplevel窗口创建自己的消息框,并使用bind来处理大小写。

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()

event name list绑定!

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()

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")

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")
© www.soinside.com 2019 - 2024. All rights reserved.