代码之家  ›  专栏  ›  技术社区  ›  mazunki

创建从一个类到另一个类的变量

  •  0
  • mazunki  · 技术社区  · 7 年前

    我目前正在与Tkinter合作完成一项学校作业,为用户创建一个图形用户界面来输入他们的输入。我已经决定将输入分成不同的页面,以避免用户被问题压倒,也不需要滚动。
    每一页都有一系列的标签和条目,在一个左右除数上分开,我已经设法使它在每一页上工作,付出了一些努力。这是我的工作代码的简化版本:

    import tkinter as tk
    
    
    class Layers(tk.Frame):
        def __init__(self, root):
            super().__init__(root)
    
            self.layers = []
    
            self.layers.append(Welcome_Page(self))
            self.layers.append(Form_1(self))
            self.layers.append(Form_2(self))
    
            for layer in self.layers:
                layer.add_form(self)
                layer.add_buttons(self)
                layer.grid(row=0, column=0, sticky="nsew")
    
            self.layers[0].tkraise()
    
    
    class Welcome_Page(tk.Frame):
        def __init__(self, root):
            super().__init__(root, width=600, height=800, background="red")
    
        def add_buttons(self, root):
            self.next = tk.Button(self, text="Next page", width=25, height=5, command=self.master.layers[1].tkraise)
            self.next.place(relx=1, rely=1, anchor="se")
    
            self.prev = tk.Button(self, text="Quit", width=25, height=5, command=self.master.master.destroy)
            self.prev.place(relx=0, rely=1, anchor="sw")
            pass
    
        def add_form(self, root):
            self.text_label = tk.Label(self, text="Welcome to this program")
            self.text_label.place(relx=0.5, rely=0, anchor="n")
            pass
    
    
    
    class Form_1(tk.Frame):
        def __init__(self, root):
            super().__init__(root, width=600, height=800, background="yellow")
    
        def add_buttons(self, root):
            self.next = tk.Button(self, text="Next page", width=25, height=5, command=self.master.layers[2].tkraise)
            self.next.place(relx=1, rely=1, anchor="se")
    
            self.prev = tk.Button(self, text="Back", width=25, height=5, command=self.master.layers[0].tkraise)
            self.prev.place(relx=0, rely=1, anchor="sw")
            pass
    
        def add_form(self, root):
            self.text_label = tk.Label(self, text="Personal data")
            self.text_label.place(relx=0.5, rely=0, anchor="n")
    
            self.container_left = tk.Frame(self, background="#BAFFCE")
            self.container_right = tk.Frame(self, background="#72FF9A")
            self.container_left.grid(row=0, column=0, sticky="nsew")
            self.container_right.grid(row=0, column=1, sticky="nsew")
            self.grid_columnconfigure(0, weight=1, uniform="group1")
            self.grid_columnconfigure(1, weight=1, uniform="group1")
            self.grid_rowconfigure(0, weight=1)
    
            self.last_name_label = tk.Label(self.container_right, text="Last name")
            self.last_name_space = tk.Entry(self.container_right, text="lastname")
            self.last_name_label.grid(row=0, column=0, padx=(10,0), pady=(10,0))
            self.last_name_space.grid(row=0, column=1, padx=(5, 0), pady=(10,0))
    
            pass
    
    
    class Form_2(tk.Frame):
        def __init__(self, root):
            super().__init__(root, width=600, height=800, background="gray")
    
        def add_buttons(self, root):
            self.next = tk.Button(self, text="Next page", width=25, height=5)
            self.next.place(relx=1, rely=1, anchor="se")
    
            self.prev = tk.Button(self, text="Back", width=25, height=5, command=self.master.layers[1].tkraise)
            self.prev.place(relx=0, rely=1, anchor="sw")
            pass
    
        def add_form(self, root):
            self.text_label = tk.Label(self, text="Third page")
            self.text_label.place(relx=0.5, rely=0, anchor="n")
            pass
    
    
    if __name__ == '__main__':
        root = tk.Tk()
        root.geometry("600x800")
    
        window = Layers(root)
        window.pack(expand=True, fill="both")
        root.mainloop()
    

    不过,在将每个页面拆分为两个不同的frame()容器时,我偶然发现了两个问题:

    • 用ipadx和ipady设置帧的内部填充似乎没有任何作用。不过,我已经用padx和pady手动地将其中的每个元素设置在它的位置,这很好,但我相信我应该能够在container_left和container_right上使用内部填充。
    • 为每个页面设置容器是多余的,因为它们都将被分成两个框架。我试过下面的方法,但没有达到我的预期(一点也没有)。
    class Layers(tk.Frame):
        def __init__(self, root):
            super().__init__(root)
    
            self.layers = []
    
            self.layers.append(Welcome_Page(self))
            self.layers.append(Form_1(self))
            self.layers.append(Form_2(self))
    
            for layer in self.layers:
                layer.add_form(self)
                layer.add_buttons(self)
                layer.grid(row=0, column=0, sticky="nsew")
    
                layer.container_left = tk.Frame(layer, background="#BAFFCE")
                layer.container_right = tk.Frame(layer, background="#72FF9A")
                layer.container_left.grid(row=0, column=0, sticky="nsew")
                layer.container_right.grid(row=0, column=1, sticky="nsew")
                layer.grid_columnconfigure(0, weight=1, uniform="group1")
                layer.grid_columnconfigure(1, weight=1, uniform="group1")
                layer.grid_rowconfigure(0, weight=1)
    
                print(layer)
    
            self.layers[0].tkraise()
    

    我得到的错误是 AttributeError: 'Form_1' object has no attribute 'container_right' . 我从中得到的是,我没有在类中创建变量,而是在另一个地方创建变量,即使我正在使用 layer. . 如何在类内创建变量,而不重用代码?

    我对python和tkinter还不太熟悉,所以我也很欣赏其他的建议。

    1 回复  |  直到 7 年前
        1
  •  0
  •   Sun Bear    7 年前

    你可以看到 ipadx ipady 在第一个代码中,将第17行更改为:

    layer.grid(row=0, column=0, sticky="nsew", ipadx=30, ipady=30,)