0

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

2 Answers 2

1

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())
Sign up to request clarification or add additional context in comments.

3 Comments

Thanks for that .... just to clarify ... Is it possible to create separate label widgets in a loop as above, or will I need to create them all separately and give the co-ordinates for each one (I was hoping to avoid that way of doing it :-< ) JJ
You need to think about this as creating the windows and then having them updated. I have updated the answer with an example that constructs the UI in a class and then just updates the text fields in the task method called by the timer.
I've pasted the code and it works, it shouldn't take long to adapt it. Thanks for the help- I've learned a lot with this mini project.
0

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()

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.