So, I have been trying to create a simple stopwatch in tkinter in which I created a loop to update text to new time i.e., the next second in timer label as I click button_1. I tried to do this with StringVar() as well as .config method but none of them are updating the text in label. The code is below
from datetime import *
from time import *
init_time = datetime(100, 1, 1, 0, 0, 0)
running = True
def clock():
while running == True:
sleep(1)
global init_time
a = init_time.strftime("%H:%M:%S")
mtime.set(a)
init_time = init_time + timedelta(seconds=1)
def stop():
global running
running = False
main = Tk()
main.geometry("500x200")
mtime = StringVar()
timer = Label(main, textvariable = mtime, width=30, bg="black", fg="white", font=(25))
timer.place(x=90, y=20)
button_1 = Button(main, text = "Start", command = clock()).place(x=170, y=120)
button = Button(main, text = "Stop", command = stop).place(x=250, y=120)
main.mainloop()
I even tried to convert the init_time to a string because I thought maybe the updates of text work only for strings. The initial GUI window shows but as I click button_1 it doesn't work.
You did common mistake, look at these two lines
button_1 = Button(main, text = "Start", command = clock()).place(x=170, y=120)
button = Button(main, text = "Stop", command = stop).place(x=250, y=120)
Note that you have clock() and stop. First is function invocation, second is function. You should provide function as command. Replace clock() using clock.
Also if you are interested in executing function every n miliseconds, please take look at .after, consider following simple timer
import tkinter as tk
elapsed = 0
def update_timer():
global elapsed
elapsed += 1
timer['text'] = str(elapsed)
root.after(1000, update_timer) # 1000 ms = 1 second
root = tk.Tk()
timer = tk.Label(root, text="0")
btn = tk.Button(root, text="Go", command=update_timer)
timer.pack()
btn.pack()
root.mainloop()
Related
I try make own autoclicker with GUI but I don't know how make CPS(Clicks per second).
I have tried in different ways but nothing work. Please for help with solution on this problem.
from tkinter import *
import time
running = False
cps_counter = 0
def scanning():
global cps_counter
cps_chk = cpscheck.get()
delay = 1/int(cps_chk)
if running:
cps_counter += 1
label.configure(text=f'{cps_counter}')
time.sleep(delay)
def start():
global running
if running == False:
running = True
else:
running = False
window = Tk()
window.title("Title")
window.geometry("500x500")
start = Button(window, text="Start/Stop Scan", command=start)
start.grid()
cpscheck = StringVar()
textBox = Entry(bd=0, bg="#545454", highlightthickness=0, textvariable=cpscheck, font=("Helvetica", 20), fg="white", justify='center')
textBox.place( x=250, y=123, width=85.0, height=25)
label = Label(text=cps_counter)
label.place(x=100, y=100)
window.after(100, scanning) # After 1 second, call scanning
window.mainloop()
I have a off delay program in which when I select the input checkbutton, the output is 1. When I deselect the input checkbutton, the output goes back to 0 after a timer (set up in a scale). For that I use the after method. That part works. My problem is that I want to reset the timer if the checkbutton is selected again before the output went to 0; but once the checkbutton is selected the first time, the after method get triggered and it doesn't stop. I'm trying to use after_cancel, but I can't get it to work. Any solution?
from tkinter import *
root = Tk()
t1= IntVar()
out = Label(root, text="0")
remain_time = IntVar()
grab_time = 1000
def start_timer(set_time):
global grab_time
grab_time = int(set_time) * 1000
def play():
if t1.get() == 1:
button1.configure(bg='red')
out.configure(bg="red", text="1")
else:
button1.configure(bg='green')
def result():
out.configure(bg="green", text="0")
out.after(grab_time,result)
button1 = Checkbutton(root,variable=t1, textvariable=t1, command=play)
time = Scale(root, from_=1, to=10, command=start_timer)
button1.pack()
time.pack()
out.pack()
root.mainloop()
Expected: when press the checkbutton before the output went to 0, reset the counter.
So you could use the .after_cencel when the value of checkbutton is 1:
from tkinter import *
root = Tk()
t1= IntVar()
out = Label(root, text="0")
remain_time = IntVar()
grab_time = 1000
def start_timer(set_time):
global grab_time
grab_time = int(set_time) * 1000
def play():
if t1.get() == 1:
button1.configure(bg='red')
out.configure(bg="red", text="1")
try: # when the first time you start the counter, root.counter didn't exist, use a try..except to catch it.
root.after_cancel(root.counter)
except :
pass
else:
button1.configure(bg='green')
def result():
out.configure(bg="green", text="0")
root.counter = out.after(grab_time,result)
button1 = Checkbutton(root,variable=t1, textvariable=t1, command=play)
time = Scale(root, from_=1, to=10, command=start_timer)
button1.pack()
time.pack()
out.pack()
root.mainloop()
I'm trying to show a sequence of numbers on the screen at regular intervals.
I'm new to python so it may be something obvious but I have tried .after and pygame.time.wait, but neither worked.
this is the code:
from tkinter import*
from random import *
import time
my_list = []
def Create_NUM(event):
x = 0
for x in range(level + 2):
button1.destroy()
num = randint(1, 100)
my_list.append(num)
Label(root, text=num,fg="red").pack()
one.pack()
time.sleep(2)
root=Tk()
num = 0
level = 1
bottomFrame = Frame(root)
bottomFrame.pack(side=BOTTOM)
button1 = Button(bottomFrame, text="Click to start game",fg="red")
button1.bind("<Button-1>", Create_NUM)
button1.pack()
root.mainloop()
I assume you want to show new number in place of old number, not below it.
import tkinter as tk
import random
def start():
# hide button
button.pack_forget()
# run `add_number` first time
add_number(level+2)
def add_number(x):
num = random.randint(1, 100)
my_list.append(num)
label['text'] = num
if x > 0:
# repeat after 2000ms (2s)
root.after(2000, add_number, x-1)
else:
# show button again after the end
button.pack()
# --- main ---
my_list = []
level = 1
root = tk.Tk()
label = tk.Label(root)
label.pack()
button = tk.Button(root, text="Click to start game", command=start)
button.pack()
root.mainloop()
Just use this simple command in your function root.update()
The program I just wrote is my playground for finding out how Tkinter works.
My question is how do I display my variable "timelabel" as a Label.
I allready made a label called timerefresher yet it doesnt show up.
I am aware that the DigitalClock class isn't written efficiently. I am new to this ;).
def Clockupdate(time):
timelabel = time
timerefresher = Label(root, textvariable=timelabel)
timerefresher.pack()
#print(timelabel) To test if variable made it this far.
class DigitalClock:
def secondrefesher(self):
newtime = ""
while 1 == 1:
oldtime = datetime.datetime.now()
a = str(oldtime.hour)
b = str(oldtime.minute)
c = str(oldtime.second)
curtime = (a+":"+b+':'+c)
if curtime != newtime:
newtime = curtime
#print("made it here")
Clockupdate(newtime)
else:
time.sleep(0.20)
DC = DigitalClock()
root = Tk()
mainlabel = Label(root, text="Hey this is working!")
Pressme = Button(root, text="Press me!", command=Presstoshowtextandpic,
bg='red', fg='white')
Clock = Button(root, text="Clock?", command=DC.secondrefesher, bg='blue',
fg='white')
Photo = PhotoImage(file="test.png")
ShowPhoto = Label(root, image=Photo)
mainlabel.pack()
Pressme.pack()
Clock.pack()
root.mainloop()
Ok so Here is what I would do with your code to accomplish what you are trying to do.
First lets make sure we have the correct imports.
from tkinter import *
import datetime
import time
I created this doNothing() function as a place holder for any commands I am not currently testing.
def doNothing():
pass
Now the way you had your Clockupdate(time): function would cause the label to be added every time you click the clock button. so this is probably not what you want as it just keeps adding new labels instead of replacing the existing one. Take a look at this function. All I do in this is .config() the text to be the time argument from the function. Note you do not need to redefine the time to timelabel or anything of the sort, just use time as your varable.
def Clockupdate(time):
timerefresher.config(text = time)
I don't know if you wanted to use a class for a specific reason but I think you should just use a function here. Also try to keep your quotes consistent. I know they are interchangeable but its good practice to keep them consistent.
def secondrefesher():
newtime = ""
oldtime = datetime.datetime.now()
a = str(oldtime.hour)
b = str(oldtime.minute)
c = str(oldtime.second)
curtime = (a + ":" + b + ":" + c)
if curtime != newtime:
newtime = curtime
Clockupdate(newtime)
Note I always place commands at the end of any config of a button. It helps when managing code so you can just check the end of each line as you scroll through your code. I also changed the command for Pressme to doNothing so I could test the code. You didn't provide the code for Presstoshowtextandpic and would not be able to test the code with out that part. Remember when asking a question here to use MCVE.
root = Tk()
mainlabel = Label(root, text="Hey this is working!")
Pressme = Button(root, text = "Press me!", bg = "red", fg = "white", command = doNothing)
Clock = Button(root, text = "Clock?", bg = "blue", fg = "white", command = secondrefesher)
Photo = PhotoImage(file = "test.png")
ShowPhoto = Label(root, image = Photo)
Here I created the time label just once and then you can call the update function all you want to change the text to current time.
timerefresher = Label(root, text = "")
timerefresher.pack()
mainlabel.pack()
Pressme.pack()
Clock.pack()
root.mainloop()
Here is what I think the completed code should look like for you.
from tkinter import *
import datetime
import time
def Clockupdate(time):
timerefresher.config(text = time)
def secondrefesher():
newtime = ""
oldtime = datetime.datetime.now()
a = str(oldtime.hour)
b = str(oldtime.minute)
c = str(oldtime.second)
curtime = (a + ":" + b + ":" + c)
if curtime != newtime:
newtime = curtime
Clockupdate(newtime)
root = Tk()
mainlabel = Label(root, text = "Hey this is working!")
Pressme = Button(root, text = "Press me!", bg = "red", fg = "white", command = Presstoshowtextandpic)
Clock = Button(root, text = "Clock?", bg = "blue", fg = "white", command = secondrefesher)
Photo = PhotoImage(file = "test.png")
ShowPhoto = Label(root, image = Photo)
timerefresher = Label(root, text = "")
timerefresher.pack()
mainlabel.pack()
Pressme.pack()
Clock.pack()
root.mainloop()
Edit:
In case you are trying to create a clock that is always active and does not require you to click the button you can use .after().
Take a look at this example.
from tkinter import *
import datetime
import time
root = Tk()
mainlabel = Label(root, text = "Hey this is working!")
Photo = PhotoImage(file = "test.png")
timerefresher = Label(root, text = "")
timerefresher.pack()
status_time = ""
def tick():
global status_time
time2 = time.strftime("%H:%M:%S")
if time2 != status_time:
status_time = time2
timerefresher.config(text = time2)
timerefresher.after(200, tick)
tick()
mainlabel.pack()
root.mainloop()
You should have written an MCVE so that one can test your code, especially that things are missing (such as Presstoshowtextandpic()).
When reading the rest of your code, I think you need to read about variable classes and modify Clockupdate() as follows:
def Clockupdate(time):
timelabel = StringVar() # modified
timelabel.set(time) # added
timerefresher = Label(root, textvariable=timelabel.get()) #modified
timerefresher.pack()
P.S. You should write clock_update() instead of Clockupdate()
I would like to ask how would I go about maybe creating a 'LIVE' text box in python? This program is a simulator for a vending machine (code below). I want there to be a text box showing a live credit update How do you do that in tkinter?
For Example: Say there is a box for credit with 0 inside it in the middle of the window. When the 10p button is pressed the box for credit should change from '0' to '0.10'.
Is it possible to do thit in tkinter and python 3.3.2?
Thank you in advance!
import sys
import tkinter as tk
credit = 0
choice = 0
credit1 = 0
coins = 0
prices = [200,150,160,50,90]
item = 0
i = 0
temp=0
n=0
choice1 = 0
choice2 = 0
credit1 = 0
coins = 0
prices = [200,150,160,50,90]
item = 0
i = 0
temp=0
n=0
choice1 = 0
choice2 = 0
def addTENp():
global credit
credit+=0.10
def addTWENTYp():
global credit
credit+=0.20
def addFIFTYp():
global credit
credit+=0.50
def addPOUND():
global credit
credit+=1.00
def insert():
insert = Tk()
insert.geometry("480x360")
iLabel = Label(insert, text="Enter coins.[Press Buttons]").grid(row=1, column=1)
tenbutton = Button(insert, text="10p", command = addTENp).grid(row=2, column=1)
twentybutton = Button(insert, text="20p", command = addTWENTYp).grid(row=3, column=1)
fiftybutton = Button(insert, text="50p", command = addFIFTYp).grid(row=4, column=1)
poundbutton = Button(insert, text="£1", command = addPOUND).grid(row=5, column=1)
insert()
Sure you can! Just add another label to the frame, and update the text attribute whenever one of your add functions is called. Also, you can simplify that code, using one add function for all the different amounts.
def main():
frame = Tk()
frame.geometry("480x360")
Label(frame, text="Enter coins.[Press Buttons]").grid(row=1, column=1)
display = Label(frame, text="") # we need this Label as a variable!
display.grid(row=2, column=1)
def add(amount):
global credit
credit += amount
display.configure(text="%.2f" % credit)
Button(frame, text="10p", command=lambda: add(.1)).grid(row=3, column=1)
Button(frame, text="20p", command=lambda: add(.2)).grid(row=4, column=1)
Button(frame, text="50p", command=lambda: add(.5)).grid(row=5, column=1)
Button(frame, text="P1", command=lambda: add(1.)).grid(row=6, column=1)
frame.mainloop()
main()
Some more points:
note that you define many of your variables twice
you should not give a variable the same name as a function, as this will shadow the function
probably just a copy paste error, but you forgot to call mainloop and your tkinter import is inconsistent with the way you use the classes (without tk prefix)
you can do the layout right after creating the GUI elements, but note that in this case not the GUI element will be bound to the variable, but the result of the layouting function, which is None
Borrowing a framework from tobias_k's excellent answer, I would recommend you use a DoubleVar instead.
from tkinter import ttk
import tkinter as tk
def main():
frame = Tk()
frame.geometry("480x360")
credit = tk.DoubleVar(frame, value=0)
# credit = tk.StringVar(frame, value="0")
ttk.Label(frame, textvariable = credit).pack()
def add_credit(amt):
global credit
credit.set(credit.get() + amt)
# new_credit = str(int(credit.get().replace(".",""))+amt)
# credit.set(new_credit[:-2]+"."+new_credit[-2:])
ttk.Button(frame, text="10p", command = lambda: add_credit(0.1)).pack()
# ttk.Button(frame, text="10p", command = lambda: add_credit(10)).pack()
ttk.Button(frame, text="20p", command = lambda: add_credit(0.2)).pack()
# ttk.Button(frame, text="20p", command = lambda: add_credit(20)).pack()
ttk.Button(frame, text="50p", command = lambda: add_credit(0.5)).pack()
# ttk.Button(frame, text="50p", command = lambda: add_credit(50)).pack()
ttk.Button(frame, text="P1", command = lambda: add_credit(1.0)).pack()
# ttk.Button(frame, text="P1", command = lambda: add_credit(100)).pack()
frame.mainloop()
The comments in that code is an alternate implementation that will work better, if only just. This will guarantee you won't have any strange floating-point errors in your code.