When I run the program, it first waits until I enter input, then it will play the sound, then it shows the window with my image. Why is it doing this out of order?
from tkinter import *
import winsound
main = Tk()
main.state('zoomed')
main.geometry("1366x768")
# Displays a gif.
def show():
dollar_canvas = Canvas(width=50, height=50, bg='lightgrey', highlightthickness=0)
dollar_canvas.place(x=850, y=25)
my_gif = PhotoImage(file='Dollar50x50.gif')
dollar_canvas.image = my_gif
dollar_canvas.create_image(0, 0, image=my_gif, anchor=NW)
# Accepts an input, such as enter.
def getinput():
a = input()
# Plays a ring sound.
def play():
winsound.PlaySound('money', winsound.SND_ALIAS)
show()
getinput()
play()
mainloop()
They aren't running out of order. Throw in a few print statements to see the order they are executing in. The problem is that until the event loop (mainloop) runs, tkinter doesn't have an opportunity to update the display. In your code mainloop won't run until the other functions finish.
To force the display to update you can call root.update_idletasks().
Related
My program needs to track the user input at all times. For that i think the input() command is the easiest solution. The problem is: At the same time there should be a Tkinter GUI in fullscreen mode running. I've tried a few things, but nothing really worked out. Here is a simplified program, which shows the problems:
from tkinter import *
import tkinter as tk
from threading import Thread
def GUI():
root=tk.Tk()
Text = Label(master=root, text="Test").pack(side="top")
Button = Button(master=root, text="Button").pack(side="top")
root.mainloop()
def input_loop():
x = input()
print(x)
t1 = Thread(target=GUI)
t2 = Thread(target=input_loop)
t1.start()
t2.start()
Even though now both loops work, i still can't type into the console unless I manually select the console window. Other solutions like the entry widget in tkinter won't work because there is no place for them in my actual program. Please let me know if you find something which works reliably.
i didn't get your problem clearly but i will try to help .
so you are saying the program running on full screen but you want to run it on some resolution?
from tkinter import *
import tkinter as tk
from threading import Thread
def GUI():
root=tk.Tk()
# Program title
root.title("Title")
# Preventing user from fullscreen/resize the window
root.resizable(0, 0)
# Resolution of the windows in pixles
root.geometry(f"{820}x{460}")
Text = Label(master=root, text="Test").pack(side="top")
Btn = Button(master=root, text="Button").pack(side="top")
root.mainloop()
def input_loop():
x = input()
print(x)
t1 = Thread(target=GUI)
t2 = Thread(target=input_loop)
t1.start()
t2.start()
also i changed button function to btn because i faced an error with it , and you can now complete the program and play with the resolution of the buttons and windows so on .
I have a program that I wrote in tkinter, but if the while true loop starts running, the window stops working(not responding) what should I do?
code:
import pyautogui
import sys
import keyboard
def basla():
while True:
if keyboard.is_pressed("shift"):
pyautogui.press("enter")
pyautogui.typewrite("/pull ")
elif keyboard.is_pressed("E"):
pyautogui.press("enter")
pyautogui.typewrite("/me WHO GAS")
pyautogui.press("enter")
def bitir():
sys.exit()
pencere = Tk()
pencere.title("Keybinder")
pencere.geometry("300x300+10+10");
baslat_buton = Button(pencere)
baslat_buton.config(text="Başlat", bg="black",width=8,height=2, fg="white", command=basla)
baslat_buton.place(x=100,y=100)
bitir_buton = Button(pencere)
bitir_buton.config(text="Bitir", bg="black", fg="white",width=8,height=2, command=bitir)
bitir_buton.place(x=100,y=150)
mainloop()```
"In tkinter don't use while True which runs forever (or runs longer time) because it blocks mainloop() in tkinter and it can't update items in window, and it looks like it freezes."
Check out this topic and see if it makes it clear to you. tkinter root.mainloop with While True loop
So I have this code:
try:
# for Python2
from Tkinter import *
except ImportError:
# for Python3
from tkinter import *
class Injector():
def __openInjector(self):
root = Tk()
root.geometry('600x400')
root.title('Toontown Rewritten Injector')
root.resizable(False, False)
def __init__(self):
self.code = ''
self.__openInjector()
def runInjectorCode(self):
exec(self.code.get(1.0, 'end'), globals())
def __openInjector(self):
root = Tk()
root.geometry('600x400')
root.title('Toontown Rewritten Injector')
root.resizable(False, False)
frame = Frame(root)
self.code = Text(frame, width=70, height=20)
self.code.pack(side='left')
Button(root, text='Inject!', command=self.runInjectorCode).pack()
scroll = Scrollbar(frame)
scroll.pack(fill='y', side='right')
scroll.config(command=self.code.yview)
self.code.config(yscrollcommand=scroll.set)
frame.pack(fill='y')
Injector()
In the IDLE console it works fine and does everthing I want it to do. But whenever I run the .py file on my Desktop. The black window appears, then just closes and nothing happens. Any help?
First, you have two methods in your class with the same name. The first one gets overwritten by the second one. At the end of that second one, you need the following line:
root.mainloop()
This will actually run the GUI. It's needed when running from a script, but not when running within the interactive interpreter.
Add it at the end of the second __openInjector:
...
self.code.config(yscrollcommand=scroll.set)
frame.pack(fill='y')
root.mainloop()
At the end of your second __openInjector method, add the line: root.mainloop().
This is necessary for Tkinter to run your code. mainloop is really nothing more than an infinite loop that waits for events. An event may be a user interaction, such as clicking a button.
My guess is you don't need mainloop when running interactively for purely convenience reasons.
I'm trying to run a simple Tkinter program that opens a program when you click a button. The code is listed below. I use a command to call a program that then calls a fortran program. However, when I click on the button, it opens the program but the menu of the program i'm calling goes into an infinite loop......the offending code seems to be in the button1Click module.
Any help is greatly appreciated.
Thanks
from Tkinter import *
import os, sys
from win32com.client import Dispatch
xlApp=Dispatch('Excel.Application')
_PSSBINPATH=r"C:\Program Files\PTI\PSSE32\PSSBIN"
os.environ['PATH']=_PSSBINPATH+';'+os.environ['PATH']
sys.path.insert(0,_PSSBINPATH)
import redirect; redirect.psse2py()
import psspy
class MyApp:
def __init__(self, parent):
self.myParent = parent ### (7) remember my parent, the root
self.myContainer1 = Frame(parent)
self.myContainer1.pack()
self.button1 = Button(self.myContainer1)
self.button1.configure(text="OK", background= "green")
self.button1.pack(side=LEFT)
self.button1.bind("<Button-1>", self.button1Click) ### (1)
self.button2 = Button(self.myContainer1)
self.button2.configure(text="Cancel", background="red")
self.button2.pack(side=RIGHT)
self.button2.bind("<Button-1>", self.button2Click) ### (2)
def button1Click(self,event): ### (3)
psspy.runiplanfile(r"C:\MNTACT\Contingency Program\work\contingency-31-4.irf")
if self.button1["background"] == "green": ### (4)
self.button1["background"] = "yellow"
else:
self.button1["background"] = "green"
def button2Click(self, event): ### (5)
self.myParent.destroy() ### (6)
root = Tk()
myapp = MyApp(root)
root.mainloop()
What makes you think there's an infinite loop happening? I see no loop in button1Click, unless the loop is in runiplanfile. Are you using "infinite loop" to mean simply that the GUI has stopped responding?
Tkinter is single threaded and cannot process events except via the event loop. If one event takes a long time to process, the GUI will hang until the processing of that event is completed. If you're exec'ing an external process and waiting for it to complete, your GUI will appear to be frozen until that process finishes.
I want to track my mouse-position and show that in a tiny window.
For that, I created this piece of code:
#! /usr/bin/python
from Tkinter import *
from Xlib import display
def mousepos():
data = display.Display().screen().root.query_pointer()._data
return data["root_x"], data["root_y"]
root = Tk()
strl = "mouse at {0}".format(mousepos())
lab = Label(root,text=strl)
lab.pack()
root.title("Mouseposition")
root.mainloop()
This little script shows the mouse-position on startup but doesn't refresh it on mouse-movement. I don't get behind it (did I say that I'm new to python?).
I think I have to use an event from Xlib that tells my script when the mouse is moving...
How do I refresh my mouse-position?
Use root.after to call update periodically.
Use strl = tk.StringVar() and tk.Label(...,textvariable=strl) to
allow the Label text to change.
Call strl.set() to change the Label text.
A default value for screenroot equal to display.Display().screen().root was added
to mousepos so that most of that long chain of function calls are
not repeated every time mousepos is called. Calling mousepos() without any arguments will continue to work as usual.
import Tkinter as tk
import Xlib.display as display
def mousepos(screenroot=display.Display().screen().root):
pointer = screenroot.query_pointer()
data = pointer._data
return data["root_x"], data["root_y"]
def update():
strl.set("mouse at {0}".format(mousepos()))
root.after(100, update)
root = tk.Tk()
strl = tk.StringVar()
lab = tk.Label(root,textvariable=strl)
lab.pack()
root.after(100, update)
root.title("Mouseposition")
root.mainloop()