On Jul 4, 3:21 am, Peter Otten <__pete...@web.de> wrote: > Icarus wrote: > > I'm working on a serial protocol analyzer in python. We have an > > application written by someone else in MFC but we need something that > > is cross platform. I intended to implement the GUI portion in Tkinter > > but am having trouble. > > > The idea is that I will read messages from the serial port and output > > them to a Tkinter Text object initially. Eventually it will have > > other functionality but that's it for the short term. I've written > > this little test app to experiment with putting things on the GUI via > > a Queue which is polled by the Tkinter loop. > > > On some machines this code works fine and I get whatever I type in > > displayed in the Text widget. On others I get errors like this as > > soon as I start it running. > > > error in background error handler: > > out of stack space (infinite loop?) > > while executing > > "::tcl::Bgerror {out of stack space (infinite loop?)} {-code 1 -level > > 0 -errorcode NONE -errorinfo {out of stack space (infinite loop?) > > while execu..." > > > I don't understand why on some machines it works exactly as expected > > and on others it acts the same way Tkinter does when I call functions > > directly from outside the Tkinter thread. Does anyone have any > > suggestions? The full code as appended below. Thanks in advance. > > > [code] > > > import Queue > > > class functionQueue: > > > def __init__(self, root = None, timeout = 250): > > > self.functionQueue = Queue.Queue() > > self.root = root > > self.timeout = timeout > > > if(self.root): > > self.pop_function(root) > > > def pop_function(self, root = None): > > > try: > > funcArgList = self.functionQueue.get(block = False) > > except Queue.Empty: > > pass > > else: > > try: > > funcArgList[0](*funcArgList[1]) > > except: > > try: > > print "Failed to call function", funcArgList[0] > > except: > > print "Failed to call function" > > > if(root): > > root.after(self.timeout, lambda: self.pop_function > > (self.root)) > > > def add_function(self, function, argList): > > > try: > > self.functionQueue.put([function, argList]) > > except: > > pass > > > if( __name__ == '__main__'): > > > import Tkinter > > import thread > > > text = Tkinter.Text() > > text.pack() > > > myQueue = functionQueue(text, 50) > > > def gui_loop(): > > try: > > text.mainloop() > > except: > > import os > > os._exit(1) > > > thread.start_new_thread(text.mainloop, ()) > > > while(True): > > usrInput = raw_input() > > > if(usrInput == "-1"): > > import os > > os._exit(0) > > > myQueue.add_function(text.insert, ['end', usrInput + "\n"]) > > myQueue.add_function(text.see, ['end']) > > > [/code] > > I can make it work over here by putting the UI into the main thread, as > suggested byhttp://effbot.org/zone/tkinter-threads.htm: > > import Queue > import Tkinter > import threading > > class FunctionQueue: > # unchanged > > def input_loop(): > while True: > try: > usrInput = raw_input() > except EOFError: > break > myQueue.add_function(text.insert, ['end', usrInput + "\n"]) > myQueue.add_function(text.see, ['end']) > myQueue.add_function(text.quit, []) > > if __name__ == '__main__': > text = Tkinter.Text() > text.pack() > > myQueue = FunctionQueue(text, 50) > threading.Thread(target=input_loop).start() > text.mainloop() > > Peter
Peter, thanks for the suggestion. I tried your code exactly on my box and I still get the same results. As soon as I run the script and every time I click on the Text box I get tcl::Bgerror ... just like I mentioned above. I'm fairly certain that I'm not calling Tkinter functions from any other thread but it's acting as though I am as soon as I create the input thread. If I comment out the input loop thread everything is fine but of course that's not terribly useful as a logging box. -- http://mail.python.org/mailman/listinfo/python-list