将 class 传递给函数并发症

Passing a class to functions complications

我正在用 tkinter 编写 python 程序,但我 运行 遇到了一些我不知道该如何处理的并发症。

更新:演示问题的功能代码

import tkinter as tk

class MainApp(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)

        self.label = tk.Label(self, text='Schedule')
        self.label.pack()

        self.mtp_enter = False
        self.enter_small_shifts = False

        self.Button_Frame = Button_Frame(self)
        self.widgets = self.Button_Frame.New()
        self.Button_Frame.pack()

    def toggle_enter_small_shifts():
        if self.enter_small_shifts == False:
            if self.mtp_enter == True:
                self.toggle_mtp_enter()
            self.label.configure(text='MTP')
            self.enter_small_shifts = True
        else:
            self.label.configure(text='schedule')
            self.enter_small_shifts = False

    def toggle_mtp_enter():
        if self.mtp_enter == False:
            if self.enter_small_shifts == True:
                self.toggle_enter_small_shifts()
            self.label.configure(text='MTP')
            self.mtp_enter = True
        else:
            self.label.configure(text='schedule')
            self.mtp_enter = False

if __name__ == "__main__":
    root= tk.Tk()
    root.wm_title("Shelter Schedule Maker")
    app = MainApp(root)
    app.pack()
    root.mainloop()

class Button_Frame(tk.Frame):
    def __init__(self, parent, *args, **kwargs):
        tk.Frame.__init__(self, parent, *args, **kwargs)
        self.parent = parent
    def New(self):
        widgets = {}
        toggle_enter_mtp = tk.Button(self, text='Enter MTP\'s', command=app.toggle_mtp_enter, width=15)
        widgets['enter mtp'] = toggle_enter_mtp
        toggle_enter_mtp.pack()
        toggle_enter_small_shifts = tk.Button(self, text='Enter small shift\'s', command=app.toggle_enter_small_shifts, width=15)
        widgets['enter small shifts'] = toggle_enter_small_shifts
        toggle_enter_small_shifts.pack()
        return widgets

总结:在MainApp之前我需要定义Button_Frame,在Button_Frame之前我需要MainApp实例,在Mainapp实例之前我需要MainApp class。有一个完整的圆圈。

我应该如何调整它才能工作?

您应该将class中的所有方法定义为实例方法,并在class内使用self,在class外使用app

class MainApp(tk.Frame):
    ...
    def toggle_mtp_enter(self):
        if self.enter_mtp == False:
            if self.enter_small_shifts == True:
                self.toggle_enter_small_shifts()
            self.shift_buttons_widgets = self.shift_buttons.Activate_mtp()
    ...
app = MainApp(...)
...
toggle_enter_mtp = tk.Button(self, text='Enter MTP\'s', command=app.toggle_mtp_enter, width=15)
...

理想情况下,Button_Frame 不应依赖全局变量 app。当您创建 Button_frame(如 parent)时,您已经传入了应用程序的一个实例,因此您可以执行如下操作:

class Button_Frame(tk.Frame):
    ...
    def New(self):
        ...
        toggle_enter_mtp = tk.Button(..., command=self.parent.toggle_mtp_enter, ...)
        ...
        toggle_enter_small_shifts = tk.Button(..., command=self.parent.toggle_enter_small_shifts, ...)
        ...

您还需要在创建应用程序之前定义所有 classes:

class MainApp(...):
    ...
class Button_Frame(...):
    ...
if __name__ == "__main__":
    ...