我在堆叠' Pages'在tkinter中彼此重叠。
我有一个主Frame
,它包含两个包含不同信息的子帧。第一个子帧包含Listbox
和几个按钮,并在主框架的左侧打包。第二帧应该具有不同的“页面”。 (现在两个)并让它们填满整个框架。
我的问题是这两个页面都是'并排显示而不是彼此重叠。
import tkinter as tk
class Settings(tk.Tk):
def __init__(self, master=None):
tk.Tk.__init__(self, master)
self.focus_force()
self.grab_set()
# set focus to settings window
# Main window title
self.title("Settings")
# set up grid containers
container_main = tk.Frame(self, width=500, height=700)
container_main.pack(side='top', fill='both', expand=True)
container_main.grid_rowconfigure(0, weight=1)
container_main.grid_columnconfigure(0, weight=1)
container_listbox = tk.Frame(container_main, bg='blue', width=200, height=700)
container_listbox.pack(side='left', fill='both', expand=True)
container_listbox.grid_rowconfigure(0, weight=1)
container_listbox.grid_columnconfigure(0, weight=1)
container_settings = tk.Frame(container_main, bg='red', width=300, height=700)
container_settings.pack(side='right', fill='both', expand=True)
container_settings.grid_rowconfigure(0, weight=1)
container_settings.grid_columnconfigure(0, weight=1)
# build settings pages
self.frames = {}
self.frames["Options"] = Options(parent=container_listbox, controller=self)
self.frames["General"] = General(parent=container_settings, controller=self)
self.frames["Future"] = Future(parent=container_settings, controller=self)
如果我解开这两行。我得到一个错误,说我不能在里面使用几何管理器网格。
# self.frames["General"].grid(row=0, column=0, sticky='nsew')
# self.frames["Future"].grid(row=0, column=0, sticky='nsew')
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
class Options(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(parent, text='List Box')
label.grid(row=0, column=0, sticky='nsew', padx=1, pady=1)
button1 = tk.Button(parent, text='General', command=lambda: controller.show_frame('General'))
button2 = tk.Button(parent, text='Future', command=lambda: controller.show_frame('Future'))
button1.grid(row=1, column=0, sticky='ew')
button2.grid(row=2, column=0, sticky='ew')
class General(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(parent, text='General')
label.pack(side='left', fill='both', expand=True, )
print("Hi I'm General")
class Future(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(parent, text='Future')
label.pack(side='left', fill='both', expand=True)
print("Hi I'm Future")
app = Settings()
app.mainloop()
两个页面'在有意义的同时进行初始化和显示。我只是不知道如何让一个人在另一个上升,因为frame.tkraise()
应该这样做,但事实并非如此。我还希望能够在不在顶部的页面上执行grid_forget()
,以避免将来可能意外地将值输入隐藏的输入框。
编辑:如果我评论出未来'页面然后是' General'页面将占用整个框架空间,因此使用grid_forget()
我会得到相同的结果。我只是不知道我会在哪里grid_forget()
,然后我还会在哪里重新配置或进行grid()
来电?
答案 0 :(得分:2)
我的问题是这两个页面都是'并排显示而不是彼此重叠。
如果您使用pack()
在根窗口上放置一个框架,然后在该框架内使用grid()
,那么它会起作用,但如果您尝试在框架内使用pack()
然后尝试在同一帧内使用grid()
,它将失败。
根窗口和框架也是如此。如果pack()
根窗口中有一个框架,则您无法使用grid()
将任何内容放入同一个根窗口。
grid()
vs pack()
问题的问题是因为类General
和类Future
配置标签小部件的位置是父框架{{{正在使用1}}。这阻止了在同一父框架中使用pack()
来放置General和Future框架。
为了解决这个问题,我们改变了:
grid()
为:
label = tk.Label(parent, text='General')
and
label = tk.Label(parent, text='Future')
以上是唯一可以正常工作的修复方法。
label = tk.Label(self, text='General')
and
label = tk.Label(self, text='Future')
答案 1 :(得分:2)
我冒昧地重组您的应用程序逻辑,以表达如何更容易解决您的问题 - 我还提供了一些其他信息。
您当前实施的问题是hide
和show
您的网页的问题,在您的按钮的command
关键字分配中。在我提供的实现中,Options
类是所有魔法发生的地方 - 特别是show_general
和show_future
方法。简单地说,当点击常规按钮时,我在pack_forget()
窗口小部件上调用future_page
,在pack(...)
窗口小部件上调用general_page
,反之亦然,当我想要显示未来页面时。 (这可以很容易地实现,但我会把它留给你。)
此外,我以模块化代码的方式构建应用程序逻辑,因此在每个步骤中我都可以测试它,看看我在哪里,例如我开始在main()
创建每个容器,并确保所有内容都正确布局(我喜欢给每个容器一个不同的颜色,使其更容易可视化间距等),然后再转到{{1我将放置小部件的框架和Settings
框架,并编写GUI按预期运行所需的代码。
我不会解释每一行,但我确信在这一点上你可以看到我所得到的。我建议阅读代码(从Options
开始),
并弄清楚我是如何以及为什么以我的方式写这个。 (我把它写成了我认为你想要的功能,以及在这里和那里提供一些指示 - 它并不意味着完美。)
main()
我希望这有帮助!