Reputation: 113
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
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
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