信号重名
即信号重载时,多个信号名称相同,参数列表不同,这时候如何绑定
- 利用QT4的写法:
//举例
connect(example,SIGNAL(valueChanged(int)),this,SLOT(onValueChanged(int)));
connect(example,SIGNAL(valueChanged(const QString&)),this,SLOT(onValueChanged(const QString&)));
- 利用QOverload<T>::of函数获取对应类型的函数指针
T就是信号或者槽函数的参数类型
//举例
connect(example,QOverload<int>::of(&Example::valueChanged),this,QOverload<int>::of(&Widget::onValueChanged));
connect(example,QOverload<const QString&>::of(&Example::valueChanged),this,QOverload<const QString&>::of(&Widget::onValueChanged));
信号参数为自定义类型
若信号的参数为自定义类型。在发送信号之前,需要先将这个自定义类型注册,然后信号绑定的槽函数才能获取到信号参数里的携带的值
//注册的接口
//模板参数就是自定义类型
//参数就是自定义类型的类名(字符串类型)
qRegisterMetaType<MyClass>("MyClass");
connect函数的第5个参数
即确定信号和槽的连接类型
- Qt::AutoConnection,默认就是他,即信号发射时自动确定连接类型。信号的发送者和接收者在同一个线程,则自动使用Qt::DirectConnection;不在同一个线程中,则自定使用Qt:: QueuedConnection
- Qt::DirectConnection,即信号发送时,槽函数会被直接调用,槽函数运行于信号发送者所在线程。多线程环境下比较危险,可能会造成崩溃
- Qt::QueuedConnection,即信号发送时,槽函数不会立即调用,而是等接收者的当前函数执行完,进入到事件循环之后,才会被调用。槽函数运行在接收者的线程中。多线程环境下用这个
- Qt::BlockingQueuedConnection,槽函数调用时机和Qt::QueuedConnection一样,但是信号发送后,发送者所在线程会被阻塞,直到槽函数执行完毕。信号的发送者和接受者不能再同一个线程中,否则会死锁。多线程之间需要同步时可能会用到这个
- Qt::UniqueConnection,信号在连接时,前面的类型可以或上(|)这个类型,防止同一个槽函数重复连接
举例
//自定义1个类,里面有自定义的几个信号
#ifndef EXAMPLE_H
#define EXAMPLE_H
#include <QWidget>
class Example : public QWidget
{
Q_OBJECT
public:
struct Person
{
QString name;
int age;
};
explicit Example(QWidget *parent = nullptr) : QWidget{parent}
{
//在构造函数中先注册这个自定义类型,作为信号的参数时才能发送到槽函数中
qRegisterMetaType<Person>("Person");
}
signals:
//同名信号
void valueChanged(int num);
void valueChanged(const QString& str_num);
//自定义信号的参数为自定义类型
//需要先注册这个自定义类型,这之后,该信号绑定的槽函数才能得到参数的值
void personInfoChange(Person person_info);
};
#endif // EXAMPLE_H
//绑定前面的信号
#ifndef WIDGET_H
#define WIDGET_H
#include <QWidget>
#include<example.h>
class Widget : public QWidget
{
Q_OBJECT
public:
Widget(QWidget *parent = nullptr):QWidget(parent)
{
Example* example=new Example(this);
//qt4写法
connect(example,SIGNAL(valueChanged(int)),this,SLOT(onValueChanged(int)));
connect(example,SIGNAL(valueChanged(const QString&)),this,SLOT(onValueChanged(const QString&)));
//泛型写法
//获取指定参数的函数指针QOverload<T>::of
connect(example,QOverload<int>::of(&Example::valueChanged),this,QOverload<int>::of(&Widget::onValueChanged));
connect(example,QOverload<const QString&>::of(&Example::valueChanged),this,QOverload<const QString&>::of(&Widget::onValueChanged));
}
~Widget()=default;
private slots:
void onValueChanged(int val){}
void onValueChanged(const QString& val){}
};
#endif // WIDGET_H
学习链接:https://github.com/0voice