How to make a button print out certain text? - Tkinter - python

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.

Related

Executing a command before window.destroy() in tkinter

I am learning to build basic GUIs with Tkinter in order to use it in a project.
I would like to have a button that runs a certain task, then prints "Task done", then waits 1 second, and then closes the window.
Here's what I tried to do :
from tkinter import *
from time import *
def PrintAndClose():
label.configure(text="Task done")
t1 = time()
t2 = time()
while t2-t1 < 1:
t2 = time()
window.destroy()
window = Tk()
window.title("Task doer")
window.geometry('400x400')
label = Label(window, text="Task to be done")
label.pack()
bouton = Button(window , text = "Do the task", command=PrintAndClose)
bouton.pack()
window.mainloop()
When I run the GUI and click the button, it waits 1 second and then closes the window, but it does not change the label.
Is there anything wrong in what I'm doing ? I guess it's more complicated than that.
Thanks for your help !
It turns out using the after method as Matiss suggested fixed it.

How to make a speedrun timer stay to the front

I made an in game timer for Minecraft to use while speedrunning and it works great but the one problem is that when I make Minecraft fill my whole screen NOT FULLSCREEN just cover it the timer disappears.
I knew this would happen and I am wondering if this is possible to fix and make the pygame window go to the front even if it is blocked by an app that you are currently using.
You can do this with Tkinter:
This way, you can make a timer:
Always put to front
Transparent
Furthermore, tkinter is in the Standard library.
You can use this code:
from tkinter import *
from threading import Thread
from time import time
tk = Tk()
tk.title('Timer')
tk.wm_attributes('-topmost', 1) # put the window to front
pause = True
start = time()
time_when_paused = time() # time displayed when in pause
def restart(): # restart to 0
global pause, start
pause = False
start = time()
def toggle_pause():
global pause, start, time_when_paused
pause = not pause
if pause:
time_when_paused = time() # update the time displayed
else:
start += time() - time_when_paused # forget the time passed in pause
def timer():
while True:
if pause:
label['text'] = '%.2f' %(time_when_paused - start) # %.2f for 2 decimals
label['fg'] = 'orange'
else:
label['text'] = '%.2f' %(time() - start)
label['fg'] = 'green'
label = Label(tk, '', font=('Helvetica', 30), fg='orange')
label.grid(columnspan=2) # display the timer
# buttons
restart_button = Button(tk, text='Restart', width=20, command=restart)
restart_button.grid(padx=5, pady=5)
pause_button = Button(tk, text='Pause', width=20, command=toggle_pause)
pause_button.grid(padx=(0, 5), column=1, row=1)
timer_thread = Thread(target=timer)
timer_thread.start() # put in a thread because of...
tk.mainloop() # ...this which acts like "while window is not closed"

Sleep while loop without break it, for write new entry in tkinter

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 am making a CPS counter but am having trouble with the timer?

I am very new to tkinker in python (Really new) and am having some trouble making and displaying a timer for a CPS calculator (Like this one: http://www.mcrpg.com/kohi-click-test).
I have tried a couple of solutions but none have seemed to work.
Example one:
while True:
if seconds > -10:
time.sleep(1)
seconds += 1
secs.configure(text=seconds)
In this example it makes the window.mainloop() unreachable.
When it doesn't have the while True: and window.mainloop() is reachable it only updates 'seconds' once. (0 --> 1)
It says not to include my entire code, hopefully I have only included the necessary code.
Timer code:
# Seconds
secs = Label(window, text=0, fg='white', bg='blue')
secs.grid(column=6, row=6)
if seconds > -10:
time.sleep(1)
seconds += 1
secs.configure(text=seconds)
window.mainloop()
My variables:
from tkinter import *
# noinspection PyUnresolvedReferences
import time
window = Tk()
clicks = 0
window.title("CPS TEST")
window.geometry('500x500')
lbl = Label(window, text='CPS TEST', bg='orange')
lbl.grid(column=0, row=0)
clicks1 = 0
seconds = 0
I expect the secs in the window to be updated every second, adding one to the variable, making the number go up. Is there anyway I can fix it?
Tkinter is an event-driven system, like most GUI toolkits. For it to function properly, your code is basically a guest in the mainloop() and must be called from it.
So your code must live in callbacks. You could say that there are two kinds of callbacks;
callbacks attached to widgets (e.g. for when a button is pressed)
callbacks invoked by a timer (using Tk.after)
Using the firstkind of callback, you can record the datetime.datetime every time the callback is invoked. Append that datetime to a global list.
Using the second kind of callback (e.g called every second), you could calculate the difference between subsequent items in the list of datetime. That will give you timedelta objects. Then set the list to a empty list. Average the timedeltas and invert it if the average is not 0. That gives you CPS. Use that to update the display.
Building on Roland Smith's answer, to continue the root.after() multiple times you can make it recursive. So it would look something like this
from tkinter import *
root = Tk()
label = Label(root, text='Time: ')
label.pack()
time = Label(root, text=0)
time.pack()
def update_time():
time.configure(text=time.cget('text') + 1)
root.after(1000, update_time)
root.after(1000, update_time)
root.mainloop()
Well, the question is old and my code does not use tkinter, but I just wanted to share it anyway
from pynput.mouse import Listener
from time import sleep, time
from threading import Thread
import os.path
from pyfiglet import Figlet
f = Figlet ( font = "roman" )
print ( "\x1b[?25l" )
clicks = [ ]
def reduce ( ) :
while True :
removed = [ i for i in clicks if time ( ) - i > 1 ]
for i in removed : clicks.remove ( i )
#print ( "\x1b[1;1H\x1b[J" )
print ( f.renderText ( str ( len ( clicks ))))
if os.path.isfile ( "stop" ) :
print ( "\x1b[?25h" )
return
def on_click ( x, y, button, pressed ):
if pressed and str ( button ) == "Button.left" :
global clicks
clicks += [ time ( )]
x = Thread ( target = reduce )
x.start ( )
with Listener ( on_click = on_click ) as listener:
listener.join ( )
It also creates a neat console window with a big number telling you the CPS

Count time intervals (secs) between 2 button clicks

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

Categories

Resources