使用 tkinter 将多个框架与小部件组合在一个窗口中



我正在尝试构建一个基本上只有一个窗口的GUI。此窗口是不同框架的组合。我想做的是将这些框架(每个框架进一步由多个小部件组成(以某种格式排列在一起:

  • 第一帧(左上(:从上到左为窗口大小的一半
  • 第二个框架(左下(:窗口大小从底部和左侧的一半
  • 第三帧(右上角(:从顶部开始,从窗口右侧开始大小的一半。
  • 第四帧(右下(:窗口上的剩余空间。

下面,我为该问题添加了一个简单的简约代码。为了简单起见,我使用了相同的 FRAME 类并创建了 4 个要添加到主窗口中的此类实例。我使用 Tkinter 的网格管理器来组织框架中的小部件,然后再次使用网格管理器将这些框架打包到主窗口中。

import Tkinter as tk 
# Test frame class. The same frame is used to create 4 instances. 
class TestFrame(tk.Frame): 
def __init__(self, master=None, *args, **kwargs):
tk.Frame.__init__(self, *args, **kwargs)
super().__init__(master)

# Test Entry fields
test_label_1                = tk.Label(master, text="Test Label 1").grid(row=0, column=0)
test_label_1_entry          = tk.Entry(master, bd=5).grid(row=0, column=1)
test_label_2                = tk.Label(master, text="Test Label 2").grid(row=0, column=2)
test_label_2_entry          = tk.Entry(master, bd=5).grid(row=0, column=3)

# Test checkbox fields
test_checkbox_1_label       = tk.Label(master, text="Test check button 1").grid(row=2, column=0)
test_checkbox_1_entry       = tk.Checkbutton(master, bd=5).grid(row=2, column=1)
test_checkbox_2_label       = tk.Label(master, text="Test check button 2").grid(row=2, column=2)
test_checkbox_2_entry       = tk.Checkbutton(master, bd=5).grid(row=2, column=3)

# Test dropdowns
test_dropdown_label         = tk.Label(master, text="Test dropdown 1").grid(row=3, column=0)
list_of_options             = ["first option", "second option", "third option", "forth option"]
first_option                = tk.StringVar(master)
first_option.set(list_of_options[0])
test_dropdown_label         = tk.OptionMenu(master, first_option, *list_of_options).grid(row=3, column=1)
test_dropdown_label         = tk.Label(master, text="Test dropdown 1").grid(row=3, column=0)
list_of_options             = ["first option", "second option", "third option", "forth option"]
first_option                = tk.StringVar(master)
first_option.set(list_of_options[0])
test_dropdown_label         = tk.OptionMenu(master, first_option, *list_of_options).grid(row=3, column=1)
pass 

pass
class TestMainApplication(tk.Frame):
def __init__(self, master, *args, **kwargs):
tk.Frame.__init__(self, master, *args, **kwargs)
super().__init__(master)
title                       = "Test Application"
self.grid()
# Assign the weight to each row and column as 1. This is required to align the parameters in grid.
for r in range(3):
self.master.rowconfigure(r, weight=1)    
for c in range(8):
self.master.columnconfigure(c, weight=1)

self.master.title(title)

# Add two instances of the class TestFrame
self.testFrame1            = TestFrame(master)
self.testFrame2            = TestFrame(master)
self.testFrame3            = TestFrame(master)
self.testFrame4            = TestFrame(master)
self.testFrame1.grid(row=0, column=0, rowspan=3, columnspan=3, sticky=tk.W+tk.E+tk.N+tk.S)
self.testFrame2.grid(row=3, column=0, rowspan=3, columnspan=3, sticky=tk.W+tk.E+tk.N+tk.S)  
self.testFrame3.grid(row=0, column=3, rowspan=2, columnspan=3, sticky=tk.W+tk.E+tk.N+tk.S)
self.testFrame4.grid(row=2, column=3, rowspan=4, columnspan=3, sticky=tk.W+tk.E+tk.N+tk.S)

pass 
pass 

# Main application is created here. 
root                   = tk.Tk()
mainApplication        = TestMainApplication(root)
root.mainloop()

我希望在运行此代码后,一个窗口会分成 4 个部分,按上述格式组织。但是,我看到的是所有帧彼此重叠。

环境: MacOS, tkinter 8.6, python 3.6.7

好的,这里有一些问题。

  1. 你的代码有点混乱。请考虑使用 PEP8 标准。链接在这里

  2. 如果要对框架使用类固有性,为什么不对根窗口执行相同的操作。我已经编辑了您的代码以继承Tk().

  3. 重叠的原因是,在TestFrame类中,您告诉小部件它们属于master而不是self(即TestFrame类本身(。要更正此问题,只需将测试帧中的所有master调用替换为self

  4. 您同时使用tk.Frame.__init__(self)super().__init__(master)。在使用这种固有性时,您实际上只需要使用super().__init__()

请参阅下面的示例代码:

import tkinter as tk

class TestFrame(tk.Frame):
def __init__(self):
super().__init__()
list_of_options = ["first option", "second option", "third option", "forth option"]
first_option = tk.StringVar(self)
first_option.set(list_of_options[0])
tk.Label(self, text="Test Label 1").grid(row=0, column=0)
tk.Entry(self, bd=5).grid(row=0, column=1)
tk.Label(self, text="Test Label 2").grid(row=0, column=2)
tk.Entry(self, bd=5).grid(row=0, column=3)
tk.Label(self, text="Test check button 1").grid(row=2, column=0)
tk.Checkbutton(self, bd=5).grid(row=2, column=1)
tk.Label(self, text="Test check button 2").grid(row=2, column=2)
tk.Checkbutton(self, bd=5).grid(row=2, column=3)
tk.Label(self, text="Test drop down 1").grid(row=3, column=0)
tk.OptionMenu(self, first_option, *list_of_options).grid(row=3, column=1)

class TestMainApplication(tk.Tk):
def __init__(self):
super().__init__()
self.title("Test Application")
for r in range(3):
self.rowconfigure(r, weight=1)
for c in range(8):
self.columnconfigure(c, weight=1)
self.testFrame1 = TestFrame()
self.testFrame2 = TestFrame()
self.testFrame3 = TestFrame()
self.testFrame4 = TestFrame()
self.testFrame1.grid(row=0, column=0, rowspan=3, columnspan=3, sticky='nsew')
self.testFrame2.grid(row=3, column=0, rowspan=3, columnspan=3, sticky='nsew')
self.testFrame3.grid(row=0, column=3, rowspan=2, columnspan=3, sticky='nsew')
self.testFrame4.grid(row=2, column=3, rowspan=4, columnspan=3, sticky='nsew')

TestMainApplication().mainloop()

最新更新