Qt中如何跨类调用函数并共享类方法间的变量?
解决思路与实现方案
嘿,这问题核心就是搞定两个Qt类之间的实例引用和数据传递嘛,给你两种实用的方案,你可以根据项目情况选:
方案一:互相持有实例引用(直接调用)
这种方式适合两个类关系比较紧密的场景,步骤很简单:
- 创建
App和AppWindow实例的时候,让它们互相存好对方的引用; - 在
getText()里拿到用户输入的text后,直接调用AppWindow实例的addItem(),把text当参数传进去; - 改一下
addItem()的定义,让它能接收这个text参数就行。
修改后的代码示例:
class App(QWidget): def __init__(self, app_window): super().__init__() self.app_window = app_window # 保存AppWindow的实例引用 def getText(self): text, okPressed = QInputDialog.getText(self, "Get text", "Your name:", QLineEdit.Normal, "") if okPressed and text != '': wb = openpyxl.load_workbook('hello.xlsx') wb.save(text+ '.xlsx') # 直接调用AppWindow的addItem并传入text self.app_window.addItem(text) class AppWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(AppWindow, self).__init__() self.setupUi(self) # 别忘了这句!不然Qt Designer做的UI加载不出来 self.app = App(self) # 创建App实例时把自己传进去 def addItem(self, text): # 给方法加个text参数 auditdate = self.dateEdit.date() a = auditdate.toPyDate() area = self.lineEdit_Area.text() # 现在就能直接用传进来的text啦 print(f"拿到的用户名:{text},审计日期:{a},区域:{area}")
启动程序的代码补充:
if __name__ == "__main__": import sys app = QApplication(sys.argv) window = AppWindow() window.show() sys.exit(app.exec_())
方案二:用Qt信号槽机制(解耦推荐)
要是不想让两个类绑得太死,Qt的信号槽是更优雅的选择——让App类定义一个信号,拿到text就发射它,AppWindow类把这个信号连到自己的方法上就行,完全不用互相硬持有引用。
修改后的代码示例:
from PyQt5.QtCore import pyqtSignal # 得先导入这个 class App(QWidget): # 定义一个信号,用来传字符串类型的text textReceived = pyqtSignal(str) def __init__(self): super().__init__() def getText(self): text, okPressed = QInputDialog.getText(self, "Get text", "Your name:", QLineEdit.Normal, "") if okPressed and text != '': wb = openpyxl.load_workbook('hello.xlsx') wb.save(text+ '.xlsx') # 发射信号,把text传出去 self.textReceived.emit(text) class AppWindow(QMainWindow, Ui_MainWindow): def __init__(self): super(AppWindow, self).__init__() self.setupUi(self) self.app = App() # 把App的信号和自己的处理方法连起来 self.app.textReceived.connect(self.handleText) def handleText(self, text): # 这里可以直接调用你的addItem逻辑,把text传进去 self.addItem(text) def addItem(self, text): auditdate = self.dateEdit.date() a = auditdate.toPyDate() area = self.lineEdit_Area.text() print(f"处理用户输入:{text},审计日期:{a},区域:{area}")
几个小提醒
- 不管用哪种方案,
AppWindow的__init__里一定要加self.setupUi(self),不然你在Qt Designer里画的界面根本出不来; - 如果
App不是在AppWindow内部创建的,那只要确保能拿到对方的实例(方案一)或者正确连接信号(方案二)就行; - 方案二更适合复杂项目,两个类耦合度低,以后改其中一个的时候,对另一个影响更小,推荐优先考虑这种。
内容的提问来源于stack exchange,提问作者LoneExplorer
相关产品推荐
相关产品推荐

