当我打电话时
self.client=ThreadedClient()
在我的Python程序中,我得到了错误
“RuntimeError:主线程不在主循环中”
我已经做了一些谷歌搜索,但不知为什么我犯了一个错误。。。有人能帮我吗
完全错误:
线程1中的异常:
回溯(最近一次呼叫最后一次):
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py”,第530行,在bootstrap\u内部
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/threading.py”,第483行,运行中
文件“/Users/Wim/Bird Swarm/Bird_Swarm.py”,第156行,在workerGuiThread中
self.root.after(200,self.workerGuiThread)
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py”,第501行,在后面
文件“/System/Library/Frameworks/Python.framework/Versions/2.7/lib/python2.7/lib-tk/Tkinter.py”,第1098行,在_寄存器中
运行时错误:主线程不在主循环中
课程:
类ThreadedClient(对象):
定义初始化(自):
self.queue=queue.queue()
self.gui=GuiPart(self.queue、self.endApplication)
self.root=self.gui.getRoot()
self.running=True
self.GuiThread=threading.Thread(target=self.workerGuiThread)
self.GuiThread.start()
def WorkerGuitThread(自):
自运行时:
self.root.after(200,self.workerGuiThread)
self.gui.processIncoming()
def端应用程序(自身):
self.running=False
def tc_TekenVogel(自我,vogel):
self.queue.put(vogel)
类GuiPart(对象):
def uuu init uuu(self、queue、endCommand):
self.queue=队列
self.root=Tkinter.Tk()
Canvas(self.root,width=g_grootteschem,height=g_grootteschem).pack()
Tkinter.Button(self.root,text=“Move 1 tick”,command=self.doSomething.pack())
self.vogelcords={}#鸟类登记册及其相应的坐标
def getRoot(self):
返回自根
def doSomething():
通过按钮操作
def processIncoming(自):
而self.queue.qsize():
尝试:
msg=self.queue.get(0)
尝试:
沃格尔=味精
l=vogel.Geeflotatie()
如果self.vogelcords.具有_键(vogel):
cirkel=self.vogelcords[vogel]
self.gcanvas.coords(cirkel,l.geefx()-g_groottevogel,l.geefy()-g_groottevogel,l.geefx()+g_groottevogel,l.geefy()+g_groottevogel)
其他:
cirkel=self.gcanvas.create_oval(l.geefx()-g_groottevogel,l.geefy()-g_groottevogel,l.geefx()+g_groottevogel,l.geefy()+g_groottevogel,填充为红色,轮廓为黑色,宽度为1)
self.vogelcords[vogel]=cirkel
self.gcanvas.update()
除:
打印('Failed,was van het type%'%type(msg))
队列除外。空:
通过
您正在主线程之外的线程中运行主GUI循环。你不能这样做
文档在一些地方不假思索地提到Tkinter不是非常线程安全的,但据我所知,从来没有完全站出来说您只能从主线程与Tk对话。原因是事实有点复杂。Tkinter本身是线程安全的,但很难以多线程方式使用。与此最接近的官方文件似乎是本页:
有线程安全的Tkinter替代方案吗
特金特
只需在主线程中运行所有UI代码,并让编写器写入队列对象
(给出的示例代码不太好,但足以找出他们的建议并正确地执行操作。)
实际上,Tkinter、mtTkinter之外还有一种线程安全的替代方案。它的文档实际上很好地解释了这种情况:
虽然Tkinter在技术上是线程安全的(假设Tk是用–enable线程构建的),但实际上在多线程Python应用程序中使用时仍然存在问题。问题源于这样一个事实,即当处理来自其他线程的调用时,\ u tkinter模块试图通过轮询技术获得对主线程的控制
我相信这正是您所看到的:Thread-1中的Tkinter代码试图窥视主线程以找到主循环,但它不在那里
因此,这里有一些选择:
- 执行Tkinter文档推荐的操作,并从主线程使用Tkinter。可能通过将当前主线程代码移动到工作线程中
- 如果您正在使用希望接管主线程的其他库(例如,
twisted),它可能有一种与Tkinter集成的方法,在这种情况下,您应该使用它 - 使用
mkTkinter解决此问题
另外,虽然我没有找到任何与这个问题完全相同的问题,但也有一些相关的问题。有关更多信息,请参见此问题、此答案以及更多内容