QtCore.pyqtSignal 信号传递
在 PyQt6 里的元件,都是透过信号的传递进行沟通和互动,虽然大部分的元件都有 connect 接收消息的机制,但也可以使用 QtCore.pyqtSignal 的方式自订信号进行传递,这篇教学会介绍相关用法。
快速导览:
因为 Google Colab 不支援 PyQt6,所以请使用本机环境 ( 参考:使用 Python 虚拟环境 ) 或使用 Anaconda Jupyter 进行实作 ( 参考:使用 Anaconda )。
开始使用 QtCore.pyqtSignal
首先使用 pyqtSignal() 建立 pyqtSignal 对象,接着透过 emit() 方法发送信号,使用 connect() 方法监听是否有信号,下方程序码执行后,按下按钮时就会发送信号,并在后台印出收到信号的文字。
QtCore.pyqtSignal 仅支援 class 写法。
from PyQt6 import QtWidgets
from PyQt6.QtCore import pyqtSignal
import sys
class mainWindow(QtWidgets.QWidget):
signal = pyqtSignal() # 建立信號物件
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
self.signal.connect(self.signalListener) # 監聽信號
def ui(self):
self.btn = QtWidgets.QPushButton(self)
self.btn.setText('發送信號')
self.btn.setGeometry(50,60,100,30)
self.btn.clicked.connect(lambda:self.signal.emit()) # 發送信號
def signalListener(self):
print('收到信號')
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = mainWindow()
Form.show()
sys.exit(app.exec())
QtCore.pyqtSignal 支援的信号类型
QtCore.pyqtSignal 可以在定义对象时,指定发送特定类型的信号,常见定义类型的方式如下:
| 定义类型 | 说明 |
|---|---|
| pyqtSignal() | 无参数信号。 |
| pyqtSignal(int) | int 类型参数的信号。 |
| pyqtSignal(int, str) | int 和 str 类型参数的信号。 |
| pyqtSignal(list) | list 类型参数的信号。 |
| pyqtSignal([int, str], str) | 多重类型参数的信号。 |
将程序修改成 QtCore.pyqtSignal 方式
参考“QPushButton 按钮”文章范例,建立具有 QLabel 和 QPushButton 的视窗,程序执行后,点击不同的按钮时,QLabel 就会显示不同的文字。
from PyQt6 import QtWidgets
import sys
class MyWidget(QtWidgets.QWidget):
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
def ui(self):
self.label = QtWidgets.QLabel(self)
self.label.setText('A')
self.label.setStyleSheet('font-size:20px;')
self.label.setGeometry(50,30,100,30)
self.btn2 = QtWidgets.QPushButton(self)
self.btn2.setText('B')
self.btn2.setGeometry(110,60,50,30)
self.btn2.clicked.connect(lambda:self.showMsg('B')) # 使用 lambda 函式
self.btn1 = QtWidgets.QPushButton(self)
self.btn1.setText('A')
self.btn1.setGeometry(50,60,50,30)
self.btn1.clicked.connect(lambda:self.showMsg('A')) # 使用 lambda 函式
def showMsg(self, e):
self.label.setText(e)
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
上述的程序码里,按钮的点击事件 ( clicked ) 使用了 connect 方法产生点击事件的插槽 ( Slot ),当点击事件发生时在背后会发送信号 signal,当插槽 slot 收到信号时,就会执行对应的动作 ( 函数 ),但信号的传递仅限于绑定的元件,没有办法跨出元件的范围 ( 例如不同视窗沟通、不同函数之间沟通...等 ),这时如果使用 QtCore.pyqtSignal,就可以自订发送的信号,只要放置接收信号的插槽接收到信号,就可以执行对应的动作。
了解原理后,就可将上述的程序码改变成 pyqtSignal 的做法,也会得到相同的结果:
from PyQt6 import QtWidgets
from PyQt6.QtCore import pyqtSignal
import sys
class MyWidget(QtWidgets.QWidget):
signal = pyqtSignal(str) # 建立 pyqtSignal 物件,傳遞字串格式內容
def __init__(self):
super().__init__()
self.setWindowTitle('oxxo.studio')
self.resize(300, 200)
self.ui()
self.signal.connect(self.showMsg) # 建立插槽監聽信號
def ui(self):
self.label = QtWidgets.QLabel(self)
self.label.setText('A')
self.label.setStyleSheet('font-size:20px;')
self.label.setGeometry(50,30,100,30)
self.btn2 = QtWidgets.QPushButton(self)
self.btn2.setText('B')
self.btn2.setGeometry(110,60,50,30)
self.btn2.clicked.connect(lambda:self.signal.emit('B')) # 發送字串信號 B
self.btn1 = QtWidgets.QPushButton(self)
self.btn1.setText('A')
self.btn1.setGeometry(50,60,50,30)
self.btn1.clicked.connect(lambda:self.signal.emit('A')) # 發送字串信號 A
def showMsg(self, val):
self.label.setText(val) # 顯示內容
if __name__ == '__main__':
app = QtWidgets.QApplication(sys.argv)
Form = MyWidget()
Form.show()
sys.exit(app.exec())
微信扫码关注
抖音扫码关注