user1379351
user1379351

Reputation: 785

Python tkinter error messages

I have an application spread across several modules that consists of a main module, a UI, a processing function and a module to hold the global variables. I'm having problems with tkinter throwing error messages, but I don't understand why, and I think the route cause may be unrelated to tkinter (possibly to do with threading?).

A simplification of the application that exhibits the same issues is as follows:

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()

myfunction.py

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)

myui.py

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 is a blank file that holds the variables.

The error messages I'm getting include the following:

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"

and

Unhandled exception in thread started by <function myfunc at 0x02940A30>
Traceback (most recent call last):
  File "C:\myfunction.py", line 20, in myfunc
    multiprint(str(random.random()))
  File "C:\myfunction.py", line 29, in multiprint
    myglobals.ui.writeToLog(msg)
  File "C:\myui.py", line 67, in writeToLog
    self.log['state'] = 'disabled'
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1269, in __setitem__
    self.configure({key: value})
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1262, in configure
    return self._configure('configure', cnf, kw)
  File "C:\Python27\lib\lib-tk\Tkinter.py", line 1253, in _configure
    self.tk.call(_flatten((self._w, cmd)) + self._options(cnf))
_tkinter.TclError: invalid command name ".43240984"

I am bemused about how to understand these error messages. I've tried googling the message codes, but haven't found anything helpful so far.

Really grateful for any assistance.

Upvotes: 2

Views: 2328

Answers (1)

Bryan Oakley
Bryan Oakley

Reputation: 385980

The error message mentions threads. In the stack trace it looks like you are altering the state of a variable. If that is true, and you're trying to alter the state of a widget from a thread other than the one that created the widget, that's the problem. You cannot call widget methods from any thread except the one that created the widget.

Upvotes: 3

Related Questions