import tkinter as tk
from tkinter import *
import keyboard
import time
a = 120
root = tk.Tk()
root.state('zoomed')
root.configure(bg='white')
root.resizable(False, False)
a = 30
x = 0
def increase():
global a
a += 10
def ar():
for i in range(50):
labele1.place(x=120, y=a)
root.after(1000, increase)
c1 = Canvas(root, width=700, height=700, bg='gray95')
c1.place(x=450, y=60)
labele1 = tk.Label(c1, text='_______', font='Calibri 20')
startbutton = tk.Button(text='Başla', command=ar)
startbutton.pack()
root.mainloop()
I want to create a moving label which moves per second. Everything looks clear but it doesn't work well. I want to make a car race app but first the walls should move back and it exit the project
The idea to use root.after is correct, but the implementation is wrong. Just because you update the value of a inside a function, tkinter will not automatically update that value with its widget unless you manually ask it to. So what you can do is:
Make the label a canvas object (recommended since you will be making a game and canvas is closer to give you tools you need):
def ar():
global a
a += 10 # Increase the value of a
c1.coords('wall', [120, a]) # Change the coord of the tag 'wall'
root.after(25, ar) # Repeat this function every 25 ms
....
labele1 = tk.Label(c1, text='_______', font='Calibri 20')
c1.create_window(120, a, window=labele1, tags='wall') # Initial coords -> x=120, y=30
Change the location of the label using place_configure:
def ar():
global a
a += 10 # Increase the value of a
labele1.place_configure(y=a)
root.after(25, ar) # Repeat this function every 25 ms
....
labele1 = tk.Label(c1, text='_______', font='Calibri 20')
labele1.place(x=120, y=a)
Plus checking frame size and decreasing functions.
the main problem was a minor bug which you should change in line 37.
import tkinter as tk
from tkinter import *
import keyboard
import time
a = 120
root = tk.Tk()
root.state('zoomed')
root.configure(bg='white')
root.resizable(False, False)
a = 30
x = 0
moving_rate = 10
max_y = 600
min_y = 30
flag_mov_func= 1
def moving_func(): #increase or decrease function
global a
global flag_mov_func
if flag_mov_func :
a += moving_rate
if a + moving_rate == max_y: #simple logic bouncing if it ends
flag_mov_func=0
elif flag_mov_func==0 :
a -= moving_rate
if a - moving_rate == min_y:
flag_mov_func=1
def ar():
moving_func()
labele1.place(x=120, y=a)
root.after(1000, ar)
flag_is_called=1
def button1(): #new update on code to make the button work once.
global flag_is_called
if flag_is_called:
flag_is_called=0
ar()
c1 = Canvas(root, width=700, height=700, bg='gray95')
c1.place(x=450, y=60)
labele1 = tk.Label(c1, text='_______', font='Calibri 20')
startbutton = tk.Button(text='Başla', command=button1)
startbutton.pack()
root.mainloop()
Related
I am trying to add a progress bar to my window until some work is being done. But it is not working properly. I want it to keep moving until the work is done but it just moves rapidly and then stops. Also if I try to minimize or close the progress window it just hangs and stops responding.
Can anyone help me how can I do it properly? Here is my code.
import time
from tkinter import ttk
from tkinter import *
numbers = []
def main():
main_window = Tk()
app = info(main_window)
main_window.mainloop()
class info:
def __init__(self, root):
# start = timer()
self.error_str = ''
self.root1 = root
self.root1.title('LOADING......')
self.root1.geometry("380x200")
self.root1.eval('tk::PlaceWindow . center')
self.root1.resizable(width=False, height=False)
self.root1.configure(background='white')
progress = ttk.Progressbar(self.root1, orient=HORIZONTAL,
length=380, mode='determinate')
progress.place(x=0, y=100)
i = 20
for x in range(1, 50):
numbers.append(x * 2)
print(numbers)
progress['value'] = i
self.root1.update_idletasks()
time.sleep(0.1)
i = i + 40
self.root = root
self.root.title('Second window')
self.root.geometry('1350x800+0+0')
frame1 = Frame(self.root, bg='#7877a5')
frame1.place(x=0, y=0, width=1350, height=150)
title = Label(frame1, text="Second Window", font=("Times New Roman", 40, "bold", "italic"),
bg='#7877a5',
fg='white')
title.place(x=380, y=45)
if __name__ == '__main__':
main()
Generally speaking you shouldn't call time.sleep() in a tkinter application because it interferes with the GUI's mainloop() and will make your program hang or freeze. Use the universal widget method after() instead.
Lastly you need to specify a maximum value for the Progressbar so its indicator scales properly relatively to the values of i you are setting its value to. The default for maximum is only 100, which your code was greatly exceeding in the for x loop.
Here's the code that needs to change in info.__init__(). The two lines changed have # ALL CAPS comments:
progress = ttk.Progressbar(self.root1, orient=HORIZONTAL,
length=380, mode='determinate',
maximum=(48*40)+20) # ADDED ARGUMENT.
progress.place(x=0, y=100)
i = 20
for x in range(1, 50):
numbers.append(x * 2)
print(numbers)
progress['value'] = i
self.root1.update_idletasks()
self.root1.after(100) # Delay in millisecs. # REPLACED TIME.SLEEP() CALL.
i = i + 40
I want to update my gui every second (i dont actually care about the time, but it should be like realtime). I got a script, where actually a Label as an int should increase by one and displayed. But i don't get the change, also i want to place the Label according to the width of the root, but it doesn't update. Only the update is a problem, maybe someone can help me with that. (Im a Beginner-Noob).
Script:
from tkinter import *
import time
c = 0
root = Tk()
root.title("Real Time Plot")
root.minsize(width = 200, height = 300)
m = root.winfo_reqwidth() / 2
root.update()
Text = Label(root, text = c)
Text.place(x =m, y = 150)
c = c + 1
print(m)
root.mainloop()
I've created a timer so I suppose you can do it like I did. Hope this works for you.
First, create a StringVar:
text = StringVar (value = "text")
Then create a Label with textvariable.
yourlabel = Label(root, textvariable = Text)
And then just make a function that will update the yourlabel:
yourlabel.set(and here you pass the new value)
So then your yourlabel will have the value that you ve passed. So then you can use something like self.after to update a func every 1000 ms.
You have to use a Python Threading, which will carry out this flawlessly!
Here is the code:
from tkinter import *
import threading
import time
def realtime_update():
while True:
global c, Text
c += 1
Text.configure(text=c+1)
time.sleep(0.001)
root_width = root.winfo_geometry()
root_width = root_width.split('x')
root_width = int(root_width[0])
Text.place(x=root_width/2, y=150)
time.sleep(0.01)
c = 0
root = Tk()
root.title("Real Time Plot")
root.minsize(width = 200, height = 300)
m = root.winfo_reqwidth() / 2
Text = Label(root, text = c)
Text.place(x=int(m), y = 150)
print(m)
threading.Thread(target=realtime_update, daemon=True).start()
root.mainloop()
It solves the following:
Realtime Update (precision to 0.01s)
Label changes position when root window resizes
You are updating just the variable value, not the value of the label.
You need to update the label with the content of c after increasing it:
Text.configure(text=c)
So it becomes something like that:
from tkinter import *
import time
c = 0
root = Tk()
root.title("Real Time Plot")
root.minsize(width = 200, height = 300)
m = root.winfo_reqwidth() / 2
root.update()
Text = Label(root, text = c)
Text.place(x =m, y = 150)
root.update()
time.sleep(2)
c = c + 1
Text.configure(text=c)
root.update()
print(m)
root.mainloop()
I did some minor update to your code, like adding a sleep time, to better show the behaviour.
I'm trying to create a simple tkinter GUI, and have read up online to add a .mainloop() to the end of my code to make the window appear, It is still not appearing.
There is no error message and simply
Process finished with exit code 0
I have attached my code.
Any help is greatly appreciated
def window():
global FPS
global maxFPS
root = Tk()
root.title('Camera Tracker')
root.geometry('500x300')
def quitfunc():
quitm=Tk()
quitm.title('Quit')
quitm.geometry('200x100')
yesbutton=Button(quitm,text='Yes',command=quit)
nobutton =Button(quitm,text='No',command=quitm.destroy)
yesbutton.place(x=50,y=60)
nobutton.place(x=130,y=60)
reassure = Label(quitm,text='Are you sure you want to quit?')
reassure.place(x=17,y=20)
quitm.mainloop()
sbview = Label(root, text=FPS)
sbview.place(y=50, x=50)
def FPScallback(self):
global FPS
FPS = round(sb.get())
if 10 > FPS < 18 or 29 < FPS:
sbview.config(fg='orange')
elif FPS < 10:
sbview.config(fg='red')
else:
sbview.config(fg='green')
sbview.config(text=FPS)
quitbutton = Button(root,command=quitfunc,text='Quit')
quitbutton.pack()
sb = ttk.Scale(root, from_=0, to=maxFPS, command=FPScallback, orient=HORIZONTAL)
sb.place(y=100, x=100)
sb.set(FPS)
root.mainloop()
Thanks A Bunch In Advance
If you create root from inside a function it will not be available when the function exits. In my example I'm creating root as well as some global variables in the global scope.
To ask the user if he wants to exit it's easier to use the standard library messagebox. If you want to catch any attempt to close the application (such as ALT-F4) you should reasearch root.protocol("WM_DELETE_WINDOW", do_exit) which runs the do_exit function when the app wants to exit by any means.
from tkinter import *
from tkinter import ttk
from tkinter import messagebox # Quit dialog
root = Tk() # Create root in the global scope
root.title('Camera Tracker') # so the functions can find it
root.geometry('500x300')
maxFPS = 50 # Initiate variables in the global scope
FPS = 25
sbview = Label(root, text=FPS)
sbview.place(y=50, x=50)
def quitfunc():
result = messagebox.askyesno('Quit', 'Are you sure you want to quit?')
if result:
root.destroy()
def FPScallback(self):
global FPS
FPS = round(sb.get())
if 10 > FPS < 18 or 29 < FPS:
sbview.config(fg='orange')
elif FPS < 10:
sbview.config(fg='red')
else:
sbview.config(fg='green')
sbview.config(text=FPS)
sb = ttk.Scale(root, from_=0, to=maxFPS, command=FPScallback, orient=HORIZONTAL)
sb.place(y=100, x=100)
sb.set(FPS)
quitbutton = Button(root, command=quitfunc, text='Quit')
quitbutton.pack()
root.mainloop()
I am looking to move a tkinter window to different x and y coordinates after it has been created. For example 5 seconds after the window has been created move it to
x=??? and y=???.
from tkinter import*
root = Tk()
root.title("lol")
root.geometry("300x300")
photo = PhotoImage(file="pepe.gif")
label = Label(image=photo).place(x=10, y=10)
root.mainloop()
The above code is just an example, how does it need to be modified to move by itself?
This example will show you how to reset the root geometry that controls the position of the window on screen; clicking on the image will toggle the locationof the window.
from tkinter import *
def move_me(idx=[0]): # <- creates a closure for the index of the location strings
loc = ["300x300+200+200", "300x300+300+300"]
root.geometry(loc[idx[0]]) # <-- reset the geometry
idx[0] = (idx[0]+1) % 2 # <-- toggles the index between 0 and 1
root = Tk()
root.title("lol")
root.geometry("300x300-100+100")
photo = PhotoImage(file="pepe.gif")
button = Button(root, image=photo, command=move_me)
button.place(x=10, y=10)
root.mainloop()
[edit] with auto repeat moving the window.
(attention, you have challenging game to catch the window to close it)
from tkinter import *
import random
def move_me():
x, y = str(random.randrange(800)), str(random.randrange(800))
loc = "300x300+" + x + '+' + y
root.geometry(loc)
root.after(500, move_me) # <-- auto call to move_me again every 1/2 second
root = Tk()
root.title("lol")
root.geometry("300x300+100+100")
photo = PhotoImage(file="pepe.gif")
label = Label(root, image=photo)
label.place(x=10, y=10)
move_me() # <-- call to move_me
root.mainloop()
What is the easy method to update Tkinter progress bar in a loop?
I need a solution without much mess, so I can easily implement it in my script, since it's already pretty complicated for me.
Let's say the code is:
from Tkinter import *
import ttk
root = Tk()
root.geometry('{}x{}'.format(400, 100))
theLabel = Label(root, text="Sample text to show")
theLabel.pack()
status = Label(root, text="Status bar:", bd=1, relief=SUNKEN, anchor=W)
status.pack(side=BOTTOM, fill=X)
root.mainloop()
def loop_function():
k = 1
while k<30:
### some work to be done
k = k + 1
### here should be progress bar update on the end of the loop
### "Progress: current value of k =" + str(k)
# Begining of a program
loop_function()
Here's a quick example of continuously updating a ttk progressbar. You probably don't want to put sleep in a GUI. This is just to slow the updating down so you can see it change.
from Tkinter import *
import ttk
import time
MAX = 30
root = Tk()
root.geometry('{}x{}'.format(400, 100))
progress_var = DoubleVar() #here you have ints but when calc. %'s usually floats
theLabel = Label(root, text="Sample text to show")
theLabel.pack()
progressbar = ttk.Progressbar(root, variable=progress_var, maximum=MAX)
progressbar.pack(fill=X, expand=1)
def loop_function():
k = 0
while k <= MAX:
### some work to be done
progress_var.set(k)
k += 1
time.sleep(0.02)
root.update_idletasks()
root.after(100, loop_function)
loop_function()
root.mainloop()