我正在尝试创建一个具有多个页面的 Tkinter GUI,每个页面显示由不同小部件组成的不同组件。我在处理来自不同对象的网格时遇到问题。
from tkinter import *
import tkinter as tk
class MainWindow(tk.Tk):
def __init__(self):
super().__init__()
MainFrame(self)
#EndClass
class MainFrame(tk.Frame):
""" My pages manager, wich will contain pages and manage how to change them """
def __init__(self, root):
super().__init__(root)
Page()
MainFrame.mainloop(self)
#EndClass
class Lab(tk.Frame):
""" Some element like a button with label, for exemple """
def __init__(self):
super().__init__()
#Would be in fact more than just one element
tk.Label(self, text="AAA", font="Arial 30 bold", bg="red").grid()
#EndClass
class Page(tk.Frame):
""" One page of the application """
def __init__(self):
super().__init__()
Component().grid(row=0, column=0)
#EndClass
class Component(tk.Frame):
""" Functionnal component that could be called in various pages """
def __init__(self):
super().__init__()
#tk.Label(self, text="Label 1", font="Arial 30 bold", bg="red").grid(row=0, column=0, sticky="nswe")
Lab().grid(row=0, column=0, sticky="nswe")
tk.Label(self, text="Label 2", font="Arial 30 bold", bg="blue").grid(row=0, column=1, sticky="nswe")
tk.Label(self, text="Label 3", font="Arial 30 bold", bg="blue").grid(row=1, column=0, sticky="nswe")
tk.Label(self, text="Label 4", font="Arial 30 bold", bg="red").grid(row=1, column=1, sticky="nswe")
#EndClass
MainWindow()
我希望每个页面都有自己的网格,我可以在其中放置我的组件。 同样,我想将元素放置在组件网格中。
我在之前的代码中尝试了许多更改,但无法同时显示 Lab 对象和标签。
问题在于你创建
Lab
和
Component
对象的方式。你直接调用它们的构造函数,而不是将它们作为子部件添加到父部件中。这意味着它们没有被正确地放置到 Tkinter 窗口层次结构中。
为了解决这个问题,你需要在创建
Lab
和
Component
对象时,将它们的父部件作为参数传递给它们的构造函数。然后,在调用
grid
方法放置它们之前,使用
self
将它们添加到父部件中。
以下代码展示了如何修改你的代码来解决这个问题:
from tkinter import *
import tkinter as tk
class MainWindow(tk.Tk):
def __init__(self):
super().__init__()
MainFrame(self)
#EndClass
class MainFrame(tk.Frame):
""" My pages manager, wich will contain pages and manage how to change them """
def __init__(self, root):
super().__init__(root)
self.pack() # 添加这行以确保 MainFrame 显示
Page(self).grid() # 将 Page 添加到 MainFrame
# 不需要在这里调用 mainloop,Tkinter 会自动处理
#EndClass
class Lab(tk.Frame):
""" Some element like a button with label, for exemple """
def __init__(self, parent):
super().__init__(parent)
#Would be in fact more than just one element
tk.Label(self, text="AAA", font="Arial 30 bold", bg="red").grid()
#EndClass
class Page(tk.Frame):
""" One page of the application """
def __init__(self, parent):
super().__init__(parent)
Component(self).grid(row=0, column=0) # 将 Component 添加到 Page
#EndClass
class Component(tk.Frame):
""" Functionnal component that could be called in various pages """
def __init__(self, parent):
super().__init__(parent)
# 将 Lab 添加到 Component
Lab(self).grid(row=0, column=0, sticky="nswe")
tk.Label(self, text="Label 2", font="Arial 30 bold", bg="blue").grid(row=0, column=1, sticky="nswe")
tk.Label(self, text="Label 3", font="Arial 30 bold", bg="blue").grid(row=1, column=0, sticky="nswe")
tk.Label(self, text="Label 4", font="Arial 30 bold", bg="red").grid(row=1, column=1, sticky="nswe")
#EndClass
MainWindow()
在这个修改后的代码中,
Lab
和
Component
类的构造函数现在接受一个
parent
参数,该参数表示它们的父部件。在创建
Lab
和
Component
对象时,我们将
self
作为父部件传递给它们的构造函数。这样,Tkinter 就能够将它们正确地放置到窗口层次结构中,并且你将能够同时看到
Lab
对象和标签。