I'm running pycharm on the mac and noticed that the GUI would not open when it previously has. It bounces in the dock and then says that it is not responding.
So I wrote a very simple program to test the GUI and it still doesn't work.
from tkinter import *
import random
import time
root = Tk()
root.geometry("600x400")
var = 0
one = Label(root, textvariable=var)
one.pack()
while 1 == 1:
var = random.randint(1, 100)
time.sleep(1)
root.mainloop()
I tried reinstalling python but it doesn't help. Also, for my other program, textvariable wasn't able to work and I can't figure out why.
In order for the GUI to run and be responsive, mainloop has to execute. But your mainloop will never execute, because your while 1 == 1: loop will never finish. If you want to do something every second, remove that loop and use root.after instead.
Your textvariable isn't working because var is an integer. It needs to be a StringVar.
Related
I'm using Tkinter to show a login dialog and then run my main logic.
I intend for the following snippet to close the window (finish the main loop of tk) after clicking the button and just print indefinitely (it is wrapped in while True is in order for the whole script to continue executing, which simulates a real program logic).
But instead, the following snippet hangs the window and fails to close in macOS Ventura with Python 3.10:
from time import sleep
from tkinter import Tk, Button
def quit():
root.quit()
root = Tk()
Button(root, text="Quit", command=quit).pack()
root.mainloop()
while True:
sleep(1)
print("Running a program logic...")
I've tried to run a functional version of this code (which fails the same) and a threaded version of it (which just crashes since an NSWindow must be created on the main thread).
I just really can't wrap my head around it!
EDIT: Fully working example
EDIT 2: Clarify the intention of this code
EDIT 3: Even more minimal code
Try this:
from Tkinter import *
def quit():
global root
root.quit()
root = Tk()
while True:
Button(root, text="Quit", command=quit).pack()
root.mainloop()
This is NOT a duplicate of Python tkinter mainloop not quitting on closing the window
I have an app that builds on tkinter. I observed at sometimes after I close the window using the X button, the code will not execute past the mainloop() line. This happens completely randomly about 10% of chance. Rest of the time, it works like a charm. I would like to ask if there are any way to force it. As I said, the code blocks on the mainloop() line, thus calling sys.exit() after it does not help.
I am using Python 3.9.8.
This is not 100% reproducible, but here is something that might trigger the problem:
from tkinter import *
root = Tk()
Label(root, 'hi').pack()
mainloop()
print('exited')
My first thought is to use root.mainloop() instead of tkinter.mainloop(). This makes a difference if you are using several windows.
That said, I did see this a long time ago on some old OSes. Never figured out the reason, so I just wrote my own quit function, like this:
import tkinter as tk
def _quit():
root.quit()
root.destroy()
root = tk.Tk()
root.protocol("WM_DELETE_WINDOW", _quit)
tk.Label(root, 'hi').pack()
root.mainloop()
print('exited')
I wrote a Tkinter program that works great except that the entire program freezes when pressing a button that calls a long running function. The user has to wait for the function to finish before doing anything else.
I found a video that showed a solution for this and it worked for the guy in the video but not for me.
The following test case shows the problem.
import tkinter as tk
from random import randint
import time
import threading
root = tk.Tk()
root.title("Test Tkinter Threading")
root.geometry("500x400")
def five_seconds():
time.sleep(5)
my_label.config(text="5 Seconds is up!")
def rando():
random_label.config(text=f'Random Number: {randint(1, 100)}')
my_label = tk.Label(root, text="Hello there!")
my_label.pack(pady=20)
# This works but hangs program while executing five_seconds()
#sleep_button = tk.Button(root, text="5 seconds", command=five_seconds)
#sleep_button.pack(pady=20)
# Supposed to let user keep chosing random numbers while five_seconds() is running.
sleep_button = tk.Button(root, text="5 seconds",
command=threading.Thread(target=five_seconds).start())
sleep_button.pack(pady=20)
random_button = tk.Button(root, text="Pick Random Number", command=rando)
random_button.pack(pady=20)
random_label = tk.Label(root, text="")
random_label.pack(pady=20)
root.mainloop()
The guy in the video was able to ckick on the sleep button and keep clicking on the random button as expected. When I run this on windows 10 I get a strange result. If I click on the random button the five_seconds() function executes (even though I never hit the sleep buttton). The random button works and does not seem to hange but the program execution is messed up.
Is there an issue with windows 10 and threading Tkinter?
I'm using tkinter to display a simple yesno messagebox in python 3.2.
The code is as follows:
x = tkinter.messagebox.askyesno("New Process", "New Process:\n" + e[2:-7] + "\n\nKill?")
Althought there is nothing wrong with the code(it functions as I want it to), there is a window in the background that appears and does not respond.
This window will crash after about a few seconds or after killing the host process.
What might cause this?
A couple of things:
It looks like you're not running it as a root window.
root = Tk()
app = Frame(root)
app.grid()
my_example = Label(app, "text")
my_example.grid()
root.mainloop()
You should put it in a bat file with pause and you'll be able to see the error
I want to see continuously changing value of label in tkinter window. But I'm not seeing any of it unless I make a keyboard interrupt in MS-CMD while running which shows me the latest assigned value to label. Plz tell me ..What's going on & what's the correct code ??
import random
from Tkinter import *
def server() :
while True:
x= random.random()
print x
asensor.set(x)
app=Tk()
app.title("Server")
app.geometry('400x300+200+100')
b1=Button(app,text="Start Server",width=12,height=2,command=server)
b1.pack()
asensor=StringVar()
l=Label(app,textvariable=asensor,height=3)
l.pack()
app.mainloop()
The function server is called when you click the button, but that function contains an infinite loop. It just keep generating random numbers and sending these to asensor. You are probably not seeing any of it because the server function is run in the same thread as the GUI and it never gives the label a chance to update.
If you remove the while True bit from your code, a new number will be generate each time you click the button. Is that what you wanted to do?
Edit after comment by OP:
I see. In that case your code should be changed as follows:
import random
from Tkinter import Tk, Button, Label, StringVar
def server():
x = random.random()
print x
asensor.set(x)
def slowmotion():
server()
app.after(500, slowmotion)
app = Tk()
app.title("Server")
app.geometry('400x300+200+100')
b1 = Button(app, text="Start Server", width=12, height=2, command=slowmotion)
b1.pack()
asensor = StringVar()
asensor.set('initial value')
l = Label(app, textvariable=asensor, height=3)
l.pack()
app.mainloop()
I also introduced a new function, slowmotion, which does two things: 1) calls server, which updates displays the value, and 2) schedules itself to be executed again in 500ms. slowmotion is first ran when you first click the button.
The problem with your code was that it runs an infinite loop in the main GUI thread. This means once server is running, the GUI will not stop and will not get a chance to display the text you asked it to display.