JJ_
JJ_

Reputation: 113

Tkinter gui stops processing (Binary clock)

Since I'm new to Python I hope this is a blindingly obvious question.

I'm coding a binary clock (i.e. shows 1s and 0s, but will ultimately display graphics of large LEDs)

Here is the code which I have used so far:

#Simple binary clock
#Python 3.3.2

from tkinter import *
import time

root=Tk()
root.title("Title")
root.geometry("500x500")

def task():

    tme= time.strftime("%H",time.localtime()) + time.strftime("%M",time.localtime()) + time.strftime("%S",time.localtime())
    print(tme)
    hpos=0
    for c in tme:               #tme set to HHMMSS, iterate through each digit
        col=50+hpos*50          #Set column position
        b=format(int(c),'04b')  #Covert digit to 4 bit binary
        vpos=0

        for r in b:
            row=50+vpos*50
            if r=="1":
                label1=Label(root,text="1")                
            else:
                label1=Label(root,text="0")                
            label1.place(x=col,y=row)
            vpos+=1
        hpos+=1

    root.after(1000,task)       #reschedule event, 1000=1sec

root.after(100,task)
root.mainloop()

The issue is this- after leaving to run the code for about 15 minutes it slows down and grinds to a halt. I've tried it on more than one PC to the same effect, I want this to work on a Raspberry Pi but again it has the same result.

I will eventually make the form fill the screen and use graphics in the label widgets- I'm open to suggestions to solving the solution in a different way.

Thanks in advance for any help you are able to offer.

JJ

Upvotes: 0

Views: 440

Answers (2)

patthoyts
patthoyts

Reputation: 33203

The line label1 = Label(root, ...) creates a new window each time and places this on top of the previous instance. So over time you are creating more and more windows which gradually consumes your memory.

Instead, create the label once and place it. Then just update it's text property in the task so that it displays the new value in the same window instance.

Also, you can format time in one call time.strftime("%H%M%S",time.localtime())

Example

from Tkinter import *
import sys,time

class App():
    def __init__(self, parent):
        parent.title("Title")
        parent.geometry("500x500")
        self.labels = []
        self.parent = parent
        x,y = 50,50
        for index in range(3):
            label = Label(parent, text='0')
            label.place(x = x, y = y)
            self.labels.append(label)
            y += 50
        self.parent.after(1000, self.Task)

    def Task(self):
        t = time.strftime("%H:%M:%S", time.localtime())
        print(t)
        index = 0
        for c in t.split(':'):
            b = format(int(c), '04b')
            self.labels[index].configure(text=b)
            index += 1
        self.parent.after(1000, self.Task)


def main():
    root = Tk()
    app = App(root)
    root.mainloop()

if __name__=='__main__':
    sys.exit(main())

Upvotes: 1

JJ_
JJ_

Reputation: 113

I've attempted to put in the changes as outlined, I've added a separate widget for each bit, initialized them, placed them on the form.

On changing the text of the widgets the form is not updated. I have looked to see if the label widget has an update method, but apparently not. I must be missing something really obvious here.

I have a slimmed-down version of the code here which only displays the last digit of the seconds, what have I missed?:

#Simple binary clock

from tkinter import *
import time

root=Tk()
root.title("Title")
root.geometry("500x500")

def task():

    tme=time.strftime("%S",time.localtime())    #testing on just the seconds
    tme=tme[1]  #testing, just take last digit of seconds
    print(tme)

    for c in tme:               #tme set to HHMMSS, iterate through each digit
        b=format(int(c),'04b')  #Covert digit to 4 bit binary

        print(b)
        if b[0]=="1":
            label0=Label(root,text="1")                
        else:
            label0=Label(root,text="0")

        if b[1]=="1":
            label1=Label(root,text="1")                
        else:
            label1=Label(root,text="0")

        if b[2]=="1":
            label2=Label(root,text="1")                
        else:
            label2=Label(root,text="0")

        if b[3]=="1":
            label3=Label(root,text="1")

        else:
            label3=Label(root,text="0")


    root.after(1000,task)       #reschedule event, 1000=1sec

label0=Label(root, text="*")
label0.place(x=50,y=50)

label1=Label(root, text="*")
label1.place(x=50,y=100)

label2=Label(root, text="*")
label2.place(x=50, y=150)

label3=Label(root, text="*")
label3.place(x=50,y=200)


root.after(1000,task)
root.mainloop()

Upvotes: 0

Related Questions