QT 学习 (信号和槽)

首先看下信号和槽的连接函数

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. 感觉好灵活...

 

 

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值