【问题标题】:Tkinter multithreading queue waits foreverTkinter 多线程队列永远等待
【发布时间】:2014-04-02 17:30:07
【问题描述】:

我的 tkinter 应用程序有 2 个线程(我需要它们),我在 stackoverflow 上找到了一个很棒的函数 tkloop(),它是为 tkinter-only-one-main-thread 制作的;它使用队列。当我这样做时,它确实显示 tkMessagebox:

self.q.put((tkMessageBox.askyesno,("Cannot download it", "Download \"" + tag +"\" via internet site"),{}, self.q1 ))

但是当我创建自己的函数时,它以某种方式不执行该函数

self.q.put((self.topleveldo,(resultlist),{},None))

只有一个类 App:

self.q=Queue()
def tkloop(self):
    try:
        while True:
            f, a, k, qr = self.q.get_nowait()
            print f
            r = f(*a,**k)

            if qr: qr.put(r)
    except:
        pass
    self.okno.after(100, self.tkloop)
def topleveldo(resultlist):
    print ("executed - actually this never prints")
    self.choice=Toplevel()
    self.choices=Listbox(self.choice)
    for result in resultlist:
        self.choices.insert(END,str(result))
    choosebutton=Button(text="Vybrat",command=self.readchoice)
def readchoice(self):
    choice=int(self.choices.curselection())
    self.choice.destroy()
    self.q1.put(choice)

App 类方法中的另一个代码,由第二个线程运行:

def method(self):
    self.q1=Queue()
    self.q.put((self.topleveldo,(resultlist),{},None))
    print ("it still prints this, but then it waits forever for q1.get, because self.topleveldo is never executed")
    choice=self.q1.get()

【问题讨论】:

    标签: python multithreading python-2.7 tkinter queue


    【解决方案1】:

    在 tkloop 异常处理程序中记录错误 - 现在您不知道对 topleveldo 的调用是否失败(它可能失败了)。问题是 (1) (resultlist) 只是结果列表,而不是像 topleveldo 期望的那样具有 1 个参数的元组。并且 (2) tkloop 仅在消息中的第 4 个参数是队列时才发出响应。您可以使用以下方法修复它:

    self.q.put((self.topleveldo,(resultlist,),{},self.q1))
    

    已添加:

    tkloop 应该总是返回一条消息,即使它捕获了一个异常,以便调用者可以可靠地调用 q.get() 来获得响应。一种方法是返回被调用程序引发的异常:

    def tkloop(self):
        while True:
            try:
                f, a, k, qr = self.q.get_nowait()
                print f
                r = f(*a,**k)
                if qr: 
                    qr.put(r)
                del f,a,k,qr
        except Exception, e:
            if qr:
                try:
                    qr.put(e)
                except:
                    # log it
                    pass
        self.okno.after(100, self.tkloop)
    

    【讨论】:

    • 好的,我试试 tuple(resultlist),但 topleveldo 不应该返回任何东西。 readchoice 执行 self.q1.put(choice)
    • 哦,谢谢!只需要捕获并打印异常。 topleveldo() 只需要 1 个参数(给定 11 个)似乎没有你所说的元组。那么当 tuple(resultlist) 不起作用时我该如何做 tuple 呢?
    • 我更新了响应以显示(resultlist,)(注意额外的逗号)等等。我没有注意到你在选择按钮中使用 self.q1 的方式。
    • 我试过 (resultlist,),{},None 但我得到:topleveldo() 只需要 1 个参数(给定 2 个)
    • 对不起,在顶层没有自我:D
    猜你喜欢
    • 1970-01-01
    • 2017-08-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-01-19
    • 1970-01-01
    • 1970-01-01
    • 2013-11-24
    相关资源
    最近更新 更多