I want to create a frameless resizable window, the problem is, when there are many widgets, they glitch when the window is resized using a Sizegrip. The only solution that I found that removes this glitch effect is to update the window during the resize.
Unfortunately if you keep resizing for a few seconds a recursion error will occur and I have no idea why.
Here's my code
import tkinter as tk
from tkinter.ttk import Sizegrip
root = tk.Tk()
root.overrideredirect(True)
root.geometry("500x400")
def on_resize(event):
global root
root.update()
tk.Label(root, text = "Use the bottom right grip to resize, try for a few seconds").pack()
sg = Sizegrip(root)
sg.pack(side = tk.BOTTOM, anchor = tk.E)
sg.bind("<B1-Motion>", on_resize)
root.mainloop()
Check if you're already resizing and don't call root.update() again.
resizing = False
def on_resize(event):
global resizing
if not resizing:
resizing = True
root.update()
resizing = False
Related
When I use win.resizable(False, False) on a window that has the zoomed attribute set to true, the window still can be resized by moving the title bar of the window, or by using the "Super + Down Arrow" shortcut. Is there any way to prevent this?
example code, that can reproduce this:
import tkinter as tk
master = tk.Tk()
master.wait_visibility()
master.attributes("-zoomed", True)
master.resizable(False, False)
master.title("This window should not be resizable")
tk.mainloop()
Ubuntu 22.04.1
Gnome 42.5
X11
I was able to create a maximized window that could not be resized by doing the following:
import tkinter as tk
master = tk.Tk()
master.resizable(0, 0) # prevent resizing
master.wait_visibility() # wait for the window
master.state('zoomed') # maximize the window
# this guard clause isn't strictly necessary,
# but it's a 'best practice' kind of thing
if __name__ == '__main__':
master.mainloop() # run
That said, I'm on Windows 10 so YMMV. I hope this helps!
P.S.: I noticed you're calling tk.mainloop() instead of master.mainloop(), which may or may not be a problem (at the very least, it's unorthodox) - just a heads-up!
I want to update a widgets on a canvas widget when the window is resized. You can bind a function call on window resize via the <Configure> flag:
window.bind("<Configure>",resize)
However, this calls resize continuously while the window is being updated, many times per second. What would be better is if I could call resize after the window has been resized. So I imagine, once MB1 has been released.
So can I combine bindings? I need to combine both <Configure> and <ButtonRelease-1>
I was thinking of creating a global variable that contains the state of MB1, and updating this state via <ButtonRelease-1> and <ButtonPress-1> but I'm wondering if there's a lass hacky method.
A simple solution is to not do the work immediately, but instead schedule it for some time in the future. Each time the <Configure> event is handled you can cancel any previously scheduled work before scheduling the work again.
The following example shows how to update a label in the middle of a frame on <Configure>, but only after the window size hasn't changed for 200ms.
import tkinter as tk
def handle_configure(event):
global after_id
if after_id:
event.widget.after_cancel(after_id)
after_id = event.widget.after(200, update_label)
def update_label():
width = root.winfo_width()
height = root.winfo_height()
text = f"Size: {width}x{height}"
label.configure(text=text)
root = tk.Tk()
frame = tk.Frame(root, width=400, height=400)
frame.pack(fill="both", expand=True)
label = tk.Label(frame, text="")
label.place(relx=.5, rely=.5, anchor="c")
after_id = None
frame.bind("<Configure>", handle_configure)
root.mainloop()
So I tried to make this labelframe wider by using the basic width and width option.
Here's my given minimal code.
from tkinter import *
from tkinter import ttk
app = Tk()
app.resizable(False, False)
mainLayout = ttk.Frame(app, padding=10)
mainLayout.grid()
settings = ttk.Labelframe(mainLayout, text="Settings", padding=10, width=1000)
settings.grid()
ttk.Label(settings, text="Length limit (in seconds)").grid()
ttk.Spinbox(settings, from_=60, to=600, width=4).grid()
app.mainloop()
minimalized preview:
used in application:
i want to get this labelframe little bit bigger and make the inside centered, But i had no knowledge to do so, Any help will apreciated!
It seems like you just want to have a main_frame in the app. For simplicity I've used .pack with the options fill and expand with the constants tkinter.BOTH to stretch the widget in both (x,y) direction and True to consume extra space. (This is one of the reasons why wildcard imports are discouraged, you can be unaware of overwriting something, use import tkinter as tk instead). Same happens with the LabelFrame, you may could delete one of the containers, but that is up to you.
In LabelFrame I have configured the grid and gave the instruction that the column 0 should get the extra space with the priority/weight 1.
In addition, I gave your Spinbox a little bit more width, changed the size of the window and separated the constructor from the geometrymethod.
To get in touch with the geometry management in tkinter, you could play around with the instructions (e.g. comment some out) and see what happens.
from tkinter import *
from tkinter import ttk
app = Tk()
app.geometry('500x500')
app.resizable(False, False)
mainLayout = ttk.Frame(app, padding=10)
mainLayout.pack(fill=BOTH,expand=True)
settings = ttk.Labelframe(mainLayout, text="Settings", padding=10, width=1000)
settings.pack(fill=BOTH,expand=True)
settings.columnconfigure(0,weight=1)
my_label = ttk.Label(settings, text="Length limit (in seconds)")
my_label.grid()
my_spinbox = ttk.Spinbox(settings, from_=60, to=600, width=20)
my_spinbox.grid()
app.mainloop()
I am trying to display an image on my desktop without any boarder or window, like an image floating in the desktop. I also want to be able to control its position once it has been created, with the arrow keys or with a line of code that changes its position with some coordinate system of some sorts. I haven't found any method after some reaserch (not in Python, at least).
If that's not possible, please recommend another programming language that can.
You can use Tkinter for this.
I made a little example:
Python3
from tkinter import Toplevel, Tk, Label, PhotoImage
win = Tk()
win.attributes('-alpha', 0.0)
win.iconify()
window = Toplevel(win)
window.geometry("500x500+100+100")
window.overrideredirect(1)
photo = PhotoImage(file="test.png")
label = Label(window, image=photo)
label.pack()
win.mainloop()
Python2
from Tkinter import Toplevel, Tk, Label
import ImageTk
win = Tk()
win.attributes('-alpha', 0.0)
win.iconify()
window = Toplevel(win)
window.geometry("500x500+100+100") # create an window 500x500 pixel, 100 pixels from the upper left corner
window.overrideredirect(1) # Take the border away
photo = ImageTk.PhotoImage(file="test.png")
label = Label(window, image=photo)
label.pack()
win.mainloop()
Every time I use this code in my applications:
tkMessageBox.showinfo("Test", "Info goes here!")
a message box pops up (like it is supposed to), but after I click OK, the box disappears along with most of the other widgets on the window. How do I prevent the other widgets from disappearing?
Here Is My Code:
from Tkinter import *
import tkMessageBox
root = Tk()
root.minsize(600,600)
root.maxsize(600,600)
p1 = Label(root, bg='blue')
p1.place(width=600, height=600)
b1 = Button(p1, text="Test Button")
b1.place(x="30", y="50")
tkMessageBox.showinfo("Test", Info")
root.mainloop()
Ok, there are a few things going wrong here. First, your label has no string or image associated with it. Therefore, it's width and height will be very small. Because you use pack, the containing widget (the root window) will "shrink to fit" around this widget and any other widgets you pack in the root window.
Second, you use place for the button which means its size will not affect the size of the parent. Not only that, but you place the button inside the very tiny label. Thus, the only thing controlling the size of the parent is the label so the main window ends up being very small.
You have another problem is that you're showing the dialog before entering the event loop. I'm a bit surprised that it even works, but Tkinter sometimes does unusual things under the covers. You should enter the event loop before calling the dialog.
Try this variation of your code as a starting point:
from Tkinter import *
import tkMessageBox
def showInfo():
tkMessageBox.showinfo("Test","Info")
root = Tk()
p1 = Label(root, bg='blue', text="hello")
p1.pack()
b1 = Button(root, text="Test Button", command=showInfo)
b1.pack()
root.mainloop()