[英]How to properly access class functions from another Class python
Say I have a collection of classes using Tkinter: 说我有一些使用Tkinter的类的集合:
class MAIN(tk.Tk):
def __init__(self, *args):
...
class Page1(tk.Frame): #Login page Frame
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
...
def Method(self):
...
class Page2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
...
Say Page2
needs to use Method(self)
from Page1
, how would it be designed? 说Page2
需要使用Page1
Method(self)
,它将如何设计? Assuming that we have Tkinter frames, each frame is written in a class format with all the frames initiated in the MAIN
class. 假设我们有Tkinter帧,则每个帧都以类格式编写,而所有帧都在MAIN
类中启动。
What I am trying to do, for a while now with no success, is to get my main menu page to update it's List Box which takes and displays arguments from a database. 我试图做的一段时间(现在没有成功)是让我的主菜单页面更新它的列表框,该列表框接受并显示数据库中的参数。 For example, When I insert another row in the db using Page2
it has to bring me back to Page1
, However, Page1
is static and does not update. 例如,当我使用Page2
在数据库中插入另一行时,必须将我带回到Page1
,但是, Page1
是静态的,不会更新。 I'm learning UI, and stuck on this for days now. 我正在学习UI,现在已经坚持了好几天。 I have a function that deletes the list box arguments, and a function to display arguments again, But, they are in Page1
and once I raise Page1
back up from Page2
, Page1
won't update arguments. 我有一个删除列表框参数的函数,以及一个再次显示参数的函数,但是,它们在Page1
,一旦我将Page1
从Page2
备份回来, Page1
就不会更新参数。
EDIT: This is the Class with the method I need to use elsewhere (Continue below) 编辑:这是类与我需要在其他地方使用的方法(下面继续)
class mainMenuPage(tk.Frame): #Main Menu Frame, consists of the main navigation page, List box
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
self.listBox()
#self.listBox_delete(numrow)
self.label = tk.Label(self, text="Search employee by typing his/her last name:")
self.label.grid(row=0, column=1)
self.entry_username = tk.Entry(self)
self.entry_username.grid(row=0, column=3)
button = tk.Button(self, text='Add Employee', width=15,
command=lambda: (controller.clear_shared_data(), controller.raise_frame(addEmpFrame)))
button.grid(row=2, column=3)
button = tk.Button(self, text='Remove Employee', width=15, command=lambda: controller.raise_frame(removeEmpFrame))
button.grid(row=3, column=3)
button = tk.Button(self, text='Employee Lookup', width=15, command=lambda: controller.raise_frame(EmpLookupFrame))
button.grid(row=4, column=3)
button = tk.Button(self, text='Calculate Pay Roll', width=15, command=lambda: controller.raise_frame(calcPayRollFrame))
button.grid(row=5, column=3)
def listBox(self):
self.row = []
self.scrollbar = tk.Scrollbar(self)
self.scrollbar.grid(row=2, column=2)
connection: Connection = pymysql.connect(host='localhost',
port=3306,
user='root',
password='root',
db='hrdb')
cursorObject = connection.cursor()
cursorObject.execute('SELECT `firstName`,`lastName` from `employeeprofile`')
numrows = int(cursorObject.rowcount)
for x in range(0, numrows):
self.row.append(cursorObject.fetchone())
self.list1 = tk.Listbox(self, height=10, width=35)
for x in self.row:
self.list1.insert(END, x)
self.list1.grid(row=2, column=0, columnspan=2)
self.scrollbar.config(command=self.list1.yview)
return numrows
def listBox_delete(self, numrow):
self.list1 = tk.Listbox(self, height=10, width=35)
for x in range(0, numrow):
self.list1.delete('0', 'end')
self.list1.grid(row=2, column=0, columnspan=2)
self.list1 = tk.Listbox(self, height=10, width=35)
The class, which is a Frame of my UI, is basically a main menu navigator with a list box of values from mySQL. 该类是UI的框架,基本上是一个主菜单导航器,带有来自mySQL的值的列表框。 The problem here, is after using any other Frame or operation within the program which leads me back to the main menu, the program wont update the List Box list1
, ie when I add an employee
into the system, the new employee shows in the list box only after I restart the app. 这里的问题是,在程序中使用任何其他Frame或操作将其带回到主菜单之后,该程序将不会更新列表框list1
,即,当我向系统中添加employee
,新员工会显示在列表中仅在我重新启动应用程序后打开框。 (The methods work with the db). (这些方法适用于db)。 I know the reason is the frame is static, and my list box is created once and nothing is manipulated since, but, I can't find a way to basically generate the list box every time the frame is called, and in turn get all the values from the db again to update the list box. 我知道原因是框架是静态的,并且我的列表框仅创建一次,此后没有任何操作,但是,我找不到一种基本上在每次调用框架时都生成列表框并反过来得到所有列表框的方法再次从数据库中更新值以更新列表框。
The only way to reference one frame from the other is through the controller. 从另一帧参考另一帧的唯一方法是通过控制器。 Consider this example: 考虑以下示例:
import tkinter as tk
class MAIN(tk.Tk):
def __init__(self, *args):
tk.Tk.__init__(self)
container = tk.Frame(self)
container.pack(side="top", fill="both", expand=True)
self.frames = {}
for F in (Page1, Page2):
page_name = F.__name__
frame = F(parent=container, controller=self)
self.frames[page_name] = frame
frame.grid(row=0, column=0, sticky="nsew")
def show_frame(self, page_name):
frame = self.frames[page_name]
frame.tkraise()
def get_frame(self, page_name):
frame = self.frames[page_name]
return frame
class Page1(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
tk.Label(self, text='Page 1').pack()
def Method(self):
print('Page 1 method')
class Page2(tk.Frame):
def __init__(self, parent, controller):
tk.Frame.__init__(self, parent)
self.controller = controller
tk.Label(self, text='Page 2').pack()
tk.Button(self, text='Raise Page 1 and execute function', command=self.exit).pack()
def exit(self):
self.controller.show_frame("Page1")
self.controller.get_frame("Page1").Method()
app = MAIN()
app.mainloop()
Page1
has no reference to Page2
but it does have controller
which is a reference to the instance of MAIN
. Page1
没有对Page2
引用,但是它确实具有对MAIN
实例的引用的controller
。 Because MAIN
is the controller, it "knows" all the frames. 因为MAIN
是控制器,所以它“知道”所有帧。 I gave MAIN
the get_frame
method that returns a reference to the frame by its name. 我给MAIN
的get_frame
方法通过其名称返回对框架的引用。 Therefore, to reference Page1
from any other frame, you can do self.controller.get_frame("Page1")
. 因此,要从任何其他框架引用Page1
,可以执行self.controller.get_frame("Page1")
。 To then call method Method()
, simply add that to make self.controller.get_frame("Page1").Method()
然后调用方法Method()
,只需将其添加为self.controller.get_frame("Page1").Method()
Because you haven't shown your actual main class, I'm not sure on how you save references to your frames, but I think you used this as a start. 因为您尚未显示实际的主类,所以我不确定如何保存对框架的引用,但是我认为您以此为起点。 From my example I think the concept should be clear. 从我的例子中,我认为这个概念应该很清楚。
Another way to accomplish what you want would be to make sure a method is called every time Page1
is made visible, to do this follow the explanation in the answer to How would I make a method which is run every time a frame is shown in tkinter . 完成您想要的操作的另一种方法是确保每次使Page1
可见时都调用一个方法,为此请按照“ 如何使每次在tkinter中显示框架时都运行的方法 ”答案中的解释进行操作。 。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.