简体   繁体   中英

Python Tkinter runtime variable geometry

My Question: In the python Tkinter module, is it possible to increase and adjust the size of GUI geometry at runtime to accommodate the number of widgets displayed?

My case: At initialization, I have defined a standard geometry of XxY dimensions. As the program runs, the number of widgets displayed on the GUI increase/decrease. Is there a mechanism to auto adjust the geometry, instead of manually dragging and extending using the borders.

Below I have added two images, Image 1- defined geometry when the program was run. Second Image: During run time, many labels get added and this standard dimensions doesn't show all of them.

GUI 不显示尺寸大小下方的标签

初始 GUI 几何尺寸

Let's start with the docs to answer your Question:

By default a top-level window appears on the screen in its natural size, which is the one determined internally by its widgets and geometry managers . If the natural size of a top-level window changes, then the window's size changes to match. A top-level window can be given a size other than its natural size in two ways. First, the user can resize the window manually using the facilities of the window manager, such as resize handles. Second, the application can request a particular size for a top-level window using the wm geometry command . These two cases are handled identically by Tk; in either case, the requested size overrides the natural size. You can return the window to its natural by invoking wm geometry with an empty geometry string .

The problem is that you still want to use your wm_geometry , right? So you cant just put the empty string in the wm_geometry, since this would undo your geometry that you defined before. This would only work if you knew a specific point in your code, eg a big widget, that will beyond your defined bounderies.

As I dont know your code I see just this two options:

  1. Kepp track of the dimension of widgets you put on your window.
  2. Define a minsize of your root window.

-> You would need to use grid in this case, cause you need the bbox of the basic widget methods that works with grid, pack return just (0,0,0,0) .

So here is the code as exampel:

import tkinter as tk

root=tk.Tk()
root.geometry('200x200')

def adder():
    tk.Label(root,text='spacer').grid(column=0,row=_r.get()) #add spacer
    _r.set(_r.get()+1) #next row
    root.update_idletasks() #update_idletasks to get correct value
    if _b.get(): #if this part of the function never happend
        if root.bbox()[3] >= 200: #check if the pixels of your bbox right down corner is beyond the height of 200
            root.geometry('') #go back to natural behavior
            _b.set(False) #set flag that we dont need this part of code anymore
    else:
        pass #skip
        

add_b = tk.Button(root,text='add', command=adder)
add_b.grid(column=0,row=0)

_b = tk.BooleanVar(value=True)
_r = tk.IntVar(value=1)


root.mainloop()

If you do know, when your frame will beyond your predefined geometry and you just want to span an empty frame then look at this and call root.geometry('') at this point.

The second option is way easier to handle and maybe the preferenced answer. In this case you just use wm_minsize instead of your geometry method:

The window manager will restrict the window's dimensions to be greater than or equal to width and height

import tkinter as tk

root=tk.Tk()
root.wm_minsize(width=200,height=200)

def adder():
    tk.Label(root,text='spacer').pack() #add spacer
        

add_b = tk.Button(root,text='add', command=adder)
add_b.pack()



root.mainloop()

Last but not least you can think about a scrollable frame , which should be the best choice since your screen has limits too.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM