我有一个python程序,它正在为客户端抓取Web数据。 tkinter用于接口。大纲是:
该程序将适用于前几百页,但随后它开始吐出错误消息:
Traceback (most recent call last):
File "C:\Users\Me\AppData\Local\Programs\Python\Python35-32\lib\tkinter\__init__.py", line 248, in __del__
if self._tk.getboolean(self._tk.call("info", "exists", self._name)):
RuntimeError: main thread is not in main loop
Exception ignored in: <bound method Variable.__del__ of <tkinter.IntVar object at 0x03245510>>
多次,直到所有线程都停止。不知道是什么导致了这个错误。实际代码是:
import scraper, threading
import tkinter as tk
from queue import Queue
outputQueue = Queue()
class OutputRedirect(object):
def __init__():
super().__init__()
def write(self, string):
outputQueue.put(string)
def getInformation():
stdout = sys.stdout
sys.stdout = OutputRedirect()
scraper.startThreads()
scraper.startPulling()
sys.stdout = stdout
def updateTextField(window, root):
if not outputQueue.empty():
string = outputQueue.get()
window.textArea.insert("insert", string)
outputQueue.task_done()
root.after(1, updateTextField, window, root)
'''widget/window definitions - not important'''
guiInfo = {"stuff1": [], "stuff2": []}
root = tk.Tk()
window1 = Window1(root, guiInfo)
window1.mainloop()
pullThread = threading.Thread(target=pullClaims,
args=(list(guiInfo["stuff1"]),
list(guiInfo["stuff2"])), daemon=True)
pullThread.start()
root = tk.Tk()
window2 = Window2(root)
root.after(0, updateTextField, window2, root)
window2.mainloop()
刮刀程序(单独工作正常)使用print语句进行用户反馈。我只是将stdout指向队列,而不是重写所有内容。主线程使用“after”函数每秒检查一次队列几次。如果其中有任何内容,则会将其打印到窗口上的“文本”小部件中。
我在代码中的任何地方放置了try / catch,但它们没有抓到任何东西。我确信问题出现在主循环中,但是我找不到任何关于如何在其中添加新内容的最新信息。任何帮助将不胜感激。
答案 0 :(得分:0)
要处理tkinter错误,请执行以下操作
class TkErrorCatcher:
'''
In some cases tkinter will only print the traceback.
Enables the program to catch tkinter errors normally
To use
import tkinter
tkinter.CallWrapper = TkErrorCatcher
'''
def __init__(self, func, subst, widget):
self.func = func
self.subst = subst
self.widget = widget
def __call__(self, *args):
try:
if self.subst:
args = self.subst(*args)
return self.func(*args)
except SystemExit as msg:
raise SystemExit(msg)
except Exception as err:
raise err
import tkinter
tkinter.CallWrapper = TkErrorCatcher
但在你的情况下请不要这样做。只有在想要在生产时隐藏用户的错误消息时才应该这样做。如上所述,你有一个nono's正在进行。
要生成多个窗口,您可以使用tkinter.Toplevel
我建议一般阅读
并且针对您在tkinter中的特定线程问题,这个博客文章指出了它。基本上你需要让tkinter mainloop阻塞程序主线程,然后在其他线程的调用之后使用来运行mainloop中的其他代码。