I'm trying to make a program that will work as an "infomercial" in a separate window.
What i have are two integers (x and y) that both increase at the same time, in this case every 5 seconds. With the increasing values i need a timer displayed at the same time, that can show the elapsed time of how long the program has been running. I want to be albe to start and pause the program
So far i have an infinite while loop running where the values are increased every 5 seconds with time.sleep(5). I have tried implementing a timer in the form of a time.time(), and get it to work with the increments. I have also added buttons but don't work. I'm using tkinter as gui obtion.
How am i supposed to make it work? with threading?
import time
from tkinter import *
import math
usage = 0
yearly = 0
cubik = 0
price = 0
root = Tk()
root.title("Usage of fluid")
root.geometry("300x400")
var = IntVar()
var1 = IntVar()
var2 = StringVar()
var3 = StringVar()
var4 = StringVar()
def update_timeText():
current= time.strftime("%H:%M:%S")
timeText.configure(text=current)
root.after(1000, update_timeText)
def start():
global state
state = True
def pause():
global state
state = False
def exist():
root.destroy()
frame = LabelFrame(root, text="Liter", font=30)
frame.pack(fill = "both", expand="yes")
l = Label(frame, textvariable=var, font=20)
l.pack(pady = 3)
frame2 = LabelFrame(root, text="price from use", font=30)
frame2.pack(fill = "both", expand= "yes")
l2 = Label(frame2, textvariable=var1, font=16)
l2.pack(side = LEFT)
l3 = Label(frame2, text="dollars", font=16)
l3.pack(side=LEFT)
frame3 = LabelFrame(root, text="yearly", font=30)
frame3.pack(fill = "both", expand="yes")
m3 = Label(frame3, textvariable=var2, font=16, wraplength=0)
m3.pack(side=TOP)
l4 = Label(frame3, text="Liter", font=16)
l4.pack(side=TOP)
l5 = Label(frame3, text="m3", font=16)
l5.pack(side=BOTTOM, fill="both")
m4 = Label(frame3, textvariable=var3, font=16, wraplength=0)
m4.pack(side=BOTTOM)
frame4 = LabelFrame(root, text='runtime', font=30)
frame4.pack(fill = "both", expand="yes")
timeText= Label(frame4, text="", font=16)
timeText.pack()
startButton = Button(frame4, text='Start', command=start)
startButton.pack()
pauseButton = Button(frame4, text='Pause', command=pause)
pauseButton.pack()
quitButton = Button(frame4, text='Quit', command=quit)
quitButton.pack()
while True:
var.set(usage)
usage += 300
var1.set(round(price,1))
price+= 10
var2.set(yearly)
var3.set(round(cubik,1))
yearly += 300
cubik += 0.1
time.sleep(5)
update_timeText()
root.update_idletasks()
##update_timeText()
##root.mainloop()
Related
I was trying to make a simple Simple Interest calculator using Pycharm and tkinter.
There is my code
It is showing that x is not defined
I already tried to put variable as global.
Also I cant call that function in my finalProgram function because it makes it as endless loop
from tkinter import *
def mainWindow():
label = Label(frame, text = "What do you want to do")
label.pack()
but1 = Button(frame, text = "SI", command = SimpleInterest)
but1.pack()
def SimpleInterest():
global x
frame.destroy()
label5 = Label(frame2,text="Please enter principal amount" )
label5.pack()
p = Entry(frame2 )
p.pack()
label6 = Label(frame3,text="Please ROI")
label6.pack()
r = Entry(frame3, text="Please enter rate of interest")
r.pack()
label7 = Label(frame4, text="Please enter time")
label7.pack()
t = Entry(frame4, text="Please enter time")
t.pack()
buttonmain = Button(frame4, text = "Finlise", command = finalProgram)
buttonmain.pack()
global x
x =(p*r*t)/100
def finalProgram():
frame2.destroy()
frame3.destroy()
frame4.destroy()
global x
newlabel = Label(frame5, text = x)
root = Tk()
frame = Frame(root)
frame.grid(row=0,columnspan = 2)
mainWindow()
frame2 = Frame(root)
frame2.grid(row = 0, columnspan =2)
frame3 = Frame(root)
frame3.grid(row =1, columnspan =2)
frame4 = Frame(root)
frame4.grid(row=2, columnspan =2)
frame5 = Frame(root)
frame5.grid(row=0)
root.mainloop()
There is only one modification to your code. In the lower section one line is added:
x = 0.0
This is to ensure you have a variable x in global scope. With that variable in global scope you are then able to use (read and write) it within your functions (after you declared it as global with global x)
from tkinter import *
def mainWindow():
label = Label(frame, text = "What do you want to do")
label.pack()
but1 = Button(frame, text = "SI", command = SimpleInterest)
but1.pack()
def SimpleInterest():
global x
frame.destroy()
label5 = Label(frame2,text="Please enter principal amount" )
label5.pack()
p = Entry(frame2 )
p.pack()
label6 = Label(frame3,text="Please ROI")
label6.pack()
r = Entry(frame3, text="Please enter rate of interest")
r.pack()
label7 = Label(frame4, text="Please enter time")
label7.pack()
t = Entry(frame4, text="Please enter time")
t.pack()
buttonmain = Button(frame4, text = "Finlise", command = finalProgram)
buttonmain.pack()
global x
x =(p*r*t)/100
def finalProgram():
frame2.destroy()
frame3.destroy()
frame4.destroy()
global x
newlabel = Label(frame5, text = x)
x = 0.0
root = Tk()
frame = Frame(root)
frame.grid(row=0,columnspan = 2)
mainWindow()
frame2 = Frame(root)
frame2.grid(row = 0, columnspan =2)
frame3 = Frame(root)
frame3.grid(row =1, columnspan =2)
frame4 = Frame(root)
frame4.grid(row=2, columnspan =2)
frame5 = Frame(root)
frame5.grid(row=0)
root.mainloop()
Please note, that this is only a quick fix for the problem you asked. The general structure of you code is not really good and you should consider learning concepts like classes and/or how you pass arguments into functions.
I am writing a time clock program. I have built the code, but have had trouble creating a GUI around it. I have entries that takes input and sends them to an outside function with a button event handling for calculation.
Running the program, I do not get a label updating the time. I wonder if it has to do with my textvariables.
from tkinter import *
import time
import os
def show_entry_fields():
hr= hrvar.get()
mn = minvar.get()
sc = secvar.get()
counter = int(hr)*3600+int(mn)*60+ int(sc)
mins = int(counter/60)
hours = int(mins/60)
hours = IntVar()
mins = IntVar()
secs = IntVar()
while counter > 0:
counter -= 1
hours, sec = divmod(counter, 3600)
mins, sec = divmod(sec, 60)
printv = StringVar()
printv = (" %d Hr:, %d Min: %d Sec" % (hours, mins, sec))
win1 = Tk()
timeLabel = Label(win1, textvariable= printv).grid(row=7)
mins= int(counter/60)
hours = int(mins/60)
time.sleep(1)
os.system('cls')
return
else:
finishedLabel = Label(master, text="Time is Up").grid(row=7)
return
master = Tk()
Label(master, text="Enter Hour(s)").grid(row=0)
Label(master, text="Enter Mins(s)").grid(row=1)
Label(master, text="Enter Second(s)").grid(row=2)
hrvar = IntVar()
minvar = IntVar()
secvar = IntVar()
e1 = Entry(master, textvariable = hrvar)
e2 = Entry(master, textvariable = minvar)
e3 = Entry(master, textvariable = secvar)
e1.grid(row=0, column=1)
e2.grid(row=1, column=1)
e3.grid(row=2, column=1)
Button(master, text='Quit', command=master.quit).grid(row=3, column=0,
sticky=W, pady=4)
Button(master, text='Show', command=show_entry_fields).grid(row=3,
column=1,
sticky=W, pady=4)
mainloop( )
Updated code.
class Timer:
def __init__(self, master):
#self.seconds = 0
self.time = StringVar()
self.hr = StringVar()
self.mins = StringVar()
self.secs = StringVar()
self.hr_label = Label(master, text='Enter Hours').pack()
self.entry_hr = Entry(master, textvariable = self.hr )
self.entry_hr.pack()
self.min_label = Label(master, text='Enter Minutes').pack()
self.entry_min = Entry(master, textvariable = self.mins)
self.entry_min.pack()
self.time_label = Label(master, relief='flat', font=("Cambria", 20),
textvariable=self.time)
self.set_time(hours= self.entry_hr.get(), minutes=self.entry_min.get(), seconds = 0)
self.time.set('00:00:00')
self.start_button = Button(master, text='Start')
self.start_button.bind('<Button-1>', self.start_countdown)
self.time_label.pack(padx=30, pady=10)
self.start_button.pack(pady=(10,20))
def set_time(self, hours, minutes, seconds):
self.seconds = hours * 3600 + minutes * 60 + seconds
self.time.set(self.format_time(self.seconds))
def start_countdown(self, event):
self.countdown()
def countdown(self):
if self.seconds <= 0:
return
self.seconds -= 1
self.time.set(self.format_time(self.seconds))
self.time_label.after(1000, self.countdown)
def format_time(self, seconds):
h = seconds // 3600
m = (seconds - h*3600) // 60
s = seconds - h*3600 - m*60
return '{:0>2}:{:0>2}:{:0>2}'.format(h,m,s)
if __name__ == '__main__':
root = Tk()
timer = Timer(root)
#timer.set_time(hours=0, minutes=20, seconds=0)
root.mainloop()
There are several problems with your code. You are redefining printv, timeLabel, and creating a new Tk() object at every step in your while loop. More importantly, you define printv as a StringVar, but immediately redefine it as a string. You should define each of them once outside of the while loop and then use the set() method of printv.
Here is a very basic timer in Tkinter. First of all, you should not be using time.sleep or while loops. The mainloop function is already a while loop, and most tkinter objects have a .after() method that allows you to call events after a window of time (in milliseconds).
Notice that I created a class to encapsulate my entire UI. All variables are stored within the class and updated from its methods. The time is set within the script itself (currently to 1 hour, 20 minutes, 10 seconds), though that is easy to modify to accept args from the command line or from text fields in the UI.
from tkinter import Tk, Label, StringVar
from tkinter.ttk import Button, Entry
class Timer:
def __init__(self, master):
self.seconds = 0
self.time = StringVar()
self.time_label = Label(master, relief='flat', font=("Cambria", 20),
textvariable=self.time)
self.hr = StringVar()
self.hr_label = Label(master, text='Hours:').grid(row=1, column=1, padx=5, pady=1)
self.entry_hr = Entry(master, textvariable=self.hr, width=4)
self.entry_hr.grid(row=1, column=2)
self.mins = StringVar()
self.min_label = Label(master, text='Minutes:').grid(row=2, column=1, padx=5, pady=1)
self.entry_min = Entry(master, textvariable=self.mins, width=4)
self.entry_min.grid(row=2, column=2)
self.secs = StringVar()
self.secs_label = Label(master, text='Seconds:').grid(row=3, column=1, padx=5, pady=1)
self.entry_sec = Entry(master, textvariable=self.secs, width=4)
self.entry_sec.grid(row=3, column=2)
self.time.set('00:00:00')
self.start_button = Button(master, text='Start')
self.start_button.bind('<Button-1>', self.start_countdown)
self.time_label.grid(row=0, columnspan=4, padx=30, pady=10)
self.start_button.grid(row=4, columnspan=4, pady=(10,20))
def set_time(self, hours, minutes, seconds):
self.seconds = hours * 3600 + minutes * 60 + seconds
self.time.set(self.format_time(self.seconds))
def start_countdown(self, event):
h = self.entry_hr.get()
m = self.entry_min.get()
s = self.entry_sec.get()
h,m,s = map(lambda x: int(x) if x else 0, (h,m,s))
self.set_time(h,m,s)
self.countdown()
def countdown(self):
if self.seconds <= 0:
return
self.time.set(self.format_time(self.seconds))
self.seconds -= 1
self.time_label.after(1000, self.countdown)
def format_time(self, seconds):
h = seconds // 3600
m = (seconds - h*3600) // 60
s = seconds - h*3600 - m*60
return '{:0>2}:{:0>2}:{:0>2}'.format(h,m,s)
if __name__ == '__main__':
root = Tk()
timer = Timer(root)
root.mainloop()
i wrote this code and it runs perfectly on my windows pc using PyCharm.
when i run it from my raspberry pi 2 using the default interpreter it acts weird- buttons don't always respond, and alarmList array won't print properly on command.
has anyone had this problem before?
code:
import time
from Tkinter import *
import tkMessageBox
date = [time.strftime('%Y', time.localtime(time.time())), time.strftime('%m', time.localtime(time.time())), time.strftime('%d', time.localtime(time.time())), time.strftime('%H', time.localtime(time.time())), time.strftime('%M', time.localtime(time.time())), time.strftime('%S', time.localtime(time.time()))]
main = Tk()
main.overrideredirect(True)
main.grid_columnconfigure(0, weight=3)
main.grid_rowconfigure(0, weight=3)
main.geometry("{0}x{1}+0+0".format(main.winfo_screenwidth(), main.winfo_screenheight()))
AlarmList = []
def setAlarm():
def submit_alarm():
get_alarm = [int(alarm_hour_entry.get()), int(alarm_minute_entry.get())]
alarm_hour_entry.delete(0, END)
alarm_minute_entry.delete(0, END)
if get_alarm[0] > 0 and get_alarm[0] < 23 and get_alarm[1] >= 0 and get_alarm[1] < 59:
AlarmList.append(get_alarm)
AlarmList.sort()
else:
tkMessageBox.showinfo("Invalid Time", "please enter a valid time, you fucking douchebag")
print AlarmList
alarm_set = Tk()
# alarm_set.configure(bg='white')
alarm_set.overrideredirect(True)
alarm_set.geometry("{0}x{1}+0+0".format(alarm_set.winfo_screenwidth(), alarm_set.winfo_screenheight()))
alarm_hour_label = Label(alarm_set, text="Alarm Hour:")
alarm_hour_entry = Entry(alarm_set)
alarm_hour_label.grid(row=0, column=0)
alarm_hour_entry.grid(row=0, column=1)
alarm_minute_label = Label(alarm_set, text="Alarm Minute:")
alarm_minute_entry = Entry(alarm_set)
alarm_minute_label.grid(row=1, column=0)
alarm_minute_entry.grid(row=1, column=1)
submit_button = Button(alarm_set, text='submit', command=submit_alarm)
submit_button.grid(row=2, column=1)
quit_alarm = Button(alarm_set, text="back to menu", command=alarm_set.destroy)
quit_alarm.grid(row=2, column=0)
alarm_set.mainloop()
def tick():
global time1
# get the current local time from the PC
time2 = time.strftime('%H:%M:%S')
# if time string has changed, update it
if time2 != time1:
time1 = time2
clock.config(text=time2)
# calls itself every 200 milliseconds
# to update the time display as needed
# could use >200 ms, but display gets jerky
clock.after(200, tick)
button1=Button(text='Set Alarm', font=('times', 15, 'bold'), command=setAlarm, bd=0, padx=2, pady=2)
button1.config(height=10, width=50)
button1.grid(row=0, column=0, sticky=W)
quit_main=Button(main, text='quit', font=('times', 15, 'bold'), command=main.destroy, bd=0, padx=30, pady=2)
#quit_main.configure(height=10, width=20)
quit_main.grid(row=3, column=0, sticky=W)
time1 = ''
clock = Label(main, font=('times', 100, 'bold'), bg='blue', fg='white')
clock.grid(row=1, columnspan=2, sticky=N)
settings_photo=PhotoImage(file="settings.gif")
settings=Button(image=settings_photo,bd=0)
settings.grid(row=3, column=1)
tick()
main.mainloop()
Any ideas why the leftresult_label label does not update? The function seems to work but the label does not update. I have looked everywhere and can't find an answer. The 'left' value gets set but the label does not change.
from tkinter import *
root = Tk(className="Page Calculator")
read = IntVar()
total = IntVar()
left = IntVar()
read.set(1)
total.set(1)
left.set(1)
read_label = Label(root,text="Pages Read:")
read_label.grid(column=1, row=1)
total_label = Label(root,text="Total Pages:")
total_label.grid(column=1, row=2)
read_entry = Entry(root,textvariable=read)
read_entry.grid(column=2, row=1)
total_entry = Entry(root,textvariable=total)
total_entry.grid(column=2, row=2)
def func1():
left.set(total.get() - read.get())
print(left.get())
calculate_button = Button(root,text="Calculate",command= func1)
calculate_button.grid(column=2, row=3)
percenet_label = Label(root,text="Percent Finished:")
percenet_label.grid(column=1, row=4)
left_label = Label(root,text="Pages Left:")
left_label.grid(column=1, row=5)
percenetresult_label = Label(root,text=left.get())
percenetresult_label.grid(column=2, row=4)
leftresult_label = Label(root,text="")
leftresult_label.grid(column=2, row=5)
root.mainloop()
To make the function do the job, you'd rather have your label:
leftresult_label = Label(root, textvariable=left)
Once it's tkinter class variable, tkinter takes care about when you change the value. Once you click the button,
def func1():
left.set(total.get() - read.get())
percent.set(int(read.get()*100/total.get()))
left and percent values, which are instances of tkinter.IntVar() class have immidiate effect on widgets (labels in this case) where those values are set as textvariable, just as you have it at Entry widgets.
Here is full code:
from tkinter import *
root = Tk(className="Page Calculator")
read = IntVar()
total = IntVar()
left = IntVar()
percent = IntVar()
read.set(1)
total.set(1)
left.set(1)
percent.set(1)
def func1():
left.set(total.get() - read.get())
percent.set(int(read.get()*100/total.get()))
read_label = Label(root,text="Pages Read:")
read_label.grid(column=1, row=1)
read_entry = Entry(root,textvariable=read)
read_entry.grid(column=2, row=1)
total_label = Label(root,text="Total Pages:")
total_label.grid(column=1, row=2)
total_entry = Entry(root,textvariable=total)
total_entry.grid(column=2, row=2)
calculate_button = Button(root,text="Calculate",command= func1)
calculate_button.grid(column=2, row=3)
percenet_label = Label(root,text="Percent Finished:")
percenet_label.grid(column=1, row=4)
left_label = Label(root,text="Pages Left:")
left_label.grid(column=1, row=5)
percenetresult_label = Label(root,textvariable=percent)
percenetresult_label.grid(column=2, row=4)
leftresult_label = Label(root,textvariable=left)
leftresult_label.grid(column=2, row=5)
root.mainloop()
code including progress bar. update_idletasks() used to keep label and progress bar running.
from tkinter import *
from tkinter import ttk
root = Tk()
root.title('Counter Test')
root.iconbitmap('IT.ico')
root.geometry("800x400")
def missing():
while i < 100:
progress1['value'] = i
label1.config(text=progress1['value'])
root.update_idletasks()
i += 1
progress1 = ttk.Progressbar(root, orient=HORIZONTAL, length=250, mode='determinate')
progress1.pack(pady=15)
label1 = Label(root, text="")
label1.pack(pady=15)
button_1 = Button(root, text="Missing", command=missing)
button_1.pack(pady=15)
button_q = Button(root, text="Quit", command=root.destroy)
button_q.pack(pady=15)
root.mainloop()
so to update controls immediately, like updating labels and TreeView elements this code worked for me.
window = tk.Tk()
window.update_idletasks()
I am trying to make a timer on python Tkinter. To set the timer, I am using spinboxes. But, I am having trouble getting the value of my spinboxes to be turned into the variables time_h, time_m and time_s.
I have tried .get() but it is not working. When I tried printing the variables I got NameError: name 'spin_h' is not defined.
from tkinter import *
window = Tk()
window.title("Timer")
window.geometry('350x200')
hour = 0
minute = 0
second = 0
timer = (str(hour) + ':' + str(minute) + ':' + str(second))
lbl = Label(window, text=timer, font=("Arial Bold", 50))
hour_s = 0
min_s = 0
sec_s = 0
def save_time():
time_h = spin_h.get()
time_m = spin_m.get()
time_s = spin_s.get()
def new_window():
set_time = Tk()
spin_h = Spinbox(set_time, from_=0, to=10, width=5)
spin_h.grid(column=1,row=0)
spin_m = Spinbox(set_time, from_=0, to=60, width=5)
spin_m.grid(column=3,row=0)
spin_s = Spinbox(set_time, from_=0, to=60, width=5)
spin_s.grid(column=5,row=0)
h_label = Label(set_time, text='h', font=("Arial Bold", 10))
h_label.grid(column=2, row=0)
m_label = Label(set_time, text='m', font=("Arial Bold", 10))
m_label.grid(column=4, row=0)
s_label = Label(set_time, text='s', font=("Arial Bold", 10))
s_label.grid(column=6, row=0)
set_button = Button(set_time, text="Set Time", command=save_time)
set_button.grid(column=3, row=2)
btn = Button(window, text="Set Time", command=new_window)
btn.grid(column=3, row=2)
lbl.grid(column=3, row=0)
window.mainloop()
spin_h is a variable local to the new_window() function and there cannot be accessed by the save_time() function. You could declare it a global variable at the beginning of new_window() to fix that. - #Martineau (just made it into an answer instead of a comment).
Thanks Martineau