I want to make a windows that will shoes the values of a variable in real-time in python with tkinter. The variable in question will be in a while loop. This is for a small physics project. Thanks for your help.
OK you haven't been very clear on exactly what your doing, but if you are going to update in a while loop you would do something such as getting whatever variable and then setting a variable on a label presumably.
import tkinter, time
from tkinter import *
#declare vars for readability
var1 = StringVar()
velocityOfBall = 0
gravity = 9.8
root = Tk()
def startDemo():
while True:
velocityOfBall += gravity
var1.set("Velocity: " + velocityOfBall)
time.sleep(1)
button1 = Button(root, command=startDemo).grid(row=0, column=0)
label1 = Label(root, textvariable = var1).grid(row=1, column=0)
root.mainloop()
Related
i found a tutorial on google which integer value could be update by using .config(). So I had using the below code to update the value. I think my logic it wrong by put the while loop like that , but i not sure how could i update the a = a + 1 on to the gui.
My code :
import tkinter as tk
from random import randint
master_window = tk.Tk()
master_window.geometry("250x150")
master_window.title("IntVar Example")
lab = tk.Label(master_window)
integer_variable = tk.IntVar()
integer_variable.set(2)
label = tk.Label(master_window,text="output", height=50)
label.place(x=80, y=80)
a = 25
def update():
my_data=integer_variable.get(a) # read the value of selected radio button
label.config(text=str(my_data)) # Update the Label with data
while True:
a = a + 1
master_window.update()
master_window.mainloop()
The setup you have so far is quite strange and your intuition that the logic is wrong is accurate.
Here's an alternative to get you started - note how I refrain from using external variables and instead use the .set() and get() operations to change the value of the integer_variable:
import tkinter as tk
master_window = tk.Tk()
master_window.geometry("250x150")
master_window.title("IntVar Example")
integer_variable = tk.IntVar()
integer_variable.set(2)
label = tk.Label(master_window, text=integer_variable.get())
label.grid(row=0, column=0)
button = tk.Button(master_window, text="Update value", command=update)
button.grid(row=1, column=0)
def update():
curr_integer_variable_value = integer_variable.get()
updated_integer_value = curr_integer_variable_value + 1
integer_variable.set(updated_integer_value)
label.config(text=str(integer_variable.get()))
master_window.mainloop()
Im trying to detect a button press in tkinker but every method on google does not work for me, i want to change variable value for my python project.
Here's the basic code:
from tkinter import *
win= Tk()
win.geometry("500x600")
up = Button(win, text="⬆", bg="yellow", borderless=1, width=150, height=100, command = var = 1)
up.place(x=0, y = 500)
win.mainloop()
How do i do that?
Sourced from: To Detect Button Press In Python Tkinter Module
You could just place the variable change within a function
up = Button(win, text="⬆", bg="yellow", borderless=1, width=150, height=100, command=changeVar())
def changeVar():
var = 1
Or something close to this, assuming it's in the global namespace, since you're attemping to change it via var = 1 anyway.
I want to use the input value as variable and this is my code.
from tkinter import *
from tkinter import messagebox
window = Tk()
Label(window, text='Cavity number').grid(row=0)
CavNum = StringVar()
for i in range(1,8) :
globals()['L{}_CavNum'.format(i)] = StringVar()
globals()['L{}_CavNum'.format(i)] = Entry(window, textvariable=globals()['L{}_CavNum'.format(i)])
globals()['L{}_CavNum'.format(i)].grid(row=0, column=i)
window.geometry("1200x150")
window.mainloop()
everytime I do print(L1_CavNum), it says "<tkinter.Entry object .!entry>". please tell me what is the problem
You are re-using the same name for the entry widget as you use for StringVar. You could simply change globals()['L{}_CavNum'.format(i)] = StringVar() to globals()['L{}_CavNumSV'.format(i)] = StringVar() and print(L1_CavNum) to print(L1_CavNumSV.get()). However the .get() function will execute when your code runs so you will have to have a button or another event to callback the function.
I would do it like this.
from tkinter import *
def print_vars():
for x in range(len(cavity_string_vars)):
print(cavity_string_vars[x].get())
window = Tk()
Label(window, text='Cavity number').grid(row=0)
cavity_string_vars = []
cavity_entries = []
for i in range(7):
cavity_string_vars.append(StringVar())
cavity_entries.append(Entry(window, textvariable=cavity_string_vars[i]))
cavity_entries[i].grid(row=0, column=i)
print_button = Button(window, text="Print", command=print_vars)
print_button.grid(row=1, column=0)
window.geometry("1200x150")
window.mainloop()
To me associated arrays are much easier than naming each variable even when you program it as you have. Perhaps that is needed for your case.
I am new to python and I have been learning tkinter recently. So I thought with myself that using the grid_forget() function I can remove a widget and redefine it. I thought of this animation that changes the padding of a label so it would create space (kind of like moving the label but not exactly). However, the animation does not work at all. The program freezes until the label reaches the last value of the padding. How can I fix this? Or is there a better way to animate a label moving in the screen?
Here is my code:
from tkinter import *
import time
root = Tk()
lbl = Label(root, text='------')
lbl.grid(row=0, column=0)
def animation():
padding = 0
while padding < 31:
lbl.grid_forget()
padding += 1
lbl.grid(row=0, column=0, padx=padding)
time.sleep(0.2)
# alternative: root.after(200, lambda: lbl.grid(row=0, column=0, padx=padding))
btn = Button(root, text='Animate', command=animation)
btn.grid(row=1, column=1)
root.mainloop()
You need to update the screen for changes to be shown.
Here is a working version using the .update() method:
from tkinter import *
import time
root = Tk()
lbl = Label(root, text='------')
lbl.grid(row=0, column=0)
def animation():
padding = 0
while padding < 31:
lbl.grid_forget()
padding += 1
lbl.grid(row=0, column=0, padx=padding)
root.update()
time.sleep(0.2)
# alternative: root.after(200, lambda: lbl.grid(row=0, column=0, padx=padding))
btn = Button(root, text='Animate', command=animation)
btn.grid(row=1, column=1)
root.mainloop()
Here is a way I also use to animate stuff on the screen, I am not able to understand what you were trying to achieve with your code snippet above, I tried making some changes to it but I feel this way is much better and let's you get more control of your window.
This uses the widely used Canvas widget in the tkinter library.
The Canvas is a general purpose widget, You can use it for a lot of things. Visit the hyper link for more clarity
Here is a short example of how you would create text on the screen.
from tkinter import *
root = Tk()
root.title("My animation")
c = Canvas(root)
x = 20
y = 20 #Instead of using row and column, you simply use x and y co-ordinates
#We will use these co-ordinates to show where the text is in the starting
my_text = c.create_text(x,y,text = '-----')
c.pack()
# This is all you need to create this text on your screen!
root.mainloop()
The idea is that you put your canvas up on your window , and then place whatever you want on it.
There are a lot more attributes that you can add to make your text look even better. Here is an in-depth tutorial on it.
Now that we have made your text widget, It is now time to move it around. Let us move it to 90,20 From our initial position which is 20,20
Here is how we will do it. If we simply move to text object to 90,90, We won't see any animations, it will just directly have it there. So what we will do is first create it at 21,20. Then 22,20. And so on...
We do this really fast till we reach 90,20
This looks like we are moving the text
from tkinter import *
import time
root = Tk()
root.title("My animation")
c = Canvas(root)
x = 20
y = 20 #Instead of using row and column, you simply use x and y co-ordinates
#We will use these co-ordinates to show where the text is in the starting
my_text = c.create_text(x,y,text = 'weee')
c.pack()
def animation():
y = 0.1
x = 0
for _ in range(1000):
c.move(my_text,x,y)
root.update()
anlabel = Button(root,text = 'Animate!',command = animation).pack()
root.mainloop()
This is not only applicable to text, but everything (like other images)that is there on the canvas. The canvas also has Events which will let you use mouse-clicks and other keys on the computer too.
I have made some changes from the previous code, But it is executable and you can try it for yourself to see how it works. increasing the value in time.sleep() makes the animation slower, the lesser the value, the faster.
Are you sure you aren't trying to do something more like the below example? Animating the padding on one of your widgets is going to screw up the rest of your display.
from tkinter import *
import time
root = Tk()
lbl = Label(root, text='')
lbl.grid(row=0, column=0)
def animation(step=12):
step = 12 if step < 0 else step
lbl['text'] = ' ------ '[step:step+6]
root.after(200, lambda: animation(step-1))
Button(root, text='Animate', command=animation).grid(row=1, column=0, sticky='w')
root.mainloop()
I would like to display some numbers, as fast as possible in Tkinter. The Program, I am trying to do, gets many numbers send and should show those.
Here is an similar environment, where tinter has to change a label very quickly.
from tkinter import *
import time
window = Tk()
lbl13 = Label(window, text="-")
lbl13.grid(column=0, row=0)
x = 0
while 1:
lbl13.config(text = str(x))
time.sleep(2)
x +=1
window.mainloop()
The Tkinter window doesn't even open on my computer. Is that because i have too weak hardware? What could I change that this Program also runs on my Computer. Thank you for every answer!
The infinite while loop will keep the program from getting to the line where you call window.mainloop(). You should call window.update() repeatedly instead of window.mainloop() at the end:
from tkinter import *
import time
window = Tk()
lbl13 = Label(window, text="-")
lbl13.grid(column=0, row=0)
x = 0
while 1:
lbl13.config(text = str(x))
window.update()
x +=1
Using after and a proper mainloop is probably a more more flexible way to achieve what you want; it is also reusable in different contexts, and can be used in an application that does more than trivially increment a number on a label:
maybe something like this:
import tkinter as tk
if __name__ == '__main__':
def increment():
var.set(var.get() + 1)
label.after(1, increment)
window = tk.Tk()
var = tk.IntVar(0)
label = tk.Label(window, textvariable=var)
label.pack()
increment()
window.mainloop()