【问题标题】:OOP Tkinter Python OOP - From one class how do i run a method in another class?OOP Tkinter Python OOP - 我如何从一个类中运行另一个类中的方法?
【发布时间】:2017-09-02 03:32:04
【问题描述】:

我想要一个带有输入框的框架,当按下它旁边的提交按钮时,它会提交输入并从类ChangedPage 中调用函数Add_Label,该函数被添加到下面,然后引发下一个我希望标签出现的框架。

问题是我希望我调用的函数将小部件添加到第二个类而不是我从中调用它的类。我制作了一个新程序来演示这个问题:

import tkinter as tk

class Creating_Stuff(tk.Tk):

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

        tk.Tk.__init__(self, *args, **kwargs)
        container = tk.Frame(self)


        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 (PageTwo, ChangedPage):

            frame = F(container, self)

            self.frames[F] = frame

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

        self.show_frame(PageTwo)

    def show_frame(self, cont):

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

class PageTwo(tk.Frame):

    def __init__(self, parent, controller):
        tk.Frame.__init__(self, parent)
        global bob

        self.tk_setPalette(background='#bbfff0', foreground='black',
               activeBackground='#d9d9d9', activeForeground='#ff9933')

        self.controller = controller

        title_2 = tk.Label(self, text= "Input Page #frame1", font = "Times 17 underline bold").place(relx = 0.5, rely = 0.1, relwidth = 0.4, anchor="center")

        self.ENTRY = tk.Entry(self,width = 10, bg='white', fg='Black')
        self.ENTRY.place(relx=0.5,rely=0.5,relwidth=0.3,anchor="center")

        self.submit_button_2 = tk.Button(self, text="Submit Request", bg='#f2f2f2', command= self.raising)
        self.submit_button_2.place(relx=0.4,rely=0.6,relwidth=0.2,anchor="center")

        ####Generic Stuff

        Exit = tk.Button(self, text ="Exit",command=lambda:destroy(),bg='#f2f2f2')
        Exit.place(relx=0.5,rely=(9/10), relwidth = 0.4, anchor="center")

    def raising(self):
        #Memes and stuff goes here
        global bob

        bob = self.ENTRY.get()
        ChangedPage.Add_Label(self)

        self.controller.show_frame(ChangedPage)

class ChangedPage(tk.Frame):

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

        ###Main stuff for the frames

        self.title_27 = tk.Label(self, text= "Example Changed Page? #frame2", font = "Times 16 italic underline"
                                 ).place(relx = 0.36, rely = 0.05, relwidth = 0.4, anchor=tk.CENTER)

        ####Generic Stuff
        bk2_Menu2 = tk.Button(self, text="Back to start",
                            command=lambda: controller.show_frame(PageTwo),bg='#f2f2f2')
        bk2_Menu2.place(relx=0.5,rely=(0.8), relwidth = 0.2, anchor="center")


        Exit = tk.Button(self, text ="Exit",command=lambda:destroy(),bg='#f2f2f2')
        Exit.place(relx=0.5,rely=(9/10), relwidth = 0.4, anchor="center")

    def Add_Label(self):

        self.label1 = tk.Label(self, text= bob, font="Times 20")
        self.label1.place(anchor = tk.CENTER, relx = 0.5, rely = 0.5, relwidth = 0.2, relheight = 0.1)

app = Creating_Stuff()
def destroy():
    app.destroy()

app.tk_setPalette(background='#bbfff0', foreground='black',
       activeBackground='#d9d9d9', activeForeground='#ff9933')

app.title("Example Label Adding Program")
app.geometry("800x450")
app.mainloop()

我展示的代码是一个带有输入框的第一页的程序,当您提交它时,它将带您进入下一帧并运行ChangedPage类中的函数,这意味着在页面上制作标签刚刚提出。任何人都可以看到出了什么问题?

起始页在这里:

这里应该去哪里:

【问题讨论】:

  • “如果您不知道我想要什么……请阅读我在这里尝试说的内容!” - 但是为什么呢?我不认为提出一个不清楚和/或难以阅读的问题然后期望我们尝试破译你在说什么是很好的。请花一点时间以易于理解的方式格式化您的问题。这样,人们会更愿意帮助你。
  • 更具体地说,允许其他人重现问题的minimal reproducible example 会很有用。见How to Ask
  • 你不需要等待“下次”,请按照建议edit这个。
  • “在当前类框架中运行”这句话没有多大意义。函数不会“在”类或框架中运行。您可以在类的实例上调用函数。你是这个意思吗?不幸的是,问题出在您的代码中,您没有显示足够的代码让我们重现该问题。根据其他人的建议,请阅读并遵循此处的建议:How to create a Minimal, Complete, and Verifiable Example
  • @DestinyBob 我不确定你的意思。我发布了我之前对您问题的第一个版本的评论。 您的编辑之后,我没有对我对您的问题的理解做出任何解释。话虽如此,在重新阅读您的问题后,您仍然缺少Minimal, Complete, and Verifiable example。没有一个,我们真的无法提供更多。

标签: python class oop user-interface tkinter


【解决方案1】:

第一步是更新您的控制器,使其能够返回页面实例。

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

接下来,您需要调用此函数来获取对之前创建的实例的引用,您可以从中调用方法:

class PageTwo(tk.Frame):
    ...
    def raising(self):
        ...
        changed_page = self.controller.get_page(ChangedPage)
        changed_page.AddLabel()
        ...

【讨论】:

  • 太棒了,对于格式化问题的所有困境感到抱歉,但这有效!非常令人印象深刻,非常感谢,你能为我解释一下代码的第一部分发生了什么吗?感谢一堆已经非常有帮助的
  • @DestinyBob:可以在这里找到解释:stackoverflow.com/a/34301680/7432
  • 非常感谢,非常有帮助
【解决方案2】:

您正在调用一个类方法,没有附加实例可供它使用。

例如,要创建class Creating_Stuff(tk.Tk):,请使用代码

app = Creating_Stuff()

这为您提供了一个名为 appCreating_Stuff 实例。因此你打电话给app.destroy()

可能是您在取出的某些代码中创建了class ChangedPage 的实例,但您没有引用该实例。

在某些时候(可能在PageTwo__init__ 中)你需要类似的东西:

MyWorkingPage = ChangedPage()

然后在def raising(self):

MyWorkingPage.Add_Label()

self.controller.show_frame(MyWorkingPage)

现在代码将显示您要显示的 ChangedPage。

staticmethodclassmethod 这样的东西,但它们不是你想要的。

【讨论】:

  • 问题中的代码中,已经有ChangedPage的实例;你不应该创建一个新实例。
  • 但我在你的回答中注意到你完全按照我告诉他的去做 - 创建一个实例来引用。
  • 不,你误解了代码。我没有创建实例。就像我在回答中所说的那样,一个实例已经存在。我的回答只是获得对现有实例的引用。这是一个显着的差异。
  • 是的,差别很大。
猜你喜欢
  • 2019-06-05
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
  • 2019-03-20
  • 1970-01-01
  • 2015-08-26
  • 2013-05-17
  • 1970-01-01
相关资源
最近更新 更多