Problems with using queue in Tkinter application

Icarus asm198 at gmail.com
Sat Jul 4 03:14:23 CEST 2009


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]




More information about the Python-list mailing list