【问题标题】:How can I spawn multiple tkMessageBox.showerror at the same time?如何同时生成多个 tkMessageBox.showerror?
【发布时间】:2014-01-13 07:03:08
【问题描述】:

我正在使用 Tkinter 创建一个小时间管理工具,这样我就可以在工作中继续完成任务。我在某个方面遇到了问题,我似乎无法开始工作。我正在使用错误框,以便它显示在所有其他窗口的前面。

就像现在一样,程序在一个跟踪时间的函数上启动一个新线程,并将它与用户为他们的任务输入的时间进行比较。一旦实时 > 用户输入的时间,它就会启动另一个线程来生成 tkMessageBox。我已经尝试过了,没有启动一个新线程来生成 tkMessageBox,问题是一样的。如果用户为 2 个单独的任务输入相同的时间,则错误弹出窗口会冻结。我在查找有关此主题的信息时遇到了麻烦...这种行为很奇怪,因为如果我有 2 个警报,假设 0600 有 1 个,0601 有一个,但我没有关闭第一个弹出的错误框并让它熬夜直到第二个警报触发,第二个警报将替换第一个警报(如果可能,我希望弹出多个错误框)。但是,只有具有相同触发时间的警报才会导致弹出窗口冻结。

这是我的第一个 GUI 程序,过去 24 小时才开始学习线程和 GUI 的概念,所以我不确定这是线程问题还是 tkMessageBox 的问题。由于错误框的行为,我认为它是线程模块与 tkMessageBox 模块的结合。我正在使用的命令是:

tkMessageBox.showerror('TIMER ALERT!!!', comp_msg)

Here is the source 我把 cmets 放在那里帮忙。我说的 tkMessageBox 是第 56 行。

我想我什至不确定我是否可以用弹出框做我想做的事情,如果可以的话,我不知道该怎么做。如果我不能,是否有另一种方法可以使用 Tkinter 生成多个错误类型的弹出框?我只想在任何给定时间出现多个框。

提前致谢,非常感谢任何帮助。

编辑:

import thread
from Tkinter import *

#Spawns Error Box.  Runs in it's own thread.
def message_box(comp_msg,q):      # q is an empty string because of thread module.
    print "Spawning Error Box..."
    eb =Toplevel()
    eb.config(master=None,bg="red")
    pop_l = Label(eb,text="ALERT!!!")
    pop_l2=Label(eb,text=comp_msg)
    pop_l.pack(pady=10,padx=10)
    pop_l2.pack(pady=15,padx=10)
    return eb

thread.start_new_thread(message_box,(comp_msg,""))

【问题讨论】:

    标签: python multithreading tkinter


    【解决方案1】:

    tkmessageBox 默认对话框为modal。您可以为此应用程序实现一个简单的非模式对话框。 Here 是一个关于创建自定义对话框的好文档。

    通过这种方式,您可以根据应用的需要创建任意数量的新自定义对话框,因为每个对话框都只是一个新的顶层。

    这是一个简单的 Tkinter 应用程序,它在主窗口中显示时钟。当您单击按钮时,它会在新线程中启动新的 tkMessageBox 对话框。 (如果你运行它)你可以看到运行 TK 事件循环的主线程正在工作(因为时间正在更新),但错误框没有按预期显示。

    #!/usr/bin/env python
    
    import datetime
    import threading                                                                                                                                                                                                                                                               
    from Tkinter import *
    import tkMessageBox
    
    class MyApp(Frame):
        def __init__(self, root=None):
            if not root:
                root = Tk()
            self.time_var = StringVar()
            self.time_var.set('starting timer ...')
    
            self.root = root
            Frame.__init__(self, root)
            self.init_widgets()
            self.update_time()
    
        def init_widgets(self):
            self.label = Label(self.root, textvariable=self.time_var)
            self.label.pack()
            self.btn = Button(self.root, text='show error', command=self.spawn_errors)
            self.btn.pack()
    
        def update_time(self):
            self.time_var.set( str(datetime.datetime.now()) )
            self.root.after(1000, self.update_time)
    
        def spawn_errors(self):
            for i in range(3):
                t = threading.Thread(target=self.show_error)
                t.start()
    
        def show_error(self):
            now = datetime.datetime.now()
            tkMessageBox.showerror('Error: %s' % (str(now)), now)
    
    
    if __name__ == '__main__':
        app = MyApp()
        app.mainloop()
    

    【讨论】:

    • 谢谢你!在编程方面,我更像是一个业余爱好者,所以当涉及到 Tkinter 的课程时,它就超出了我的想象。不管怎样,我正在看它,看看我是否能弄清楚。我只是很难上课,因为我以前从未使用过它们。再次感谢您!
    • 不客气。我添加了一个示例代码,以便您可以将其用作您的应用程序的基础。
    • 不要对课程感到害怕。您已经完成了最困难的事情,即通过实际开始编码迈出了第一步。您可以轻松地了解所有这些,而 Python 显然是一种学习/进行编程的愉快语言。每当你有问题时,你已经知道去哪里问了。 ;)
    • 再次感谢 :D 现在我有一个使用 Toplevel() 而不是 tkMessageBox() 的版本。您最初的帖子使我找到了 Toplevel() ,这正是我所需要的。我还没有使用类,但我正在保存你的例子来学习,这样我就可以学习如何实现类。我将不得不去看一些视频以获得深入的解释,但这真的很棒&我需要的答案。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-07-02
    • 1970-01-01
    • 2021-12-01
    相关资源
    最近更新 更多