信号与槽机制就是某个对象A发送一个信号Signal,然后某个接收这个信号的对象B就会执行某个动作,这个动作就是槽函数slot。
连接方式
使用QObject::connect()进行信号与槽的链接,不同形式的连接方式:
- 通用的语法
cpp
QMetaObject::Connection QObject::connect(const QObject *sender, const char *signal, const QObject *reciver, const char *method, Qt::ConnectionType type = Qt::AutoConnection)
使用这种参数形式的语法一般为:
cpp
connect(sender, SIGNAL(signal()), receiver, SLOT(slot()));
- 对于没有重载函数的信号与槽,可以使用下面这种参数的连接方式
cpp
QMetaObject::Connection QObject::connect(const QObject *sender, const QMetaMethod &signal, const QObject *reciver, const QMetaMethod &method, Qt::ConnectionType type = Qt::AutoConnection)
如:
cpp
connect(lineEdit, &QLineEdit::textChanged, this, &widget::on_textChanged);
对于最后一个参数Qt::ConnectionType type,缺省值为Qt::AutoConnection。这个参数表示了信号与槽之间的关联方式。
| 类型 | 关联方式 |
|---|---|
| Qt::AutoConnection | 如果sender和reciver在同一个线程,就使用Qt::DirectConnection方式;否则使用Qt::QueuedConnection方式,在信号发射时自动确定关联方式。 |
| Qt::DirectConnection | 信号被发射时槽函数立刻执行,槽函数与信号在同一个线程。 |
| Qt::QueuedConnection | 在事件循环回到接收者线程后执行槽函数,槽函数与信号在不同线程。 |
| Qt::BlockingQueuedConnection | 信号线程被阻塞直到槽函数执行完毕。当信号与槽函数在同一个线程使绝对不能使用这种方式,否则会造成死锁。 |
获取信号发送者
在槽函数中,可以使用QObject::sender()获取信号发射者的指针。如果知道信号发射者的类型,可以将指针投射为确定的类型,然后使用这个确定类的接口函数。
例如,在QSpinBox的valueChanged(int)信号的槽函数中,可以获取发射者的指针,从而对信号发射者进行操作。
cpp
QSpinBox *spinbox = qobject_cast<QSpinBox *>(sender());
自定义信号及其使用
cpp
class QPersion : public QObject
{
Q_OBJECT
private:
int m_age = 10;
public:
void incAge();
signals:
void ageChanged(int value); // 自定义信号
}
void QPersion::incAge(){
++m_age;
emit ageChanged(m_age); // 发射信号
}