Threading and tkinter

Hendrik van Rooyen mail at microcorp.co.za
Thu Feb 19 05:08:22 EST 2009


 "gert" <gert......s at gmail.com> wrote:


>On Feb 18, 8:25 am, "Hendrik van Rooyen" <m... at microcorp.co.za> wrote:
>> "gert" <gert.cuyk... at gmail.com>wrote:
>>
>> > After reading the docs and seeing a few examples i think this should
>> > work ?
>> > Am I forgetting something here or am I doing something stupid ?
>> > Anyway I see my yellow screen, that has to count for something :)
>>
>> > from tkinter import *
>> > from threading import Thread
>>
>> > class Weegbrug(Thread):
>> > def __init__(self,v):
.> > self.v=v
>> > Thread.__init__(self)
>> > def run(self):
>> > while True:
>> > with open('com1','r') as f:
>> > for line in f:
>> > self.v.set(line[2:-1])
>>
>> It is in general not a good idea to directly
>> access GUI variables from outside the
>> GUI main loop.
>> There is a recipe for doing this sort of thing,
>> but as usual I have lost the reference.
>> What it does is that instead of interfering directly
>> as above, you put the data on a queue.
>>
>> Then, you use the after() call to set up a call
>> to a routine that reads the queue, and configures the
>> display, and then uses after again to call itself again
>> after a time, thereby keeping the GUI stuff in the GUI
>> mainloop.
>>
>
>from tkinter import *
>from threading import Thread
>
>class Weegbrug(Thread):
>    def __init__(self):
>        self.display='00000'
>        Thread.__init__(self)
>    def run(self):
>        x=0
>        while True:
>            x=x+1
>            self.display=x

Still mucking around from outside the GUI.

>            #with open('com1','r') as f:
>            #     for l in f:
>            #         self.display=l[2:-1]
>
>root = Tk()
>v = StringVar()
>v.set('00000')
>w = Weegbrug()
>w.start()
>tx = Label(root, textvariable=v, width=800, height=600, bg='yellow',
>font=('Helvetica', 300))
>tx.pack(expand=YES, fill=BOTH)
>root.title('Weegbrug')
>root.overrideredirect(1)
>root.geometry('%dx%d+0+0' % (root.winfo_screenwidth(),
>root.winfo_screenheight()))
>root.after(500, v.set(w.display))

root.after(500,displayer(q))  # You set up a "stutter thread" like this

>root.mainloop()
>
>Why does this not work ?
>It only shows one result ?

You are only calling it once.
Read my story above again.  (And Again)
Specially the bit about putting the
values into a queue.

You need to do something like this:

def displayer(q):
  # stuff to read the queue and update the display
  root.after(500, displayer(q))        # This makes sure it keeps on stuttering

Where q is an instance of Queue.Queue

There is a nice recipe by Thomas Haeller (?) but I have lost the link.

- Hendrik





More information about the Python-list mailing list