如何在 tkinter 中动态调整窗口大小以"autofit"其内容?



我目前正在使用tkinter开发一个GUI,它允许用户在不同的帧之间导航。我的代码结构基于这个用户响应。

我现在的问题是,当一个帧发生变化时,自动调整tkinter的窗口以适应其内容。我希望窗口的边框适合红色箭头后面的小部件,如这里和这里(下面示例代码的输出(,这样在每一帧中就没有这样的"空白"。

该代码的工作方式是方法show_frame允许在两个定义的帧之间进行更改。

from tkinter import *

class WindowController(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(root)
container.grid()
self.frames = {}
for F in (FirstWindow, SecondWindow):
frame = F(parent=container, controller=self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
self.show_frame(FirstWindow)
self.destroy()
def show_frame(self, cont):
frame = self.frames[cont]
frame.tkraise()

class FirstWindow(Frame):
def __init__(self, parent, controller):
self.controller = controller
self.parent = parent
Frame.__init__(self, parent)
# Widgets:
# "Do Nothing" Button
self.Title0 = Button(self, text='Do nothing')
self.Title0.grid(row=0, column=0)
# "Do Nothing" Button
self.Title1 = Button(self, text='Do Nothing')
self.Title1.grid(row=1, column=0)
# Change Frame Button
self.Title2 = Button(self, text='To Second Window', command=lambda: self.controller.show_frame(SecondWindow))
self.Title2.grid(row=2, column=0)

class SecondWindow(Frame):
def __init__(self, parent, controller):
self.controller = controller
self.parent = parent
Frame.__init__(self, parent)
# Widgets:
# "Do Nothing" Button
self.Title0 = Button(self, text='Do nothing')
self.Title0.grid(row=0, column=0)
# "Do Nothing" Button
self.Title1 = Button(self, text='Do Nothing')
self.Title1.grid(row=0, column=1)
# Change Frame Button
self.Title2 = Button(self, text='To First Window', command=lambda: self.controller.show_frame(FirstWindow))
self.Title2.grid(row=0, column=2)

if __name__ == "__main__":
root = Tk()
root.resizable(width=False, height=False)
app = WindowController()
app.mainloop()

我的问题似乎和这里的问题相似,但没有解决。

这是我在这里的第一个问题,所以我们非常感谢批评。

问题的答案是Tkinter Frame Resize:由于两个框架都是网格化的,因此窗口将展开以包含这两个框架。

要想让窗口改变大小,一次只需要网格化一个框架。

要从窗口中删除帧并仍然记住其属性,请使用:

frame.grid_remove()

要再次显示帧,请使用:

frame.grid()  # Will remember grid settings

这个代码有效,但你可能会改进它的美观性:

class WindowController(Tk):
def __init__(self, *args, **kwargs):
Tk.__init__(self, *args, **kwargs)
container = Frame(root)
container.grid()
self.frames = {}
for F in (FirstWindow, SecondWindow):
frame = F(parent=container, controller=self)
self.frames[F] = frame
frame.grid(row=0, column=0, sticky="nsew")
frame.grid_remove()     # Remove all frames
self.show_frame(FirstWindow)
self.destroy()
def show_frame(self, cont):
for fme in self.frames:     # Remove all frames
self.frames[fme].grid_remove()
frame = self.frames[cont]
frame.grid()        # Display frame

最新更新