我想创建一个管理工具,左边是菜单,右边是框架。我读了一篇关于更改框架的教程,并尝试从那里开始。问题是右框架应始终为1200x750 ..而这不起作用。我知道python,但仍然有一些学习上面向对象的python ... 有人看到我在这里缺少什么吗?
import Tkinter as tk
import tkFont as tkfont
class SampleApp(tk.Tk):
def __init__(self, *args, **kwargs):
tk.Tk.__init__(self, *args, **kwargs)
self.title_font = tkfont.Font(family='Helvetica', size=18, weight="bold", slant="italic")
self.grid_columnconfigure(1, weight=0)
self.grid_columnconfigure(2, weight=1)
self.grid_rowconfigure(1, weight=1)
leftframe = tk.Frame(self, width=300, height=750, bd=1, relief = tk.SOLID, bg="white")
rightframe = tk.Frame(self, width=1200, height=750, bd=1, relief = tk.SOLID, bg="white")
bottomframe = tk.Frame(self, width=1500, height=50, bd=1, relief = tk.SOLID, bg="white")
leftframe.grid(row=1,column=1, sticky="nsew")
rightframe.grid(row=1, column=2, sticky="nsew")
bottomframe.grid(row=2, column=1, columnspan=2, sticky="nsew")
leftframe.pack_propagate(0) # <-- still got this in to make the menu width fixed
button1 = tk.Button(leftframe, text="Start page" , anchor="w", bg="white", bd=0, command=lambda: self.show_frame("StartPage")).pack(padx=10, anchor="sw", fill="x")
button2 = tk.Button(leftframe, text="Page 1" , anchor="w", bg="white", bd=0, command=lambda: self.show_frame("PageOne")).pack(padx=10, fill="x")
button3 = tk.Button(leftframe, text="Page 2" , anchor="w", bg="white", bd=0, command=lambda: self.show_frame("PageTwo")).pack(padx=10, fill="x")
button4 = tk.Button(leftframe, text="Page 3" , anchor="w", bg="white", bd=0, command=lambda: self.show_frame("PageOne")).pack(padx=10, fill="x")
button5 = tk.Button(leftframe, text="Page 4" , anchor="w", bg="white", bd=0, command=lambda: self.show_frame("PageOne")).pack(padx=10, fill="x")
button5 = tk.Button(leftframe, text="Page 5" , anchor="w", bg="white", bd=0, command=lambda: self.show_frame("PageOne")).pack(padx=10, fill="x")
self.frames = {}
for F in (StartPage, PageOne, PageTwo):
page_name = F.__name__
frame = F(parent=rightframe, controller=self)
self.frames[page_name] = frame
# put all of the pages in the same location;
# the one on the top of the stacking order
# will be the one that is visible.
frame.config(bg="white")
frame.grid(row=0, column=0, sticky="news")
self.show_frame("StartPage")
self.init_topmenu()
def show_frame(self, page_name):
'''Show a frame for the given page name'''
frame = self.frames[page_name]
frame.tkraise()
def init_topmenu(self):
menubar = tk.Menu(self)
self.config(menu=menubar)
fileMenu = tk.Menu(menubar)
fileMenu.add_command(label="Page 1", command=lambda: self.show_frame("PageOne"))
fileMenu.add_command(label="Page 2", command=lambda: self.show_frame("PageTwo"))
menubar.add_cascade(label="File", menu=fileMenu)
class StartPage(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is the Startpage", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
class PageOne(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 1", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
class PageTwo(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
label = tk.Label(self, text="This is page 2", font=controller.title_font)
label.pack(side="top", fill="x", pady=10)
if __name__ == "__main__":
app = SampleApp()
window_width = 1500
window_height = 800
width = app.winfo_screenwidth()
height = app.winfo_screenheight()
app.geometry('%dx%d+%d+%d' % (window_width, window_height, width*0.5-(window_width/2), height*0.5-(window_height/2)))
app.mainloop()
答案 0 :(得分:0)
你犯了三个常见的错误:
调用sticky
时,可以使用grid
属性解决第一个问题。例如:
leftframe.grid(row=1,column=1, sticky="nsew")
rightframe.grid(row=1, column=2, sticky="nsew")
bottomframe.grid(row=2, column=1, columnspan=2, sticky="nsew")
您还需要对每个页面执行此操作:
frame.grid(row=0, column=0, sticky="nesw")
第二个问题可以通过给行和列赋予权重来解决。 Tkinter将使用行或列的weight
来确定是否应该为该行或列分配任何剩余空间。这可能是人们在使用grid
时最常犯的错误。
根据经验,只要您使用grid
,主窗口小部件应至少有一行和一列非零权重。
self.grid_columnconfigure(1, weight=0)
self.grid_columnconfigure(2, weight=1)
self.grid_rowconfigure(1, weight=1)
您正在关闭几何体传播,这很少是一个好的解决方案。我强烈建议您删除对grid_propagate
和pack_propagate
的所有来电。使用tkinter的最佳方法是配置内部窗口小部件,并让包含的窗口小部件增大或缩小以适应。当您正确设置GUI时,无论当时有什么分辨率或字体处于活动状态,它都将是正确的大小。
我使用tk或tkinter超过20年,并且需要在这些年中关闭几何传播不超过非常非常少的时间。这是一个有点高级的选项,它只对某些特定的边缘情况有用。
这不会导致问题,但它有助于使您的代码更容易理解。我强烈建议您将窗口小部件的创建与在屏幕上组织它们分开。当您阅读“小部件,网格,小部件,网格,小部件,网格”时,很难对您正在构建的内容进行心理描绘。相反,如果你有“小部件,小部件,小部件”,然后是“网格,网格,网格”,你就会清楚地知道你正在构建什么。
例如,我会重新安排代码的开头,如下所示:
self.grid_columnconfigure(1, weight=0)
self.grid_columnconfigure(2, weight=1)
self.grid_rowconfigure(1, weight=1)
leftframe = tk.Frame(self, width=300, height=750, bd=1, relief = tk.SOLID, bg="white")
rightframe = tk.Frame(self, width=1200, height=750, bd=1, relief = tk.SOLID, bg="white")
bottomframe = tk.Frame(self, width=1500, height=50, bd=1, relief = tk.SOLID, bg="white")
leftframe.grid(row=1,column=1, sticky="nsew")
rightframe.grid(row=1, column=2, sticky="nsew")
bottomframe.grid(row=2, column=1, columnspan=2, sticky="nsew")
请注意我在创建leftframe
,rightframe
和bottomframe
时如何明确设置父级。没有理由不这样做,它使代码更加自我记录。