Page 1 of 1

Problem with tkinter and threads

Posted: Thu Oct 25, 2018 9:07 pm
by carl47

Code: Select all

from tkinter import Tk,Canvas
import time
from threading import Thread

def run_thread(cv):
    t = Thread(target=display_clock, name = 'cd',args=(cv,10))
    t.daemon = True  #on completion the thread will be killed
    t.start()
def display_clock(cv,ts):
    while True:
        cv.create_rectangle((0, 0), (800, 100),fill='black')
        cv.create_text((400, 40), fill = 'white' ,text= str(time.time()), font=('Helvetica',40))
        time.sleep(ts)    

root = Tk()
cv = Canvas(root,width=800,height=100,bg='black')
cv.pack() 
run_thread(cv)
root.mainloop()
This program is extracted from the full program.
It demonstrates the problem.
Time is displayed every 10 seconds.

I'm using the canvas object in the tkinter mainloop.
I need to have the display calls in its own thread.
The thread is called and the canvas reference is passed
to the display function.

For 30 minutes it works well. The CPU idles at 6% increasing
to 10% at each 10 second call.
After 4 hours we idle at 8% and peak at 100%.
At 10 hours the CPU runs at 100% continuously.
The display gets updated at 15 to 20 second intervals.
Python3 memory use has increased from 16 MB to 18MB.

I cant use this method.
What is going on?
How can I use tkinter and threads?

Re: Problem with tkinter and threads

Posted: Thu Oct 25, 2018 11:19 pm
by Paeryn
Your code is creating a rectangle and a text box every 10 seconds. After 4 hours you will have 1440 rectangles and text boxes on that canvas, after 10 hours you will have 3600 of them (1 each every 10 seconds = 6 each every minute = 360 each every hour). The longer this runs the more objects are created, all these objects need memory and they all need drawing so there is no wonder your memory usage and cpu time is going up.

What you want to do is create the rectangle and text box initially when you create the window, then in your update loop just alter the contents of the text box.

Code: Select all

from tkinter import Tk,Canvas
import time
from threading import Thread

def run_thread(cv, textbox):
    t = Thread(target=display_clock, name = 'cd',args=(cv, textbox, 10))
    t.daemon = True  #on completion the thread will be killed
    t.start()
def display_clock(cv, textbox, ts):
    while True:
        cv.itemconfigure(textbox, text = str(time.time()))
        time.sleep(ts)    

root = Tk()
cv = Canvas(root,width=800,height=100,bg='black')
cv.create_rectangle((0, 0), (800, 100),fill='black')
time_textbox = cv.create_text((400, 40), fill = 'white', text = str(time.time()), font = ('Helvetica', 40))
cv.pack() 
run_thread(cv, time_text_box)
root.mainloop()

Re: Problem with tkinter and threads

Posted: Fri Oct 26, 2018 5:36 am
by carl47
Paeryn

Thank you for a perfect explanation and solution.

I did not know that each create would remain in the
canvas object.
I have made this mistake in other parts of my program.
It did not cause a problem but I will now go back
and fix those errors in my coding.