Tkinter window not opened - python

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

Related

tkinter .after() second and minute

hey guys i have a problem im making a timer in tkinter but i cant use time.sleep() so i use .after() and i have new problem,I made an entry that I want the entry number to be * 60 and after the set time, a text will be written that says >> time is over! ,but then, how should that 60 be converted into seconds? my code:
from tkinter import *
from playsound import playsound
from time import sleep
import time
def jik():
a = int(text.get())
app.after(a * 600)
Label(app,text="time is over").pack()
app = Tk()
app.minsize(300,300)
app.maxsize(300,300)
text = Entry(app,font=20)
text.pack()
Button(app,text="start",command=jik).pack()
app.mainloop()
For example, if I press the number 1, it >>time is over in a fraction of a second
The after command takes input in milliseconds, so multiply it by 1000 to convert it to seconds.
Additionally, I just made a small example that displays the countdown for you as the clock ticks down:
# Usually it is a good idea to refrain from importing everything from the tkinter
# package, as to not pollute your namespace
import tkinter as tk
root = tk.Tk() # Customary to call your Tk object root
entry = tk.Entry(root)
entry.pack()
curtime = tk.Label(root)
curtime.pack()
is_running = False # Global variable to ensure we can't run two timers at once
def countdown(count):
global is_running
if count > 0:
curtime['text'] = f'{count:.2f}' # Update label
# Call the countdown function recursively until timer runs out
root.after(50, countdown, count-0.05)
else:
curtime['text'] = 'time is over'
is_running = False
def btn_press():
global is_running
if is_running:
return
cnt = int(entry.get())
is_running = True
countdown(cnt)
tk.Button(root, text='start', command=btn_press).pack()
root.minsize(300, 300)
root.maxsize(300, 300)
root.mainloop()
.after function takes two arguments, the first is the time in milliseconds, that is 1000 milliseconds is equal to one second, the second argument is a function to call after that time has passed, simply define what to do after the time has passed in a second function, and use it as a second argument as follows.
from tkinter import *
from playsound import playsound
from time import sleep
import time
MILLISECOND_TO_SECOND = 1000
def jik():
a = int(text.get())
app.after(a * MILLISECOND_TO_SECOND, show_label)
def show_label():
Label(app,text="time is over").pack()
app = Tk()
app.minsize(300,300)
app.maxsize(300,300)
text = Entry(app,font=20)
text.pack()
Button(app,text="start",command=jik).pack()
app.mainloop()

Python tkinter after method not working as expected

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

When using tkinter in Python 3, how do you get a button to run a function each time it is pressed?

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

Why does this not work? (Python)

(Python 3.4.1)
Hey, I have this simple little guess my number game in Tkinter but it doesn't work for some reason... Can anyone see why?
from tkinter import *
from random import random
import tkinter.messagebox
window = Tk()
def Guess():
if int(guessnum) == int(Number):
print("Well Done!")
exit()
elif int(guessnum) >= int(Number):
print("Too big")
elif int(guessnum) <= int(Number):
print("Too small")
Number = (round(random() * 10))
window.title("Guess My Number")
window["padx"] = 70
window["pady"] = 20
guessnum="1"
entryWidget=Entry(window,textvariable=guessnum).grid(row=1,column=0)
button = Button(window, text="Guess",command=Guess()).grid(row=2,column=0)
window.mainloop()
You have made two classic Tkinter errors in one line:
button = Button(window, text="Guess", command=Guess()).grid(row=2,column=0)
# ^ assigned result of call to command, not
# the actual function
# ^ assigned result of grid
# (None) to button rather
# than the Button
This line is equivalent to something like:
Guess()
_ = Button(..., command=None)
button = _.grid(...)
You should have done:
button = Button(window, text="Guess", command=Guess)
button.grid(row=2,column=0)
Note parentheses removed from Guess and grid call split out to separate line
The testvariable option must be an instance of the StringVar class.
guessnum = StringVar
guessnum.set("1") # optional, otherwise '' I believe
I recommend this tkinter reference and use it constantly when programming tkinter widgets I am not completely familiar with, and even sometimes when answering questions here.

Progressbar and combinations in Python

I am using itertools.combinations module to find a large number of combinations. While my program finds all its combinations (a lot of them) it checks for sum of every combination to be some number and then program store that combination in list.
from itertools import *
from math import *
import Tkinter as tk
import ttk
x = int(raw_input('Enter number of combinations: '))
z = int(raw_input('Enter sum number: '))
def combinator():
comb = combinations(range(100), x)
for i in comb:
yield i
my_combinations = []
combination_s = combinator()
for i in combination_s:
print i
c = list(i)
if fsum(c)==z:
my_combinations.append(c)
print my_combinations
root = tk.Tk()
root.title('ttk.Progressbar')
pbar = ttk.Progressbar(root, length=300, mode='determinate', maximum = 100)
pbar.pack(padx=5, pady=5)
root.mainloop()
I want to have ttk.progressbar that shows progress every time program evaluates sum of combinations. How can I do that?
Here is an example that increases the progress bar for every combination. It just waits for a short time, but you can easily change it to do some calculations in the for loop in ProgBarApp.start instead of time.sleep
from Tkinter import *
from itertools import combinations
import ttk
import time
class ProgBarApp:
def __init__(self):
self.vals = range(1, 20)
self.combs = list(combinations(self.vals,3))
self.n = len(self.combs)
self.progressbar = ttk.Progressbar(root, maximum = self.n+1)
self.progressbar.pack()
def start(self):
for c in self.combs:
self.progressbar.step()
time.sleep(0.01)
root.update()
root.destroy()
root = Tk()
p = ProgBarApp()
root.after(0, p.start())
root.mainloop()

Categories