首先看下信号和槽的连接函数
-
QObject::
connect(
const QObject *sender,
const
char *signal,
-
-
const QObject *receiver,
const
char *method,
-
-
Qt::ConnectionType
type = Qt::AutoCompatConnection)
这是我们最常用的形式。connect() 一般会使用前面四个参数,第一个是发出信号的对象,第二个是发送对象发出的信号,第三个是接收信号的对象,第四个是接收对象在接收到信号之后所需要调用的函数。也就是说,当 sender 发出了 signal 信号之后,会自动调用 receiver 的 slot 函数。
其中最后一个参数是枚举类型定义了三种信号和槽的连接方式:
(1) Qt::DirectConnection :信号发送后立即传递给相关联的槽函数,只有槽函数执行完毕返回后,发送信号"emit <信号>" 之后的代码才被执行
(2) Qt::QueuedConnection : 信号发送后排队,知道事件循环(event)有能力将它传递给槽; 而不管槽函数有没有执行,发送信号"emit <信号>" 之后的代码都会立即得到执行
(3) Qt::AutoConnection : 如果信号和槽函数在同一线程, 信号发出后,槽函数将立即执行, 等于Qt::DirectConnection; 如果信号和槽不在同一个线程,信号将排队,等待事件循环的处理,效果等同于Qt::QueuedConnection
一个类想支持信号和槽必须从QObject或QObject的子类继承。Qt信号和槽机制不支持对模板的使用
这两个东西说起来有点抽象,我还是不太明白;其实只要切实的去用过之后就会有一定的了解。
//connect() 第五个参数的作用, 连接方式: 默认,队列 ,直接
//多线程才有用
//默认的时候
//多线程,默认使用队列
//单线程,默认使用直接方式
//队列:槽函数所在的线程和接收者一样(同类)
//直接:槽函数所在线程和发送者一样(同类)
整理下Qt4和Qt5的信号和槽的连接方式
Qt4:
槽函数必须有 slots 关键字来修饰
SIGNAL SLOT将函数名字转换为字符串 不进行错误检查
connect(&w, SIGNAL(mySignal(int,QString)), this, SLOT(dealSlot(int,QString)));
Qt5:
(1) 自定义槽, 普通函数的用法
(2). 任意的成员函数,普通全局函数,静态函数
(3). 由于信号都是没有返回值,所以,槽函数一定没有返回值
connect(&button, &QPushButton::pressed, this, &MainWidget::close);//连接信号和槽
/* &button:信号发出者,指针类型
* &QPushButton::pressed:处理的信号, &发送者的类名::信号名字
* &MainWidget::close: 槽函数, 信号处理函数 &接收的类名::槽函数名字
*/
一. 使用实例1.
源码下载:https://download.csdn.net/download/dianzishi123/10825578
在同一个类中定义一个私有槽函数和一个信号,这个信号只是在头文件(.h文件)中声明并没有真正的去实现这个信号;同样的在头文件中声明一个私有槽函数,在源文件(.cpp文件)中去实现这个槽函数某个功能,在一定条件下发射未实现的私有信号去触发这个槽函数也是可以得;总的来说就是只要声明一个信号就可以用来发射触发槽。
工程目录:
启动程序看下效果:
点击下按钮Button后效果:
工程中的相关文件
1. slotTest.pro文件:分别管理的是头文件(.h文件),源文件(.cpp文件)和相应的QT库
SOURCES += \ main.cpp \ MyWidget.cpp HEADERS += \ MyWidget.h QT += widgets gui
2. main.cpp文件: 主要是QT的事件循环和显示一个widget
-
#include <QApplication>
-
#include "MyWidget.h"
-
-
int main(int argc, char** argv)
-
{
-
QApplication app(argc,argv);
-
MyWidget s;
-
s.
show();
-
return app.
exec();
//qt事件循环
-
}
3.MyWidget.cpp文件: 槽函数的实现, 构造函数中信号和槽的连接; 设置控件布局显示
整个过程是这样的:按下Button按钮后会有一个按钮事件clicked的信号产生,去触发这个点击事件的槽函数; 在这个槽函数会打印"button ......"信息并发射我自己声明的信号"mySignals"然后这个信号又会触发另一个槽函数,在这个槽函数中打印信息"mySignals......."
-
#include "MyWidget.h"
-
#include <QHBoxLayout>
-
#include <QVBoxLayout>
-
#include <QDebug>
-
-
MyWidget::
MyWidget(QWidget *parent) :
QWidget(parent)
-
{
-
QHBoxLayout *hlay =
new QHBoxLayout;
-
button =
new
QPushButton(
this);
-
button->
setText(
"Button");
-
lineEdit =
new
QLineEdit(
this);
-
-
hlay->
addStretch(
10);
//加个弹簧
-
hlay->
addWidget(lineEdit);
-
hlay->
addWidget(button);
-
hlay->
addStretch(
10);
-
-
QVBoxLayout *vlay =
new QVBoxLayout;
-
vlay->
addLayout(hlay);
-
this->
setLayout(vlay);
//this指当前类也就是MyWidget类 把这个布局用到这个界面中
-
-
//button 连接信号和槽
-
connect(
this->button,
SIGNAL(
clicked()),
this,
SLOT(
mySlotButtonCliced()),Qt::AutoConnection);
-
-
//自己定义的信号连接槽
-
connect(
this,
SIGNAL(
mySignals()),
this,
SLOT(
mySlot()),Qt::AutoConnection);
//因为信号和槽都是本类中的,直接用this
-
}
-
-
//button 关联的槽函数
-
void MyWidget::mySlotButtonCliced()
-
{
-
qDebug()<<
"button ...........";
-
emit mySignals();
-
}
-
-
//自己定义信号mySignals关联的槽函数
-
void MyWidget::mySlot()
-
{
-
qDebug()<<
"mySignals..........";
-
}
4. MyWidget.h文件: 实现槽和信号的声明,和一些变量声明
-
#ifndef MYWIDGET_H
-
#define MYWIDGET_H
-
-
#include <QWidget>
-
#include <QPushButton>
-
#include <QLineEdit>
-
-
class
MyWidget :
public QWidget
-
{
-
Q_OBJECT
-
public:
-
explicit MyWidget(QWidget *parent = nullptr);
-
-
signals:
//信号的声明不区分public和private
-
void mySignals();
-
-
private slots:
-
void mySlotButtonCliced();
-
void mySlot();
-
-
private:
-
QPushButton *button;
-
QLineEdit *lineEdit;
-
public slots:
-
};
-
-
#endif // MYWIDGET_H
二. 自定义信号和槽函数传参数问题
在声明信号时, 添加有参数的信号, 在通过emit发射信号时把相应的参数传递给信号, 相关联的槽函数也有相同的参数,这样就把信号的参数,传递给槽函数了....................................................还未完....................
总结思考:
1. 私有的槽和信号是否只能在本类中使用;
2. 公有槽和信号是否可以实现不同类之间的通信
3. 感觉好灵活...