信号(Signal)和槽(Slot)是PyQt5中最重要的机制之一,它们用于对象之间的通信。当特定事件发生时,信号会被发射,而槽则是响应这些信号的函数。本文将深入介绍PyQt5中信号与槽的使用方法和高级特性。
信号是在特定事件发生时发出的通知。例如:
槽是响应信号的函数或方法。槽可以是:
import sys
from PyQt5.QtWidgets import QApplication, QWidget, QPushButton
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
btn = QPushButton('关闭窗口', self)
btn.clicked.connect(self.close) # close()是QWidget的内置槽
self.setGeometry(300, 300, 250, 150)
self.setWindowTitle('信号和槽示例')
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
btn = QPushButton('点击我', self)
btn.clicked.connect(self.buttonClicked) # 连接到自定义槽函数
self.setGeometry(300, 300, 250, 150)
def buttonClicked(self):
print('按钮被点击了!')
from PyQt5.QtWidgets import QLineEdit
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
line_edit = QLineEdit(self)
line_edit.textChanged.connect(self.onTextChanged)
def onTextChanged(self, text):
print('文本已更改为:', text)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
btn = QPushButton('点击我', self)
btn.clicked.connect(lambda: self.buttonClicked("自定义参数"))
def buttonClicked(self, parameter):
print('收到参数:', parameter)
from PyQt5.QtCore import pyqtSignal
class CustomSignalWidget(QWidget):
# 定义自定义信号
mySignal = pyqtSignal(str)
mySignalWithMultipleParams = pyqtSignal(str, int)
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
btn = QPushButton('发射信号', self)
btn.clicked.connect(self.emitSignal)
# 连接自定义信号到槽
self.mySignal.connect(self.onSignalReceived)
self.mySignalWithMultipleParams.connect(self.onMultiParamsSignalReceived)
def emitSignal(self):
self.mySignal.emit("Hello Signal!")
self.mySignalWithMultipleParams.emit("Count", 42)
def onSignalReceived(self, value):
print('接收到信号,值为:', value)
def onMultiParamsSignalReceived(self, text, number):
print(f'接收到信号,文本: {text}, 数字: {number}')
from PyQt5.QtCore import Qt
# 默认连接
button.clicked.connect(self.handleClick)
# 直接连接
button.clicked.connect(self.handleClick, Qt.DirectConnection)
# 队列连接
button.clicked.connect(self.handleClick, Qt.QueuedConnection)
# 阻塞队列连接
button.clicked.connect(self.handleClick, Qt.BlockingQueuedConnection)
class Example(QWidget):
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
self.btn = QPushButton('切换连接', self)
self.btn.clicked.connect(self.handleClick)
self.disconnectBtn = QPushButton('断开连接', self)
self.disconnectBtn.clicked.connect(self.toggleConnection)
def toggleConnection(self):
# 断开连接
self.btn.clicked.disconnect(self.handleClick)
def handleClick(self):
print('按钮被点击')
from PyQt5.QtWidgets import (QApplication, QWidget, QVBoxLayout, QPushButton,
QLineEdit, QLabel)
from PyQt5.QtCore import pyqtSignal
class DataWidget(QWidget):
# 定义数据更新信号
dataChanged = pyqtSignal(str, int)
def __init__(self):
super().__init__()
self.initUI()
def initUI(self):
layout = QVBoxLayout()
# 创建输入控件
self.nameEdit = QLineEdit(self)
self.ageEdit = QLineEdit(self)
self.submitBtn = QPushButton('提交', self)
layout.addWidget(QLabel('姓名:'))
layout.addWidget(self.nameEdit)
layout.addWidget(QLabel('年龄:'))
layout.addWidget(self.ageEdit)
layout.addWidget(self.submitBtn)
self.setLayout(layout)
# 连接信号
self.submitBtn.clicked.connect(self.onSubmit)
self.dataChanged.connect(self.onDataChanged)
def onSubmit(self):
name = self.nameEdit.text()
try:
age = int(self.ageEdit.text())
self.dataChanged.emit(name, age)
except ValueError:
print('年龄必须是数字')
def onDataChanged(self, name, age):
print(f'数据已更新 - 姓名: {name}, 年龄: {age}')
# 确保在创建对象后再连接信号
self.button = QPushButton()
self.button.clicked.connect(self.handleClick) # 正确
# 避免重复连接
if not self.button.receivers(self.button.clicked):
self.button.clicked.connect(self.handleClick)
from PyQt5.QtCore import QThread, pyqtSignal
class WorkerThread(QThread):
finished = pyqtSignal(str)
def run(self):
# 执行耗时操作
result = self.doSomeWork()
# 发射信号
self.finished.emit(result)
信号槽使用原则
性能考虑
调试技巧
设计建议
通过合理使用信号和槽机制,我们可以构建出响应迅速、结构清晰的PyQt5应用程序。深入理解和灵活运用这一机制是开发高质量PyQt5应用的关键。