I have a programm in Python with a simple GUI that simulates a queue management system. When i press the Button "Next Customer" it displays the next queue number. Now i want to count the time intervals between the 2 clicks (on the button "Next Customer") so to track the service time needed. How is this possible? The code is the following.
import time
import random
from Tkinter import *
def PrintNumber():
global j, label
j+=1
label.config(text=str(j))
print j
t = (time.strftime("%H:%M:%S"))
d = time.strftime("%d/%m/%Y")
return
j=0
mgui=Tk()
mgui.geometry('200x200')
mgui.title('Queue System')
st = Button(mgui, text="Next Customer", command = PrintNumber)
st.pack()
label = Label(mgui, text=str(j))
label.pack()
mgui.mainloop()
This is my lazy solution:
import time
import random
from Tkinter import *
class GetClicktime():
def __init__(self):
self.j=0
self.t=[]
self.mgui=Tk()
self.mgui.geometry('200x200')
self.mgui.title('Queue System')
self.st = Button(self.mgui, text="Next Customer", command = self.PrintNumber)
self.st.pack()
#self.st.bind('<Button-1>',callback)
self.label = Label(self.mgui, text=str(self.j))
self.label.pack()
self.mgui.mainloop()
def PrintNumber(self):
self.j+=1
self.label.config(text=str(self.j))
print self.j
t = (time.strftime("%H:%M:%S"))
d = time.strftime("%d/%m/%Y")
self.t.append(int(t.replace(':','')))
print self.t
if self.j >2:
print 'the time between clicks is:',self.t[self.j-1]-self.t[self.j-2],'seconds'
print t,d
return
if __name__ == "__main__":
GetClicktime()
you can avoid writing a class, but this does what you need to.
If you need some docs on classes i recommmend: https://www.youtube.com/watch?v=trOZBgZ8F_c#start=0:00;end=13:27;cycles=-1;autoreplay=false;showoptions=false
you could begin the timer after the first button pressed and end it after the second pressed. You could add a condition to determining weather it is the first press.
if start:
elapsed = (time.clock() - start)
print (elapsed)
start = time.clock()
Related
In this UI there is 2 buttons and 1 entry box. Buttons named "Start Loop" and "Print".
When i write a text into the entry box, i should able to see it's print out when pressed the related button. What i am trying to do is, put that button press in a while loop. But the interesting part is trying to print a new entry in every 10 seconds.
When you entered a entry and press the "Start Loop" button, it becomes run. Meanwhile user interface window will froze. Can't write a new entry or press "Print" button. Even i use time.sleep function it still frozen. It prints old entry, but i want to write a new entry at every iteration. Check out the code:
import time
from tkinter import *
class tkin(Frame):
def __init__(self,parent):
Frame.__init__(self, parent)
self.parent = parent
self.UI()
def UI(self):
self.down = StringVar()
self.down_entry = Entry(self, textvariable=self.down)
self.down_entry.grid(row=2, column=0)
self.start_loop_buuton = Button(text="Start Loop", command=self.loop_func)
self.start_loop_buuton.place(x=10,y=40)
self.print_func_button = Button(text="Print ", command=self.pprint)
self.print_func_button.place(x=120,y=40)
self.pack()
def loop_func(self):
start = time.time()
while True:
print("standart print out")
end = time.time()
if (end- start) >10:
time.sleep(10)
self.print_func_button.invoke() ## press print_func_button
start = time.time()
def pprint(self):
print("WHICH PRINT LINE I WANT TO PRINT IN LIKE EVERY 10 SECONDS")
print(self.down.get())
def main():
root = Tk()
tkin(root)
root.geometry("195x100+300+300")
root.mainloop()
main()
Any advice would be nice. Thanks in advance.
this is how I would redefine Your method:
def loop_func(self):
self.print_func_button.invoke() # press print_func_button
self.after(3000, self.loop_func)
time is in miliseconds so this will be 3 seconds
In this example, i just separated the looping "loop_func()" using thread in Button function's argument of command. Like that:
import threading
...
...
...
self.start_loop_buuton = Button(text="Start Loop", command=threading.Thread(target=self.loop_func).start())
So, these two loops have been separated.
I'm new to python and I am trying to create a program but I can't even get the basics right. I have a button app that looks like this:
#simple GUI
from tkinter import *
import time
#create the window
root = Tk()
#modify root window
root.title("Button Example")
root.geometry("200x50")
button1state = 0
def start():
count = 0
button1["text"] ="Busy!"
while (count < 5):
root.after(1000)
count = count + 1
def button1clicked():
global button1state
if button1state == 0:
start()
button1["text"] ="On!"
button1state = 1
else:
button1["text"] ="Off!"
button1state = 0
app = Frame(root)
app.pack()
button1 = Button(app, text ="Off!", command = button1clicked)
button1.pack()
#kick off the event loop
root.mainloop()
Now everything works except it doesn't change the button text to busy while
**start()** is called. How can I fix this? Once I've got it working I want to use images to show the user that its OFF ON and BUSY. Please help me
You need to force the GUI to update before starting the task:
def start():
count = 0
button1.configure(text="Busy!")
root.update() # <-- update window
while (count < 5):
root.after(1000)
count = count + 1
But if you don't want your GUI to be frozen while the task is executed, you will need to use a thread as Dedi suggested.
You have to make a thread in order to make you function as a "background event" while your interface is working. Consider using that :
from threading import Thread
and then :
my_thread=Thread(target=start())
my_thread.start()
Where the first "start()" is the name of your function and the second one a call for the thread to begin.
Below, I have created a code to track the laps a person who is running. At the moment, the button I had created tracks the laps and the time, but not on the GUI window. I was wondering how to make the data on the from the code show on the GUI window.
from Tkinter import *
import time
laps=[0]
gui=Tk()
gui.geometry("200x100")
gui.title("lapping")
def afterbutton():
label_1=Label(gui,text=end())
def end():
end = time.time()
elapsed = end - start
laps[0]+=1
print "%s seconds" % (elapsed)
print "%s lap(s)" % (laps)
starting = raw_input("start? (s to start)")
if starting == "s":
start = time.time()
button1=Button(gui,command=afterbutton,text="lap")
button1.grid()
button1.pack()
gui.mainloop()
You need to create the label at the same time you create the button. You need to put it in the grid and pack it, just like you did with the button. Then when the button is clicked, all you have to do is change the label's text. This is what it looks like:
# python 3
from Tkinter import *
import time
laps=[0]
gui=Tk()
gui.geometry("200x100")
gui.title("lapping")
def end():
end = time.time()
elapsed = end - start
laps[0] += 1
s = "%s seconds %s laps" % (elapsed,laps)
label1['text'] = s
print("%s seconds" % (elapsed))
print("%s lap(s)" % (laps))
starting = raw_input("start? (s to start)")
if starting == "s":
start = time.time()
button1 = Button(gui, command=end, text="lap")
button1.grid()
button1.pack()
label1 = Label(gui)
label1.grid()
label1.pack()
gui.mainloop()
The function afterbutton is gone; all the work is done by end(). I kept most of your program, but I'm using py3 so print is a function rather than a statement. You'll have to fix that for py2. The text of the label is set by:
label1['text'] = s
which is a somewhat weird syntax when you first see it.
BTW, I don't see why you used a 1-element list for laps instead of a simple variable.
I doing a simple python GUI using tkinter to do screen recording.Basically, I am using ffmpeg commands at the backend with tkinter as the front end triggering the ffmpeg commands.There is something that I stuck with.I dont know why my time is unable to trigger off if I program in this way.
The code below is basically the recording method.You will notice that I am actually trying to update my tkinter GUI in the while loop.This method is actually in my class named Gui_Rec() which contains other methods I need for my screen recording program.
def rec(self):
global videoFile
mydate = datetime.datetime.now()
videoFile = mydate.strftime("\%d%b_%Hh%Mm.avi")
self.l['text']=os.path.expanduser('~')+"\Videos"
self.l1['text']=videoFile
self.b.config(state=DISABLED)
self.b1.config(state=ACTIVE)
t = Thread(target=self.rec_thread)#trigger another method using thread which will run ffmpeg commands here
t.start()
while True:
if self.count_flag == False:
break
self.label['text'] = str("%02dm:%02ds" % (self.mins,self.secs))
if self.secs == 0:
time.sleep(0)
else:
time.sleep(1)
if(self.mins==0 and self.secs==1):
self.b1.config(fg="white")
self.b1.config(bg="red")
self.b.config(fg="white")
self.b.config(bg="white")
if self.secs==60:
self.secs=0
self.mins+=1
self.label['text'] = str("%02dm:%02ds" % (self.mins,self.secs))
main.gui.update()
self.secs = self.secs+1
other method in the class Gui_Rec() then this below
def main():
gui = Gui_Rec()
gui.minsize(300,155)
gui.maxsize(390,195)
gui.title("Desktop REC")
gui.attributes("-topmost", 1)
gui.mainloop() #start mainloop of program
if __name__ == '__main__':
main()
Strangely, if I don't put the above section of code in the the def main(), the GUI will be update with the duration of the time running when rec button is pressed.I don't really know how to go about solving this.Tried putting it in another thread yet it doesn't work as well.Thank you everyone for your help.
The while loop is creating a conflict with Tkinter's mainloop. Threading or multiprocessing are solutions, but I'd recommend looking into Tkinter's after() method. Here's a simplified example of how to handle a timer using after:
from Tkinter import *
class App(Frame):
def __init__(self, parent):
Frame.__init__(self, parent)
self.mins = 0
self.secs = 0
# make a stringvar instance to hold the time
self.timer = StringVar()
self.timer.set('%d:%d' % (self.mins, self.secs))
Label(self, textvariable=self.timer).pack()
Button(self, text='Start', command=self._start_timer).pack()
Button(self, text='Stop', command=self._stop_timer).pack()
def _start_timer(self):
self.secs += 1 # increment seconds
if self.secs == 60: # at every minute,
self.secs = 0 # reset seconds
self.mins += 1 # and increment minutes
self.timer.set('%d:%d' % (self.mins, self.secs))
# set up the after method to repeat this method
# every 1000 ms (1 second)
self.repeater = self.after(1000, self._start_timer)
def _stop_timer(self):
self.after_cancel(self.repeater)
root = Tk()
App(root).pack()
mainloop()
I am new to python and i am trying to make a countdown timer on a button click. But i would like this countdown timer to start its countdown and place the current countdown value in the text area. Also i need the rest of the application to not sleep while this countdown is running. So far it will output the countdown in the console but will freeze the rest of the application. Can someone point me in the right direction?
from Tkinter import *
import time
import threading
import thread
class App:
def __init__(self, master):
frame = Frame(master)
frame.pack()
self.getvalue = Button(frame, text="Get the Text Area", command=self.thevalue)
self.getvalue.pack(side=LEFT)
self.text_area = Entry()
self.text_area.pack(side=RIGHT)
def thevalue(self):
print "In the value"
try:
t = threading.Thread(target=self.print_time("I am in print_time"))
t.daemon = True
t.start()
except:
print "Error: unable to start thread"
def print_time(self,bleh):
print bleh
print "The text area value is %s" % self.text_area.get()
boom=5
while boom >0:
time.sleep(1)
self.text_area.delete(0, END)
self.text_area.insert(0, boom)
print(boom)
boom -=1
root = Tk()
app = App(root)
root.mainloop()
threading.Thread(target=self.print_time("I am in print_time"))
This will not do what you want it to do. What happens here is that the function self.print_time is called and its return value is then passed to the constructor of threading.Thread.
You need to create the thread like this:
t = threading.Thread(target=self.print_time, args=("I am in print_time",))