【问题标题】:Calling a Method of another class with a lambda expression in python在python中使用lambda表达式调用另一个类的方法
【发布时间】:2019-12-03 10:18:54
【问题描述】:

我正在尝试创建一个带有多个页面的小 GUI。第一页有一个按钮,用于提升第二页并更改第二页上的标签文本。但是,我没有调用应该更改文本的第二页的方法。谁能告诉我,为什么我在调用方法时会出现以下错误:SecondPage.changeLabel()

TypeError:changeLabel() 缺少 1 个必需的位置参数:'self'

更新:

    import tkinter as tk


class ExampleApp(tk.Tk):

    def __init__(self, *args, **kwargs):

        tk.Tk.__init__(self, *args, **kwargs)

        container = tk.Frame(self)
        container.pack()

        self.frames = {}

        for F in (FirstPage, SecondPage):

            frame = F(container, self)

            self.frames[F] = frame

            frame.grid(row=0, column=0, sticky="nsew")
        self.show_frame(FirstPage)

    def show_frame(self, cont):

        frame = self.frames[cont]
        frame.tkraise()

    def get_page(self, frame_class):
        return self.frames[frame_class]


class FirstPage(tk.Frame):


    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        page = controller.get_page(SecondPage)

        self.buttonFP = tk.Button(self, text="Next Page",
                                  command=lambda : [f for f in [page.changeLabel(),
                                                                controller.show_frame(SecondPage)]])
        self.buttonFP.pack()



class SecondPage(tk.Frame):

    def __init__(self, parent, controller):

        tk.Frame.__init__(self, parent)

        self.label = tk.Label(self, text="Test")

        self.label.pack()


    def changeLabel(self):
        """change text of label"""

        newLabel = "changed"
        self.label.configure(text=newLabel)




if __name__ == "__main__":
    app = ExampleApp()
    app.mainloop()

【问题讨论】:

    标签: python-3.x oop tkinter lambda


    【解决方案1】:

    您收到错误是因为您尝试在类而不是类的实例上调用方法。

    由于您的架构具有控制器,您可以修改控制器以具有返回页面实例的功能。然后,您可以使用该实例调用该页面上的方法。

    例子:

    class ExampleApp(tk.Tk):
        ...
        def get_page(self, frame_class):
            return self.frames[frame_class]
    

    以后可以使用该方法获取页面的实例,并使用该实例调用该方法:

    page = self.controller.get_page(SecondPage)
    page.changeLabel()
    

    【讨论】:

    • 感谢您的回复。由于某种原因,您的代码仅在我将创建类的实例并调用其方法(如controller.get_page(SecondPage).changeLabel() within the lamda function)时才起作用。否则我会收到KeyError: <class '__main__.SecondPage'> 你知道这可能是什么原因吗?
    • @Max2603:您可能在创建该页面之前调用了get_page
    • 我根据您的建议更新了上面的代码。我在 FirstPage 类中创建了实例。创建类实例的标准方法是什么?
    • @Max2603:您的代码不会在 FirstPage 类中创建实例。该实例是在循环中创建的,在这一行:frame = F(container, self)。在用户单击按钮之前,您不应尝试获取该页面。为此,您不应该使用lambda。只需创建一个普通函数并让按钮调用该函数。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-07-16
    • 1970-01-01
    相关资源
    最近更新 更多