So I'm trying to make a program that has a typing animation,
Here is my reproducible example :
from tkinter import *
root = Tk()
text = "message"
num = 0
message = text[num]
label = Label(root,text=message)
label.pack()
def add() :
global num
num + 1
leng = len(text)
if num == leng :
while True :
num = leng
label.configure(text=message)
root.after(1000, add)
root.mainloop()
It doesn't work and just shows the first letter
First of all, please make descriptive variable names. Calling a variable x will not help others understand what they stand for.
Secondly, the way you used root.after() is not how it works. This piece of code should be in a function, which should have as the second parameter.
Finally, I removed the message variable because we can just increment the index value by 1.
Here is the code:
from tkinter import *
root = Tk()
text = "message"
index = 0
lab = Label(root)
lab.pack()
def add(a):
global index
if index < len(text):
lab.config(text=lab.cget("text") + text[index])
index += 1
root.after(1000, add, root)
add('arg')
root.mainloop()
Related
I'm trying to learn Tkinter module, but I can't undestand why the after method doesn't behave as expected. From what I know, it should wait ms milliseconds and then execute the function, but in my case the function gets executed many more time, not considering the time I write. Here's the code:
from tkinter import *
def doSomething():
x = int(l["text"])
l["text"] = str(x + 1)
root = Tk()
root.geometry("300x300")
l = Label(root, text="0")
l.pack()
while True:
l.after(1000, doSomething)
root.update()
if int(l["text"]) >= 5:
break
root.mainloop()
After the first 2 seconds the label starts displaying humongous numbers
After the first 2 seconds the label starts displaying humongous numbers
Keep in mind, while True, is an infinite loop, you are making infinite calls to root.after() means alot of events are being scheduled to be called after 1 second. Better way to do this is to remove your while and move it all inside your function.
from tkinter import *
root = Tk()
def doSomething():
x = int(l["text"])
l["text"] = x + 1
if int(l["text"]) < 5: # Only repeat this function as long as this condition is met
l.after(1000, doSomething)
root.geometry("300x300")
l = Label(root, text="0")
l.pack()
doSomething()
root.mainloop()
Though the best way to write the function would be to create a variable and increase the value of that variable inside the function and then show it out:
from tkinter import *
root = Tk()
count = 0 # Initial value
def doSomething():
global count # Also can avoid global by using parameters
count += 1 # Increase it by 1
l['text'] = count # Change text
if count < 5:
l.after(1000, doSomething)
root.geometry("300x300")
l = Label(root, text=count)
l.pack()
doSomething() # If you want a delay to call the function initially, then root.after(1000,doSomething)
root.mainloop()
This way you can reduce the complexity of your code too and make use of the variable effectively and avoid nasty type castings ;)
You are using infinite loop when using while True. Correct way is:
from tkinter import *
def doSomething():
x = int(l["text"])
l["text"] = str(x + 1)
if x < 5:
l.after(1000, doSomething)
root = Tk()
root.geometry("300x300")
l = Label(root, text="0")
l.pack()
doSomething()
root.mainloop()
I have a problem. I want to simplify and explain the problem.
I have this code:
from tkinter import *
from tkinter.scrolledtext import ScrolledText
def do():
global text
for i in range(0, 10):
time.sleep(0.5)
text.insert(INSERT, i)
root = Tk()
global text
text = ScrolledText(root)
text.grid()
button = Button(root, text = 'insert', command = do)
button.grid(row = 1, column = 0)
root.mainloop()
It does a simple job. it has to open the root window and add a number to it every half second, but it does it all at once and after the loop is done.
If your looking for how to use after(ms,func), this is how your function should look like:
lst = [_ for _ in range(10)] #list of numbers to index through
count = 0 #index number
def do():
global count
text.insert(INSERT,lst[count]) #insert the current element onto the textbox
count += 1 #increase the index number
rep = root.after(500, do) #repeat the function
if count >= len(lst): #if index number greater than length of items in list
root.after_cancel(rep) #stop repeating
and root.after_cancel(id) will cancel the repetition. Using global outside the functions holds no good.
My tkinter window not opened after i add while true function. How can I get this to work. Its works without while true, but i need it in my function.
from tkinter import *
from random import random
import sys
import random
maxcount = int (input("How many times "))
i = 1
cats = Tk()
cats.wm_title("maxcount test")
cats.geometry("500x500")
def black():
while True:
i+1
if i == 5:
break
Button(cats, text="Start", command=black()).grid(row=1, column=0)
Label(cats, text="How many times:").grid(row=0, column=0)
cats.mainloop()
You had two errors:
- i + 1 probably meant i += 1, then i musty be declared global so it can be modicied in the scope of the function.
- the Button command was black(), which is a call to the function black. What is needed is a reference to the function black (without the ())
One thing to note: as remarked by #Sierra_Mountain_Tech, as it is, the user must first input an integer for the
tkinter app to start.
from tkinter import *
from random import random
import sys
import random
maxcount = int (input("How many times "))
i = 1
cats = Tk()
cats.wm_title("maxcount test")
cats.geometry("500x500")
def black():
global i
while True:
i += 1
if i >= 5: # <-- changed from i == 5 at #Sierra_Mountain_Tech suggestion
break
Button(cats, text="Start", command=black).grid(row=1, column=0)
Label(cats, text="How many times:").grid(row=0, column=0)
cats.mainloop()
In tkinter, python, I'm trying to make a program so when Up is clicked, 1 is added to a number (using StringVar to show it), and when the number gets to 10, it is restarted to 0. I've managed to complete this part, but I want to enable it so after a certain amount of time, the number can no longer be changed. For example, I hold down the Up button for a certain given amount of time, and the last number I get is a 6. Now, I want it to stay on 6, no matter how many times I press Up. Here's my code:
from tkinter import *
root = Tk()
hwd1 = 0
mult = 1
hwd = StringVar()
hwd.set("0")
def add1(event):
global hwd
global hwd1
on = True
if on:
hwd1 += 1*(mult)
hwd.set(str(hwd1));
if hwd1 == 10:
hwd1 = 0
hwd.set("0")
label = Label(root, textvariable=hwd)
label.pack()
root.bind_all('<Up>', add1)
This code shows the first part of what I have done, but when I try to do the second part, here's what I done:
from tkinter import *
root = Tk()
hwd1 = 0
mult = 1
hwd = StringVar()
hwd.set("0")
def deladd():
global add1
del(add1)
def add1(event):
global add1
global hwd
global hwd1
on = True
if on:
hwd1 += 1*(mult)
hwd.set(str(hwd1));
if hwd1 == 10:
hwd1 = 0
hwd.set("0")
root.after(5000, deladd)
label = Label(root, textvariable=hwd)
label.pack()
root.bind_all('<Up>', add1)
From using this code, I get an error message saying add1 referenced before assignment and I'm not sure why. I'd appreciate some help, so thanks for your time :)
-Jake
You're missing a declaration - just edit your code and put def add1 before def deladd
The problem is because deladd() is calling add1, but on the first call it can't 'reach' it.
import tkinter as tk
panel = tk.Tk()
num = 42
lbl1 = tk.Label(panel, text = str(num))
Let's say I have a function and button like this:
def increase():
lbl1.configure(text = str(num+1))
btn = tk.Button(panel, text = 'Increase', command = increase)
panel.mainloop()
This button will make the number that is the label increase by 1 when pressing the button. However, this only works once before the button does absolutely nothing. How can I make it so that every time I press the button, the number increases by 1?
You never saved the incremented value of num.
def increase():
global num # declare it a global so we can modify it
num += 1 # modify it
lbl1.configure(text = str(num)) # use it
It's because num is always 43
import tkinter as tk
num = 42
def increase():
global num
num += 1
lbl1.configure(text = str(num))
panel = tk.Tk()
lbl1 = tk.Label(panel, text = str(num))
lbl1.pack()
btn = tk.Button(panel, text = 'Increase', command = increase)
btn.pack()
panel.mainloop()