I am looking to move a tkinter window to different x and y coordinates after it has been created. For example 5 seconds after the window has been created move it to
x=??? and y=???.
from tkinter import*
root = Tk()
root.title("lol")
root.geometry("300x300")
photo = PhotoImage(file="pepe.gif")
label = Label(image=photo).place(x=10, y=10)
root.mainloop()
The above code is just an example, how does it need to be modified to move by itself?
This example will show you how to reset the root geometry that controls the position of the window on screen; clicking on the image will toggle the locationof the window.
from tkinter import *
def move_me(idx=[0]): # <- creates a closure for the index of the location strings
loc = ["300x300+200+200", "300x300+300+300"]
root.geometry(loc[idx[0]]) # <-- reset the geometry
idx[0] = (idx[0]+1) % 2 # <-- toggles the index between 0 and 1
root = Tk()
root.title("lol")
root.geometry("300x300-100+100")
photo = PhotoImage(file="pepe.gif")
button = Button(root, image=photo, command=move_me)
button.place(x=10, y=10)
root.mainloop()
[edit] with auto repeat moving the window.
(attention, you have challenging game to catch the window to close it)
from tkinter import *
import random
def move_me():
x, y = str(random.randrange(800)), str(random.randrange(800))
loc = "300x300+" + x + '+' + y
root.geometry(loc)
root.after(500, move_me) # <-- auto call to move_me again every 1/2 second
root = Tk()
root.title("lol")
root.geometry("300x300+100+100")
photo = PhotoImage(file="pepe.gif")
label = Label(root, image=photo)
label.place(x=10, y=10)
move_me() # <-- call to move_me
root.mainloop()
Related
I'm making a gui but ran into an issue with not knowing how to reform all the widget correctly so I decided to not allow any resizing. Now I just want the window to center itself when I drag the window to the top, and I looked up the event for this and I believe it is , but now the window keeps resetting itself to the original spot it pops up whenever I move the window. I only want it to reset when the window gets dragged to the top only
from tkinter import *
def move(e): #
root.geometry("1270x725+0+0")
root = Tk()
root.geometry("1270x725+0+0")
root.resizable(False, False)
button = Button(root, command=move)
button.place(x=10, y=10)
Entry = Entry(root)
Entry.place(relx=.4, rely=.5)
root.bind('<Configure>', move)
root.mainloop()
You can check if the event.y is smaller than a certain value. If it is smaller then, reset the position.
Here is an example:
from tkinter import *
def move(e):
if e.y < 5:
sw, sh = root.winfo_screenwidth(), root.winfo_screenheight()
root.geometry(f"1270x725+{(sw-1270)//2}+{(sh-725)//2}")
root = Tk()
root.geometry("1270x725+0+0")
root.resizable(False, False)
root.bind('<Configure>', move)
root.mainloop()
Is it possible to get the popup option (pop function in the code) on hovering the cursor on the button?
import tkinter as tk
from tkinter import Tk, BOTH, Menu
def pop(bt):
try:
x = bt.winfo_rootx()+238
y = bt.winfo_rooty()+10
popup.tk_popup(x, y, 0)
finally:
popup.grab_release()
root = tk.Tk()
popup = Menu(root, tearoff=0,relief='raised')
popup.add_command(label="About")
popup.add_command(label="User manual")
popup.add_command(label="Contact us")
button1 =tk.Button(root, text="HELP",height=3,width=26,command=lambda: controller.show_frame(HelpPage))
button1.configure(command = lambda: pop(button1))
button1.place(x=0,y=0
)
root.mainloop()
.
button1.bind('<Enter>',pop(button1)) #gives the following output without the mouse cursor over that button.
Try this:
import tkinter as tk
window = None
def leave_window(event):
global window
if 0 < root.winfo_pointerx() - root.winfo_rootx() < button.winfo_width():
if 0 < root.winfo_pointery() - root.winfo_rooty() < button.winfo_height():
# Mouse still over button
return None
if window is not None:
window.destroy()
window = None
def create_window(event):
global window
if window is not None:
# The window is already open
return None
window = tk.Toplevel(root)
window.overrideredirect(True)
label = tk.Label(window, text="Text", bg="black", fg="white")
label.pack()
window.update()
# Move the window to the cursor's
x = root.winfo_pointerx()
y = root.winfo_pointery()-window.winfo_height()
window.geometry("+%i+%i" % (x, y))
window.bind("<Leave>", leave_window)
root = tk.Tk()
button = tk.Button(root, text="-------- Hover the mouse here --------")
button.pack(fill="both", expand=True)
button.bind("<Enter>", create_window)
button.bind("<Leave>", leave_window)
root.mainloop()
I binded to <Enter> and <Leave> to check if the mouse is over the button. If it is, it creates a window with a label called text. You can change it to it showing the menu.
For more answers look here.
Please bind your Button with mouse enter and call pop function.
Check out this code :
button1.bind('<Enter>', pop)
Control your popup location as well as destroy popup on '' case again bind it and call custom function that will destroy popup.
You need <Enter> and <Leave> bind sequences to map and unmap the Menu. Tkinter Menu has two methods post and unpost where post shows the menu at given coordinates, and unpost hides it away. Unfortunately, I couldn't test it as the unpost functionality doesn't work on macOS or Linux [refer to this link for the same]. I also changed the x, y coords to map the Menu in the center of the widget (Button), it can be changed if required.
Here is the complete sample code.
import tkinter as tk
from tkinter import Tk, BOTH, Menu
def pop(evt):
but = evt.widget
if str(evt.type) == "Enter":
# Map the menu in the center of the width.
x = but.winfo_rootx() + int(but.winfo_width()/2)
y = but.winfo_rooty() + int(but.winfo_height()/2)
popup.tk_popup(x, y)
elif str(evt.type) == "Leave":
popup.unpost()
root = tk.Tk()
root.geometry("300x300")
popup = Menu(root, tearoff=0, relief='raised')
popup.add_command(label="About")
popup.add_command(label="User manual")
popup.add_command(label="Contact us")
button1 = tk.Button(root, text="HELP", height=3, width=26)
button1.bind('<Enter>', pop)
button1.bind('<Leave>', pop)
button1.pack(pady=100)
root.mainloop()
Like said, unpost doesn't work on macOS or Linux, so I couldn't test the sample code 100% but it should work fine.
In my code, I am trying to make a loading screen for a frogger game but for some reason I am encountering a problem where I display a picture and then do the .sleep function before displaying a label over the top of it however it displays both of them at the same time it just runs the code 1 second after it should, can anyone help?
Here is my code below:
from tkinter import *
import tkinter as tk
import time
window = Tk()
window.geometry("1300x899")
LoadingScreen = PhotoImage(file = "FroggerLoad.gif")
Loading = Label(master = window, image = LoadingScreen)
Loading.pack()
Loading.place(x = 65, y = 0)
time.sleep(1)
FroggerDisplay = Label(master = window, font ("ComicSans",100,"bold"),text = "Frogger")
FroggerDisplay.pack()
FroggerDisplay.place(x = 500, y = 300)
window.mainloop()
When you use time.sleep(1) before starting the window.mainloop(), the window is created only after 1 second, and the FroggerDisplay label will be created at the same time with it. So, you can't use time.sleep(seconds) now.However, you can use window.after(ms, func) method, and place into the function all the code between time.sleep(1) and window.mainloop(). Note, that unlike the time.sleep(seconds) you must give the time to window.after (the first argument) as milliseconds.Here is the edited code:
from tkinter import *
def create_fd_label():
frogger_display = Label(root, font=("ComicSans", 100, "bold"), text="Frogger") # create a label to display
frogger_display.place(x=500, y=300) # place the label for frogger display
root = Tk() # create the root window
root.geometry("1300x899") # set the root window's size
loading_screen = PhotoImage(file="FroggerLoad.gif") # create the "Loading" image
loading = Label(root, image=loading_screen) # create the label with the "Loading" image
loading.place(x=65, y=0) # place the label for loading screen
root.after(1000, create_fd_label) # root.after(ms, func)
root.mainloop() # start the root window's mainloop
PS: 1) Why do you use .pack(...) and then .place(...) methods at the same time - the first one (.pack(...) here) will be ignored by Tkinter.
2) It's better to use a Canvas widget for creating a game - unlike labels it supports transparency and simpler to use. For example:
from tkinter import *
root = Tk() # create the root window
root.geometry("1300x899") # set the root window's size
canv = Canvas(root) # create the Canvas widget
canv.pack(fill=BOTH, expand=YES) # and pack it on the screen
loading_screen = PhotoImage(file="FroggerLoad.gif") # open the "Loading" image
canv.create_image((65, 0), image=loading_screen) # create it on the Canvas
root.after(1000, lambda: canv.create_text((500, 300),
font=("ComicSans", 100, "bold"),
text="Frogger")) # root.after(ms, func)
root.mainloop() # start the root window's mainloop
Note: you might need to change coords with Canvas.
I've searched and found a few things on parent windows in python but that is not what I was looking for. I am trying make a simple program that opens a window and another window after that when the previous one is closed. I was also trying to implement some kind of loop or sleep time to destroy the window by default if the user does not. This is what I have (I'm new please don't laugh)
from tkinter import *
import time
root = Tk()
i = 0
if i < 1:
root.title("title")
logo = PhotoImage(file="burger.gif")
w1 = Label(root, image=logo).pack()
time.sleep(3)
root.destroy()
i = i + 1
if i == 1:
root.title("title")
photoTwo = PhotoImage(file="freedom.gif")
labelTwo = Label(root, image=photoTwo).pack()
time.sleep(3)
root.destroy()
i = i + 1
mainloop.()
Perhaps you're looking for something like this:
from tkinter import *
import time
def openNewWindow():
firstWindow.destroy()
secondWindow = Tk()
secondWindow.title("Second Window")
photoTwo = PhotoImage(file="freedom.gif")
labelTwo = Label(secondWindow, image=photoTwo).pack()
secondWindow.mainloop()
firstWindow = Tk()
firstWindow.title("First Window")
logo = PhotoImage(file="burger.gif")
w1 = Label(firstWindow, image=logo).pack()
closeBttn = Button(firstWindow, text="Close!", command=openNewWindow)
closeBttn.pack()
firstWindow.mainloop()
This creates a button in the first window, which the user clicks. This then calls the openNewWindow function, which destroys that window, and opens the second window. I'm not sure there's a way to do this using the window exit button.
To get create a more sustainable window creation, use this:
from tkinter import *
import time
def openThirdWindow(previouswindow):
previouswindow.destroy()
thirdWindow = Tk()
thirdWindow.title("Third Window")
photoTwo = PhotoImage(file="freedom.gif")
labelTwo = Label(thirdWindow, image=photoTwo).pack()
thirdWindow.mainloop()
def openSecondWindow(previouswindow):
previouswindow.destroy()
secondWindow = Tk()
secondWindow.title("Second Window")
photoTwo = PhotoImage(file="freedom.gif")
labelTwo = Label(secondWindow, image=photoTwo).pack()
closeBttn = Button(secondWindow, text="Close!", command= lambda: openThirdWindow(secondWindow))
closeBttn.pack()
secondWindow.mainloop()
def openFirstWindow():
firstWindow = Tk()
firstWindow.title("First Window")
logo = PhotoImage(file="burger.gif")
w1 = Label(firstWindow, image=logo).pack()
closeBttn = Button(firstWindow, text="Close!", command= lambda: openSecondWindow(firstWindow))
closeBttn.pack()
firstWindow.mainloop()
openFirstWindow()
This places the opening of each window in a seperate function, and passes the name of the window through the button presses into the next function. Another method would be setting the window names as global, but this is messy.
The function "lambda:" calls the function, in tkinter you must type this if you want to pass something through a command.
We initiate the whole process first first called "openFirstWindow()"
If I created Tkinter window with some text that filled the whole window and now wanted to replace the window with a new text, is there a way to refresh the window?
For Example:
a= 100
win= Tk()
win.geometry("500x300")
while a > 0:
if a%2 == 0:
lbl = Label (win, bg = "purple")
lbl.pack()
else:
lbl = Label (win, bg = "blue")
lbl.pack()
a= x-1
The problem with this code is that the Tkinter window does not refresh and just provides the end result instead of showing the windows changing colors.
Thanks for the help!
That is not the way to change UI states, because even if you refreshed the window it would be so quick you won't notice, instead change the state, wait some time and change the state again e.g. here I show how to animate color
from Tkinter import *
index = 0
def changeColor():
global index
if index%2==0:
label.configure(bg = "purple")
else:
label.configure(bg = "blue")
index+=1
label.after(1000, changeColor)
root = Tk()
mainContainer = Frame(root)
label = Label(mainContainer, text="")
label.configure(text="msg will change every sec")
label.pack(side=LEFT, ipadx=5, ipady=5)
mainContainer.pack()
label.after(1000, changeColor)
root.title("Timed event")
root.mainloop()
This Is How I Do To Update Data From Sql Server in tkinter GUI python3
from tkinter import *
import os
window=Tk()
window.geometry('300x300')
def update():
window.destroy()
os.system('test.py')
Button(window,text="Refresh",command=update)
window.mainloop()