Python 3.7 PyQt5 跨窗口传递self调用模块函数的实现方法
fun1 函数依赖传入参数对象携带ui.lblTest属性。当前窗口2的返回按钮回调中直接传入了窗口2自身的self对象,而窗口2的UI定义中不存在该标签组件,因此触发属性缺失的报错。要实现函数调用时使用窗口1的实例,只需将窗口1的引用显式传递给窗口2,让窗口2调用函数时传入正确的实例即可。
修改主窗口打开配置窗口的传参逻辑
对应template/main.py的openConfig方法,原代码创建ConfigScreen实例时未传入主窗口引用,修改为将当前主窗口实例作为参数传入:def openConfig(self): # 传入当前主窗口实例给设置窗口 self.config = ConfigScreen(main_window=self) self.config.show()修改设置窗口的初始化逻辑,接收并存储主窗口引用
对应template/config.py的ConfigScreen类,修改__init__方法的入参,接住外部传入的主窗口对象并存为实例属性:class ConfigScreen(QMainWindow): # 新增main_window入参,接住从主窗口传来的实例 def __init__(self, main_window, *args, **argsv): super(ConfigScreen,self).__init__(*args,**argsv) # 存储主窗口实例,后续可直接访问 self.main_window = main_window self.ui = Ui_window2() self.ui.setupUi(self) self.ui.btnReturn.clicked.connect(self.returnMain)修改设置窗口回调内的函数传参
原returnMain方法中传入的是窗口2自身的self,现在改为传入之前存储的主窗口实例:def returnMain(self): # 传入主窗口实例而非当前窗口的self fun1(self.main_window) self.close()清理冗余导入避免循环依赖
对应modulos/functions.py,删除文件顶部多余的from template import main导入。这行导入会造成模块循环引用,且fun1本身不需要依赖主窗口模块的具体实现,只要传入的对象具备对应的ui.lblTest属性即可正常运行:from PyQt5.QtWidgets import * def fun1(self): lbl = int(self.ui.lblTest.text()) lbl = (lbl+1) self.ui.lblTest.setText(str(lbl))
修改完成后,无论在主窗口初始化阶段调用fun1,还是在设置窗口点击返回按钮时触发fun1,传入的都是携带lblTest标签的主窗口实例,不会再触发Ui_window2对象缺少属性的报错,标签数值更新逻辑会正常作用在窗口1的标签组件上。
内容的提问来源于stack exchange,提问作者Maurício Morhy

