如何调用包含不同类中的函数的函数?



我在Python 3中使用Tkinter,有两个窗口,每个窗口由一个类表示。我需要单击 WindowB(我的第二个类(中的一个按钮,该按钮从 WindowA(我的第一个类(运行方法。这应该没问题,但是我调用的方法调用来自 WindowA(我的第一个类(的另一个方法。这会导致错误:属性错误:"窗口 B"对象没有属性"函数 B"。 我将如何解决此问题,以便我可以在 WindowB(第 2 类(中运行函数 A而没有错误? 法典:

from tkinter import *
from functools import partial
class WindowA(Frame):
def __init__(self, master= None): # initialise Menu
Frame.__init__(self, master) # initialise Frame
self.master = master
self.createWindow() # adds buttons
def createWindow(self):
self.pack(fill = BOTH, expand = 1)
# lambda prevents self.changeWindow from executing before button pressed
button1 = Button(self, text = 'Change to Window B', command = lambda: self.changeWindow(WindowB))
button1.pack(fill = X, padx = 10, pady = 10)
button2 = Button(self, text = 'Run Function A', command = lambda: self.functionA())
button2.pack(fill = X, padx = 10, pady = 10)

def changeWindow(self, object):
root.withdraw()
currentFrame = object(root)
def functionA(self):
print("I am function A.")
self.functionB()
def functionB(self):
print("I am function B, called from function A.")
class WindowB(Toplevel):
def __init__(self, master = None):
Toplevel.__init__(self, master)
self.master = master
self.Window()
def Window(self):
button3 = Button(self, text = 'Run Function A', command = lambda:WindowA.functionA(self))
button3.grid(row = 1, column = 0, padx = 10)
root = Tk()
app = WindowA(root)
root.mainloop()

最常见的解决方案是在创建WindowB时传递WindowA的实例,以便后者可以访问前者中的方法。

首先,确保WindowB可以接受另一个窗口的名称:

class WindowB(Toplevel):
def __init__(self, master = None, windowA=None):
Toplevel.__init__(self, master)
self.master = master
self.windowA=windowA
self.Window()

接下来,在创建WindowB实例时将self作为windowA参数传递。我将object重命名为self,因为您传递的是一个类而不是该类的实例:

class WindowA(Frame):
...
def changeWindow(self, cls):
root.withdraw()
currentFrame = cls(root, windowA=self)

然后,可以使用self.windowA调用该对象中的任何方法:

class WindowB(Toplevel):
...
def Window(self):
...
button3 = Button(self, text = 'Run Function A', command = lambda:self.windowA.functionA())
...

你快到了,你只需要在 tge 中更改一件事Window()WindowB的方法。您需要将其更改为:

button3 = Button(self, text = 'Run Function A', command = lambda:WindowA().functionA())
# instead of 
# button3 = Button(self, text = 'Run Function A', command = lambda:WindowA.functionA(self))

作为替代答案,您可以使用classmethod装饰器:

def functionA(self):
print("I am function A.")
WindowA.functionB()
@classmethod
def functionB(cls):
print("I am function B, called from function A.")

注意我正在打电话WindowA.functionB()

您必须从 WindowA 类创建实例才能使用 WindowA 函数

class WindowB(Toplevel):
def __init__(self, master=None):
Toplevel.__init__(self, master)
self.master = master
self.Window()
self.WindowA = WindowA()  # added here
def Window(self):
button3 = Button(self, text='Run Function A', command=lambda: self.WindowA.functionA())
button3.grid(row=1, column=0, padx=10)

最新更新