[英]How to call a function that contains a function in a different class?
I am using Tkinter in Python 3, and have two windows, each represented by a class.我在 Python 3 中使用 Tkinter,并且有两个 windows,每个都由 ZA2F2ED4F8EBC2ABCBBD4C 表示。 I need to click a button in WindowB (my second class) that runs a method from WindowA (my first class).
我需要单击 WindowB(我的第二类)中的一个按钮,该按钮运行 WindowA(我的第一类)中的方法。 This should be fine, however the method I am calling calls another method from WindowA (my first class).
这应该没问题,但是我正在调用的方法从 WindowA (我的第一个类)调用另一个方法。 This results in the error: AttributeError: 'WindowB' object has no attribute 'functionB'.
这会导致错误:AttributeError: 'WindowB' object has no attribute 'functionB'。 How would I fix this so I can run functionA in WindowB (2nd class) with no errors?
我将如何解决这个问题,以便我可以在 WindowB(第二类)中运行 functionA 而没有错误? Code:
代码:
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()
The most common solution is to pass the instance of WindowA
when creating WindowB
, so that the latter can access methods in the former.最常见的解决方案是在创建
WindowA
时传递WindowB
的实例,以便后者可以访问前者中的方法。
First, make sure that WindowB
can accept the name of the other window:首先,确保
WindowB
可以接受另一个 window 的名称:
class WindowB(Toplevel):
def __init__(self, master = None, windowA=None):
Toplevel.__init__(self, master)
self.master = master
self.windowA=windowA
self.Window()
Next, pass self
as the windowA
parameter when creating the instance of WindowB
.接下来,在创建
WindowB
的实例时将self
作为windowA
参数传递。 I renamed object
to self
since you're passing a class rather than an instance of the class:我将
object
重命名为self
因为您传递的是 class 而不是 class 的实例:
class WindowA(Frame):
...
def changeWindow(self, cls):
root.withdraw()
currentFrame = cls(root, windowA=self)
You can then use self.windowA
to call any method in that object:然后,您可以使用
self.windowA
调用 object 中的任何方法:
class WindowB(Toplevel):
...
def Window(self):
...
button3 = Button(self, text = 'Run Function A', command = lambda:self.windowA.functionA())
...
As an alternative answer, you could use the classmethod
decorator:作为替代答案,您可以使用
classmethod
装饰器:
def functionA(self):
print("I am function A.")
WindowA.functionB()
@classmethod
def functionB(cls):
print("I am function B, called from function A.")
Note I am calling WindowA.functionB()
注意我正在调用
WindowA.functionB()
You're almost there, you only need to change just one thing in tge Window()
method of class WindowB
.您快到了,您只需在 class WindowB 的
WindowB
Window()
方法中更改一件事。 You need to change it to be like so:您需要将其更改为:
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))
you have to create instance from WindowA class to use WindowA function您必须从 WindowA class 创建实例才能使用 WindowA function
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)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.