python - PYQT:如何将自定义信号从主窗口(父)发送到子窗口?
问题描述
如何将信号从父/主窗口发送到子窗口?
例如,我将如何注册并发mainSignal
送到其中一个widgetA
或widgetB
?
from PyQt5 import QtCore, QtGui, QtWidgets
class widgetB(QtWidgets.QWidget):
procDone = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(widgetB, self).__init__(parent)
self.lineEdit = QtWidgets.QLineEdit(self)
self.button = QtWidgets.QPushButton("Send Message to A", self)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.button)
self.button.clicked.connect(self.on_button_clicked)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.procDone.emit(self.lineEdit.text())
@QtCore.pyqtSlot(str)
def on_procStart(self, message):
self.lineEdit.setText("From A: " + message)
self.raise_()
class widgetA(QtWidgets.QWidget):
procStart = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(widgetA, self).__init__(parent)
self.lineEdit = QtWidgets.QLineEdit(self)
self.lineEdit.setText("Hello!")
self.button = QtWidgets.QPushButton("Send Message to B", self)
self.button.clicked.connect(self.on_button_clicked)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.button)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.procStart.emit(self.lineEdit.text())
@QtCore.pyqtSlot(str)
def on_widgetB_procDone(self, message):
self.lineEdit.setText("From B: " + message)
self.raise_()
class mainwindow(QtWidgets.QMainWindow):
mainSignal = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(mainwindow, self).__init__(parent)
self.button = QtWidgets.QPushButton("Click Me", self)
self.button.clicked.connect(self.on_button_clicked)
self.setCentralWidget(self.button)
self.widgetA = widgetA()
self.widgetB = widgetB()
self.widgetA.procStart.connect(self.widgetB.on_procStart)
self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.widgetA.show()
self.widgetB.show()
self.widgetA.raise_()
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
main = mainwindow()
main.show()
sys.exit(app.exec_())
解决方案
逻辑是一样的,这里不管是父母还是孩子等等,只要两个对象都可以同时访问就可以了。信号和槽的设计使得类是独立的。
from PyQt5 import QtCore, QtGui, QtWidgets
class widgetB(QtWidgets.QWidget):
procDone = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(widgetB, self).__init__(parent)
self.lineEdit = QtWidgets.QLineEdit(self)
self.button = QtWidgets.QPushButton("Send Message to A", self)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.button)
self.button.clicked.connect(self.on_button_clicked)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.procDone.emit(self.lineEdit.text())
@QtCore.pyqtSlot(str)
def on_procStart(self, message):
self.lineEdit.setText("From A: " + message)
self.raise_()
@QtCore.pyqtSlot(str)
def on_message_from_main(self, text):
self.lineEdit.setText("From Main: " + text)
class widgetA(QtWidgets.QWidget):
procStart = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(widgetA, self).__init__(parent)
self.lineEdit = QtWidgets.QLineEdit(self)
self.lineEdit.setText("Hello!")
self.button = QtWidgets.QPushButton("Send Message to B", self)
self.button.clicked.connect(self.on_button_clicked)
self.layout = QtWidgets.QHBoxLayout(self)
self.layout.addWidget(self.lineEdit)
self.layout.addWidget(self.button)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.procStart.emit(self.lineEdit.text())
@QtCore.pyqtSlot(str)
def on_widgetB_procDone(self, message):
self.lineEdit.setText("From B: " + message)
self.raise_()
@QtCore.pyqtSlot(str)
def on_message_from_main(self, text):
self.lineEdit.setText("From Main: " + text)
class mainwindow(QtWidgets.QMainWindow):
mainSignal = QtCore.pyqtSignal(str)
def __init__(self, parent=None):
super(mainwindow, self).__init__(parent)
self.button = QtWidgets.QPushButton("Click Me", self)
self.button.clicked.connect(self.on_button_clicked)
self.setCentralWidget(self.button)
self.widgetA = widgetA()
self.widgetB = widgetB()
self.widgetA.procStart.connect(self.widgetB.on_procStart)
self.widgetB.procDone.connect(self.widgetA.on_widgetB_procDone)
self.mainSignal.connect(self.widgetA.on_message_from_main)
self.mainSignal.connect(self.widgetB.on_message_from_main)
@QtCore.pyqtSlot()
def on_button_clicked(self):
self.widgetA.show()
self.widgetB.show()
self.widgetA.raise_()
self.mainSignal.emit("Hello")
if __name__ == "__main__":
import sys
app = QtWidgets.QApplication(sys.argv)
main = mainwindow()
main.show()
sys.exit(app.exec_())
推荐阅读
- python - 仅当单元格为空/null时,如何通过python在谷歌表格中插入一个值
- pine-script - 在 pine 脚本中进行回测
- git - .gitattributes:仅将属性应用于文本
- javascript - 在事件处理程序中找不到从 redux-toolkit 使用Selector 并将参数传递给它的方法
- powershell - PowerShell 在 Get-MailboxFolderStatistics cmdlet Office 365 中对 CSV 输出值进行排序
- c# - EF Core 5:如何使用用于 SELECT 和 INSERT/UPDATE 的 DB 函数自动转换实体属性?
- php - 如何 MYSQLI 选择具有 LIKE 字符串变量列的行?反转MYSQLI通配符?
- regex - 使用 ruby 和正则表达式从字符串中提取键值对
- reactjs - 是否可以在 VS Code 保存时自动重新加载开发工具控制台
- kubernetes - 使用 kubectl 执行将文件中的字符串作为标志传递的命令