Обрабатывать сигнал в Python, когда окно сообщений Tkinter ожидает ответа пользователя - PullRequest
0 голосов
/ 22 марта 2019

Я бы хотел иметь возможность обрабатывать сигналы, пока окно сообщений 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")

Ответы [ 3 ]

2 голосов
/ 28 марта 2019

Как подсказывает @ varadaraju-g, лучший подход здесь, похоже, заключается в создании окна сообщения с нуля.Привязка к событиям клавиатуры не отвечает моим требованиям, поэтому мне нужно было использовать сигнал.

Здесь важно обеспечить обработку этих сигналов, пока мы находимся в основной цепи. Этот ответ цитирование Гвидо является ключом, объясняющим, как использование 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 голосов
/ 27 марта 2019

Используйте окно 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()

список имен событий для привязки!

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()
0 голосов
/ 27 марта 2019

Если ваша программа имеет ссылку на экземпляр 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")
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...