Python tkinter错误消息

Python tkinter错误消息,python,multithreading,thread-safety,tkinter,Python,Multithreading,Thread Safety,Tkinter,我有一个跨多个模块的应用程序,包括一个主模块、一个UI、一个处理函数和一个保存全局变量的模块。我在tkinter抛出错误消息时遇到问题,但我不明白为什么,我认为路由原因可能与tkinter无关(可能与线程有关?) 具有相同问题的应用程序简化如下: mymain.py import math import random from Tkinter import * from ttk import * import tkMessageBox import myui import myfunction

我有一个跨多个模块的应用程序,包括一个主模块、一个UI、一个处理函数和一个保存全局变量的模块。我在tkinter抛出错误消息时遇到问题,但我不明白为什么,我认为路由原因可能与tkinter无关(可能与线程有关?)

具有相同问题的应用程序简化如下:

mymain.py

import math
import random
from Tkinter import *
from ttk import *
import tkMessageBox

import myui
import myfunction
import myglobals

root = Tk()

myglobals.ui = myui.UI(root)

root.mainloop()
import thread
import random

import myglobals
import myui

def myfunc():
    multiprint(str(random.random()))
    thread.start_new_thread(myfunc,())



def multiprint(*args):
    msg = ' '.join([str(arg) for arg in args])
    print msg
    if myglobals.ui:
        myglobals.ui.writeToLog(msg)
from Tkinter import *
from ttk import *
import tkMessageBox
import types
import time
import random

import myfunction

class UI:


    def __init__(self, master):

        self.master = master

        #top frame

        self.topframe = Frame(self.master)
        self.topframe.pack(fill=X)

        self.button = Button(self.topframe, text="Start", command=self.startgame)
        self.button.pack(side=LEFT)


        #event frame

        self.logframe = Frame(self.master)
        self.logframe.pack(fill=X)

        self.logframetitle = Label(self.logframe, text="Event log:")
        self.logframetitle.pack(fill=X)

        self.scrollbar = Scrollbar(self.master)
        self.scrollbar.pack(side=RIGHT, fill=Y)

        self.log = Text(self.master, state='disabled', height=24, wrap='none', yscrollcommand=self.scrollbar.set)
        self.log.pack(fill=X)

        self.scrollbar.config(command=self.log.yview)


    def startgame(self):
        myfunction.myfunc()

    def writeToLog(self,msg):
        numlines = self.log.index('end').split('.')[0] #self.log.index('end - 1 line') gives the start of the last line of text
        print 'The log is', numlines, 'long'
        self.log['state'] = 'normal'
        if self.log.index('end-1c')!='1.0':
            self.log.insert('end', '\n')
        time.sleep(0.1)
        self.log.insert('end', msg)
        self.log['state'] = 'disabled'
        self.log.see('end')



def main():

    root = Tk()

    ui = UI(root)

    root.mainloop()

if __name__ == '__main__':
    main()
myfunction.py

import math
import random
from Tkinter import *
from ttk import *
import tkMessageBox

import myui
import myfunction
import myglobals

root = Tk()

myglobals.ui = myui.UI(root)

root.mainloop()
import thread
import random

import myglobals
import myui

def myfunc():
    multiprint(str(random.random()))
    thread.start_new_thread(myfunc,())



def multiprint(*args):
    msg = ' '.join([str(arg) for arg in args])
    print msg
    if myglobals.ui:
        myglobals.ui.writeToLog(msg)
from Tkinter import *
from ttk import *
import tkMessageBox
import types
import time
import random

import myfunction

class UI:


    def __init__(self, master):

        self.master = master

        #top frame

        self.topframe = Frame(self.master)
        self.topframe.pack(fill=X)

        self.button = Button(self.topframe, text="Start", command=self.startgame)
        self.button.pack(side=LEFT)


        #event frame

        self.logframe = Frame(self.master)
        self.logframe.pack(fill=X)

        self.logframetitle = Label(self.logframe, text="Event log:")
        self.logframetitle.pack(fill=X)

        self.scrollbar = Scrollbar(self.master)
        self.scrollbar.pack(side=RIGHT, fill=Y)

        self.log = Text(self.master, state='disabled', height=24, wrap='none', yscrollcommand=self.scrollbar.set)
        self.log.pack(fill=X)

        self.scrollbar.config(command=self.log.yview)


    def startgame(self):
        myfunction.myfunc()

    def writeToLog(self,msg):
        numlines = self.log.index('end').split('.')[0] #self.log.index('end - 1 line') gives the start of the last line of text
        print 'The log is', numlines, 'long'
        self.log['state'] = 'normal'
        if self.log.index('end-1c')!='1.0':
            self.log.insert('end', '\n')
        time.sleep(0.1)
        self.log.insert('end', msg)
        self.log['state'] = 'disabled'
        self.log.see('end')



def main():

    root = Tk()

    ui = UI(root)

    root.mainloop()

if __name__ == '__main__':
    main()
myui.py

import math
import random
from Tkinter import *
from ttk import *
import tkMessageBox

import myui
import myfunction
import myglobals

root = Tk()

myglobals.ui = myui.UI(root)

root.mainloop()
import thread
import random

import myglobals
import myui

def myfunc():
    multiprint(str(random.random()))
    thread.start_new_thread(myfunc,())



def multiprint(*args):
    msg = ' '.join([str(arg) for arg in args])
    print msg
    if myglobals.ui:
        myglobals.ui.writeToLog(msg)
from Tkinter import *
from ttk import *
import tkMessageBox
import types
import time
import random

import myfunction

class UI:


    def __init__(self, master):

        self.master = master

        #top frame

        self.topframe = Frame(self.master)
        self.topframe.pack(fill=X)

        self.button = Button(self.topframe, text="Start", command=self.startgame)
        self.button.pack(side=LEFT)


        #event frame

        self.logframe = Frame(self.master)
        self.logframe.pack(fill=X)

        self.logframetitle = Label(self.logframe, text="Event log:")
        self.logframetitle.pack(fill=X)

        self.scrollbar = Scrollbar(self.master)
        self.scrollbar.pack(side=RIGHT, fill=Y)

        self.log = Text(self.master, state='disabled', height=24, wrap='none', yscrollcommand=self.scrollbar.set)
        self.log.pack(fill=X)

        self.scrollbar.config(command=self.log.yview)


    def startgame(self):
        myfunction.myfunc()

    def writeToLog(self,msg):
        numlines = self.log.index('end').split('.')[0] #self.log.index('end - 1 line') gives the start of the last line of text
        print 'The log is', numlines, 'long'
        self.log['state'] = 'normal'
        if self.log.index('end-1c')!='1.0':
            self.log.insert('end', '\n')
        time.sleep(0.1)
        self.log.insert('end', msg)
        self.log['state'] = 'disabled'
        self.log.see('end')



def main():

    root = Tk()

    ui = UI(root)

    root.mainloop()

if __name__ == '__main__':
    main()
myglobals.py是一个包含变量的空白文件

我收到的错误消息包括以下内容:

Exception in Tkinter callback
Traceback (most recent call last):
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1470, in __call__
    return self.func(*args)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 2860, in set
    self.tk.call((self._w, 'set') + args)
TclError: invalid command name "512.14"

由启动的线程中未处理的异常 回溯(最近一次呼叫最后一次): 文件“C:\myfunction.py”,第20行,在myfunc中 多重打印(str(random.random())) 文件“C:\myfunction.py”,第29行,多打印 myglobals.ui.writeToLog(msg) 文件“C:\myui.py”,第67行,写日志 self.log['state']='disabled' 文件“C:\Python27\lib\lib tk\Tkinter.py”,第1269行,在uu setitem中__ self.configure({key:value}) 文件“C:\Python27\lib\lib tk\Tkinter.py”,第1262行,在configure中 返回自。_配置('configure',cnf,kw) 文件“C:\Python27\lib\lib tk\Tkinter.py”,第1253行,在_configure中 self.tk.call(_flatten((self._w,cmd))+self._选项(cnf)) _tkinter.TclError:无效的命令名“.43240984” 我对如何理解这些错误消息感到困惑。我试着用谷歌搜索消息代码,但到目前为止还没有发现任何有用的东西


非常感谢您的帮助。

错误消息中提到了线程。在堆栈跟踪中,看起来您正在更改变量的状态。如果这是真的,并且您试图从创建小部件的线程以外的线程更改小部件的状态,那么这就是问题所在。除了创建小部件的线程外,您不能从任何线程调用小部件方法。

谢谢。我不知道你不能那样做。我认为这可能解释了第二条错误消息,但第一条没有提到线程,所以可能有两个不同的问题?有趣的是,如果你运行这个程序,它大部分时间都运行得很好,只是偶尔会抛出错误。这是我不理解的地方,因为错误不一致。可能是两个不同的问题,可能不是。与线程(非)安全性相关的错误有时可能是随机的,难以理解。