在Python中一段时间后关闭tkmessagebox

问题描述 投票:0回答:5

我正在开发一个自动考勤系统,当学生扫描他的 RFID 标签时,他的考勤会被记录下来,同时使用 tkmessagebox 弹出窗口显示欢迎消息。用户无法控制鼠标或键盘,我想让消息显示 2 秒钟并删除消息框。有没有办法像建议的那样关闭 tkmessagebox 弹出窗口?

python python-2.7 tkinter tk-toolkit tkmessagebox
5个回答
4
投票

我不认为可以用

tkMessageBox
来完成,因为这会创建一个模式对话框,并且您无权访问小部件 id(以便可以通过编程方式销毁它)。

但是创建自己的顶级窗口,向其添加一些欢迎消息,然后在一段时间后关闭它并不难。像这样的东西:

from Tkinter import *

WELCOME_MSG = '''Welcome to this event.

Your attendance has been registered.

Don't forget your free lunch.'''
WELCOME_DURATION = 2000

def welcome():
    top = Toplevel()
    top.title('Welcome')
    Message(top, text=WELCOME_MSG, padx=20, pady=20).pack()
    top.after(WELCOME_DURATION, top.destroy)

root = Tk()
Button(root, text="Click to register", command=welcome).pack()

root.mainloop()

您需要将事件处理程序连接到 RFID 检测。上面代码中是通过一个按钮来模拟的,事件处理程序是

welcome()
函数。在
welcome()
中,创建了带有消息的顶级小部件。顶级小部件在 2000 毫秒(2 秒)后使用
.after()
被销毁,它注册了一个在延迟后调用的回调函数。


4
投票

我尝试了在网上找到的许多解决方案,但没有一个像我预期的那样有效。 最后,我找到了一个简单的解决方案:

from tkinter import Tk
from tkinter.messagebox import Message 
from _tkinter import TclError

TIME_TO_WAIT = 2000 # in milliseconds 
root = Tk() 
root.withdraw()
try:
    root.after(TIME_TO_WAIT, root.destroy) 
    Message(title="your title", message="your message", master=root).show()
except TclError:
    pass

我知道这不是最佳选择,因为我忽略了 TclError,但这是唯一对我有用的东西。 顺便说一句,我正在使用 python 3.7


2
投票

下面的小函数就可以完成这项工作。通过设置您可以选择的类型:信息、警告或错误消息框,默认为“信息”。您还可以设置超时,默认为 2.5 秒。

def showMessage(message, type='info', timeout=2500):
    import tkinter as tk
    from tkinter import messagebox as msgb

    root = tk.Tk()
    root.withdraw()
    try:
        root.after(timeout, root.destroy)
        if type == 'info':
            msgb.showinfo('Info', message, master=root)
        elif type == 'warning':
            msgb.showwarning('Warning', message, master=root)
        elif type == 'error':
            msgb.showerror('Error', message, master=root)
    except:
        pass

调用该函数如下: 对于消息类型“Info”和 2.5 秒超时:

showMessage('Your message')

或者通过您自己的设置来输入消息“错误”和超时 4 秒:

showMessage('Your message', type='error', timeout=4000)

0
投票

使用Python3,您必须使用导入名称调用Toplevel(),例如:

import tkinter

top = tkinter.Toplevel()

0
投票

为了增强 Mhawke 的精彩答案,请在函数末尾添加一些位。 我的修改:

def showMessage(消息, type='info', timeout=2500): 将 tkinter 导入为 tk 从 tkinter 导入消息框作为 msgb

root = tk.Tk()
root.withdraw()
try:
    root.after(timeout, root.destroy)
    if type == 'info':
        msgb.showinfo('Info', message, master=root)
    elif type == 'warning':
        msgb.showwarning('Warning', message, master=root)
    elif type == 'error':
        msgb.showerror('Error', message, master=root)
except:
    pass

try:
    root.destroy()
except TclError:
    pass

root = None

如果您从不同的线程调用,这些添加功能将非常有用。 就我而言,我从主线程以及使用以下命令创建的系统托盘图标进行调用:

icoTray = pystray.Icon(...)
icoTray.run_detached()

未能包含:

try:
    root.destroy()
except TclError:
    pass

给出:

RuntimeError: main thread is not in main loop 

在“其他”线程的后续调用中”

未能包含“root = None”位会在“其他”线程的调用中给出类似以下内容的信息:

无效的命令名称“...” 执行时 “……” (“之后”脚本)

© www.soinside.com 2019 - 2024. All rights reserved.