Threading and tkinter

gert gert.cuykens at gmail.com
Wed Mar 25 21:26:45 CET 2009


On Mar 7, 9:40 am, Jani Hakala <jahak... at iki.fi> 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 :)
>
> I have been using the following scheme:
>   - Pass the root object to the thread object when creating the object
>   - Define a event_handler: root.bind('<<SomeEvent>>', evt_handler) in
>     the main thread.
>
>   - When the thread has done something that the GUI part should now
>     about, signal an event in the thread:
>         root.event_generate('<<SomeEvent>>')    (no other arguments)
>
>   - Call a method of the thread object in the event handler e.g. to get
>     some data from a queue object.
>
> This ensures that only the main thread accesses Tkinter-related things.
>

Thanks :-)
PS why does the first example leave a running process (dos box) open
when you close the gui and yours not ?
Also root.after can make the program crash if the threat is waiting
for com1 response.
Speaking of com1 ports, for some reason I have to start up some other
serial terminal app and close it again before the device is returning
data to the python app ? Do you need to send something to the com1
device first ?

-----------first example--------------

from tkinter import *
from threading import Thread
from time import sleep

class Weegbrug(Thread):
    def __init__(self):
        Thread.__init__(self)
        self.x=0
    def run(self):
        while True:
            self.x=self.x+1
            sleep(0.5)

w = Weegbrug()
w.start()

def display():
    v.set(w.x)
    root.after(500, display)

root = Tk()
v = StringVar()
txt = Label(root, textvariable=v, width=800, height=600, bg='yellow',
font=('Helvetica', 300))
txt.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, display)
root.mainloop()

from tkinter import *
from threading import Thread
from queue import Queue
from time import sleep

----------second example-------------

class Weegbrug(Thread):
    def __init__(self, gui):
        Thread.__init__(self)
        self.gui = gui
        self.queue = Queue()

    def run(self):
        while True:
            with open('com1', 'w+') as f:
                for line in f:
                    self.queue.put(line)
                    self.gui.event_generate('<<LineRead>>')
                    time.sleep(0.5)

    def get_line(self):
        return self.queue.get()

def evt_handler(*args):
    v.set(w.get_line())

r = Tk()
r.title('Weegbrug')
r.overrideredirect(1)
r.geometry('%dx%d+0+0' % (r.winfo_screenwidth(),r.winfo_screenheight
()))
r.bind('<<LineRead>>', evt_handler)
v = StringVar()
v.set('00000')
t = Label(r, textvariable=v, width=100, bg='yellow', font=
('Helvetica', 300))
t.pack(expand=YES, fill=BOTH)
w = Weegbrug(r)
w.start()
r.mainloop()




More information about the Python-list mailing list