如何将一个模块内的类中的 pyqtSignal 连接到另一个模块内的类中的 pyqtSlot?
Posted
技术标签:
【中文标题】如何将一个模块内的类中的 pyqtSignal 连接到另一个模块内的类中的 pyqtSlot?【英文标题】:How to connect a pyqtSignal from a class inside one module to a pyqtSlot in a class inside another module? 【发布时间】:2020-07-13 18:47:14 【问题描述】:我有一个文件wizard.py
:
class MyWizard(QWizard):
def __init__(self):
super().__init__()
# ...
class PageOne(QWizardPage):
def __init__(self):
super().__init__()
# ...
class FinalPage(QWizardPage):
populateTable = pyqtSignal()
def __init__(self):
super().__init__()
# ...
def initializePage(self):
finish_button = self.wizard().button(QWizard.FinishButton)
finish_button.clicked.connect(self.populateTable.emit)
还有另一个文件main_ui.py
:
import wizard
class UiMainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.table = QTableView(self)
# ...
self.my_wizard = wizard.MyWizard()
self.my_wizard.exec_()
# ...
self.final_page = wizard.FinalPage()
self.final_page.connect(self.populate_table)
@pyqtSlot()
def populate_table(self):
# fill some data into self.table
main_ui
模块导入wizard
模块并启动向导。
启动向导后,我想在每次单击向导的完成按钮时在最后一页关闭向导时调用main_ui.py
中的populate_table()
方法。
我尝试从向导发出pyqtSignal()
并将其连接到UiMainWindow
的populate_table()
方法,但它似乎没有收到信号。我在populate_table()
上使用了@pyqtSlot()
装饰器,但这也不起作用。
但是,从我连接到populate_table()
的自定义类内部 main_ui.py
发出信号可以正常工作。但是没有收到来自wizard.py
内部类的信号。
我的问题:
有没有办法将来自一个模块中的类的信号连接到另一个模块中的类的方法?
【问题讨论】:
“发出一个`pyqtSignal()”是什么意思?我在您的课程中没有看到任何 pyqtSignal 声明。 Qt 信号必须在类定义中声明。 我已经编辑了我的问题。 @Joey 更改为self.final_page.populateTable.connect(self.populate_table)
@Joey 连接语法为:sender.signal.connect(obj.slot)
@Joey:在您发布的示例中,self.final_page = wizard.FinalPage()
将创建一个新的FinalPage
实例,该实例独立于self.my_wizard
中的最后一页。您需要将插槽连接到在self.my_wizard
中显示的FinalPage
实例的信号。您最好将信号 populateTable
从 FinalPage
移动到 Wizard
并在 UiMainWindow
中将 self.my_wizard.populateTable
连接到 self.populate_table
。
【参考方案1】:
正如@Heike 所建议的,信号必须定义在MyWizard
而不是FinalPage
。
那么self.my_wizard.populateTable
信号必须连接到UiMainwindow
中的self.populate_table
方法。
想要在FinalPage
中使用finish_button
来发出信号已经是一个坏主意,因为之前我已经将finish_button
与self.wizard().restart()
连接起来,这是必要的,因为向导已执行来自UiMainwindow
。这意味着没有调用self.wizard().restart()
,下次执行时(即FinalPage
)向导将始终在最后一个活动页面上重新生成。
所以,为了发送信号,我现在在FinalPage
的initializePage
方法中调用self.wizard().populateTable.emit()
,然后如上所述在UiMainWindow
中使用populate_table
方法连接它。
我已经相应地重写了代码:
wizard.py
class MyWizard(QWizard):
populateTable = pyqtSignal()
def __init__(self):
super().__init__()
# ...
class PageOne(QWizardPage):
def __init__(self):
super().__init__()
# ...
class FinalPage(QWizardPage):
def __init__(self):
super().__init__()
# ...
def initializePage(self):
# need to keep finish_button connected to self.wizard().restart()
finish_button = self.wizard().button(QWizard.FinishButton)
finish_button.clicked.connect(self.wizard().restart)
# emit the signal when switching to the last page
self.wizard().populateTable.emit()
main_ui.py
import wizard
class UiMainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.table = QTableView(self)
# ...
self.my_wizard = wizard.MyWizard()
self.my_wizard.populateTable.connect(self.populate_table)
# ...
def populate_table(self):
# update the content in self.table
【讨论】:
以上是关于如何将一个模块内的类中的 pyqtSignal 连接到另一个模块内的类中的 pyqtSlot?的主要内容,如果未能解决你的问题,请参考以下文章