从 Tkinter Frame 调用函数到另一个 [英] Calling functions from a Tkinter Frame to another

查看:36
本文介绍了从 Tkinter Frame 调用函数到另一个的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个页面,我将在其中显示一些客户的详细信息.因此,我创建了一个名为客户详细信息"的页面,其中包含我需要的所有标签,并将这些标签的文本设置为变量.太糟糕了,它不起作用.标签是在 __init__ 方法中创建的,所以我不能更新"它们,因为 init 只在开始时被调用.所以我的想法是创建一个包含所有标签的新函数,我会在必要时调用该函数……这就是问题所在.我无法调用其他 tk.Frame 中的函数.以下代码是代码的简化版.

I have a page where I'll show some customers details. So I created a page called "customers details" with all the labels that I need and I set the text of these labels as variables. Too bad it doesn't work. The labels are created in the __init__ method so I can't "update" them, becouse the init is called only at the beginning. So what I thought is to create a new function that contains all the labels and I will call that function when I have the necessity...here's the problem. I'm not able to call a function in an other tk.Frame. The following code is a simplified version of the code.

import tkinter as tk
from tkinter import ttk

class Myapp(tk.Tk):

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

        container = ttk.Frame(self, borderwidth=10, relief="sunken", width=200, height=100)
        container.pack(side="top", fill="both", expand=True)
        container.grid_rowconfigure(0, weight=1)
        container.grid_columnconfigure(0, weight=1)

        self.frames = {}
        for F in (HomePage, PageOne):
            frame = F(container, self)
            self.frames[F] = frame
            frame.grid(row=0, column=0, sticky="N,S,E,W")
        self.show_frame(HomePage)

    def show_frame(self, cont):
        frame = self.frames[cont]
        frame.tkraise()


class HomePage(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="HomePage")
        label.pack()
        button1 = ttk.Button(self, text="Quit",
                            command=lambda: quit())
        button1.pack()
        button2 = ttk.Button(self, text="Call Function in the other page/class to show the label",
                            command=lambda: PageOne.function()) # this is to do it from an other class. I can't do this
        button2.pack()
        button3 = ttk.Button(self, text="Page One",
                            command=lambda: controller.show_frame(PageOne))
        button3.pack()


class PageOne(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        label = ttk.Label(self, text="PageOne")
        label.pack()
        button1 = ttk.Button(self, text="Quit",
                            command=lambda: quit())
        button1.pack()
        button2 = ttk.Button(self, text="Call Function, in local it works..",
                            command=lambda: self.function())#this is to do it in local
        button2.pack()
        button3 = ttk.Button(self, text="HomePage",
                            command=lambda: controller.show_frame(HomePage))
        button3.pack()

    def function(self):
        label1 = ttk.Label(self, text="It Worked!")
        label1.pack()


app = Myapp()
app.mainloop()

推荐答案

要调用另一个对象的方法,您需要对该对象的引用.您复制的用于管理不同页面的代码旨在简化此操作,但缺少获取页面实例的函数.

To call a method on another object, you need a reference to the object. The code you copied for managing the different pages is designed to make this easy, but it is missing a function to get the instance of a page.

所以,首先你需要做的是在控制器上添加一个 get_page 方法:

So, the first think you need to do is add a get_page method on the controller:

class Myapp(tk.Tk):
    ...
    def get_page(self, page_class):
        return self.frames[page_class]

通过它,您可以获得页面实例,并且您可以使用页面实例调用该方法.

With that, you can get the page instance, and with the page instance you can call the method.

接下来,您需要保留对控制器的引用,以便您可以从其他函数中调用它:

Next, you need to keep a reference to the controller so that you can call it from other functions:

class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        self.controller = controller
        ...

最后,您现在可以使用控制器获取页面,并且您可以使用该页面调用函数.

Finally, you can now use the controller to get the page, and with the page you can call the function.

我的建议是不要使用 lambda 除非你绝对需要它,在这种情况下你不需要.当您使用适当的函数而不是 lambda 时,编写和调试代码要容易得多.

My recommendation is to not use lambda unless you absolutely need it, and in this case you do not. It's much easier to write and debug your code when you use proper functions instead of lambda.

例如:

class PageOne(tk.Frame):
    def __init__(self, parent, controller):
        ...
        button2 = ttk.Button(..., command=self.do_button)
        ...

    def do_button(self):
        page = self.controller.get_page(PageOne)
        page.function()

这篇关于从 Tkinter Frame 调用函数到另一个的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆