不讲那么多大道理,直接上
前面用Python QT 发现在线程或者定时器里操作控件,有很大概率导致程序闪退,所以如果想要在线程和定时器中操作控件,需要自定义信号和槽,不知道C++QT会不会有这个问题,这个经验不是很多。。
信号和槽的声明:
信号:关键字signals定义一个信号,信号不能也无需实现,并且返回值是void,信号与槽方法都可以携带参数,但是槽方法的参数类型必须是信号参数类型保持一致或者少于信号参数
槽:(Slot)就是对信号响应的函数。槽就是一个函数,与一般的C++函数是一样的,可以声明在类的任何部分(public、private 或 protected),可以具有任何参数,也可以被直接调用,与一般的函数不同的是:它可以与一个信号关联,当信号被发射时,关联的槽函数被自动执行
//mywidget.h
class MyWidget : public QWidget
{
Q_OBJECT
public:
MyWidget(QWidget *parent = nullptr);
~MyWidget();
private:
QHBoxLayout *mainHBoxLayout; //主布局
QPushButton *pushButtonLINConnect;//LIN连接按钮
signals:
void signalShowFault();
private:
private slots:
void pushButtonLINConnectClicked();
void slotShowFault();
}
信号和槽的关联:
//关联信号和槽函数,需要带参数的话信号和槽函数参数一致就好了,一般写在界面的初始化里
connect(this,SIGNAL(signalShowFault()), SLOT(slotShowFault()));
信号发送:
//在需要调用槽函数的地方发送信号即可。
//当然发送完信号就会接着执行下一行代码,不会等待槽函数运行结束
emit(signalShowFault());
信号和槽的关联形式:
1. 信号和槽一对一
2.信号和信号一对一
connect(this,SIGNAL(signal1()),this,SIGNAL(signal2()));
3.信号一对多,一个信号可以同时关联多个槽和信号
4.槽函数一对多,一个槽函数可以同时被多个信号关联。
信号和槽断开关联:
QObject::disconnect(
const QObject* sender,
const char* signal,
const QObject *receiver,
const char* method
);
1.断开一个对象的所有信号关联
disconnect(sender,0,0,0);
//也可以这样
sender->disconnect();
2.断开指定信号的所有关联
disconnect(sender,SIGNAL(signal()),0,0);
//类似于
sender->disconnect(SIGNAL(signal()));
3.断开指定接收者的所有关联
disconnect(sender,0,receiver,0);
//等同于
sender->disconnect(SIGNAL(signal()));
4.断开指定信号于槽的关联
disconnect(sender, SIGNAL(single1()), receiver, SLOT(slotFun()));
//等同于:
disconnect(myConnection); //myConnection为connect()的返回值
myConnection是使用connect函数时的返回值,可以先用一个成员变量保存这个返回值
例如:
// 声明一个QMetaObject::Connect 变量
private:
QMetaObject::Connect metaRes;
//在关联信号和槽的时候把返回值赋给他
metaRes = connect(this,SIGNAL(signal()),this,SLOT(slot()));
//断开关联的时候直接用这个变量
disconnect(metaRes);
信号和槽机制的优点
松耦合,灵活!