Tkinter与线程 - 异常:堆栈空间不足(无限循环?)

3 投票
2 回答
3810 浏览
提问于 2025-04-17 13:39

我们实现了一个分布式聊天程序,使用的是Tkinter图形界面。最近我把系统更新到了Fedora18,结果在调用Tkinter事件时出现了异常,几乎和这里描述的情况一样:

Exception in thread Thread-1:
Traceback (most recent call last):
File "/usr/lib64/python2.7/threading.py", line 551, in bootstrap_inner self.run()
File "/usr/lib64/python2.7/threading.py", line 504, in run self.target(*self.__args, **self.__kwargs)
File "/hachat/peer.py", line 156, in startRecvLoop
self.processMessage(msg, addr)
File "/hachat/peer.py", line 222, in processMessage
self.gui.receive(msg) 
File "/hachat/gui.py", line 74, in receive
self.textfenster.insert(END,msg.name+": "+msg.text+'\n')
File "/usr/lib64/python2.7/lib-tk/Tkinter.py", line 2986, in insert
self.tk.call((self._w, 'insert', index, chars) + args)
TclError: out of stack space (infinite loop?)

这是我从图形界面类中摘录的一部分:

import Tkinter
import ScrolledText
import tkMessageBox
import tkSimpleDialog
import threading 

class gui(object):

    def __init__(self, parent):
        self.root = Tkinter.Tk()             
        self.textfenster = ScrolledText.ScrolledText(self.fpopup,width=90,height=24,background='white')
        self.textfenster.pack(fill=Tkinter.BOTH, expand=Tkinter.YES)

    def run(self):
        self.guiRunThread = threading.Thread(target=self.root.mainloop())
        self.guiRunThread.daemon = True
        self.guiRunThread.start()

    def receive(self,msg):
        self.textfenster.insert(Tkinter.END,msg.name+": "+msg.text+'\n')
        self.textfenster.see(Tkinter.END)

这个异常只在我的系统上出现,原因似乎是tk没有编译成支持多线程的版本。我需要解决这个异常,因为这个程序是分布式的,需要在不同的系统上运行。所以我想知道如何解决这个异常,以及如何让tk支持多线程的提示。我使用的Python版本是2.7.3,Tcl/Tk版本是8.5。运行import Tkinter; Tkinter.Tk().tk.eval("puts $tcl_platform(threaded)")也会返回一个异常。

2 个回答

0

这个可以用:

from Tkinter import *
from ScrolledText import ScrolledText
from threading import Thread

scrolled = None

def start():
    global scrolled
    root = Tk()
    scrolled = ScrolledText(root)
    scrolled.pack(fill=BOTH, expand=YES)
    return root

Thread(target=start().mainloop).start()

print scrolled.get(0.0, END)
1

我用队列解决了和Tk通信的问题。你可以看看这个链接,里面有个例子:Mutli-threading python with Tkinter!

撰写回答