(三)信号与槽

 

 

案列:

1.点击button1改变button2的内容

2.点击主窗口按钮,显示子窗口,再通过自定义信号与槽,点击子窗口,回到主窗口

3.重载的信号槽

4.拓展:

  1.信号可以连接信号

  2.一个信号可以连接多个槽函数

  3.多个信号可以连接一个槽函数

  4.槽函数可以使用lambda表达式

 

例子:
connect(operatorComboBox, QOverload<int>::of(&QComboBox::activated),
this, &ImageComposer::recalculateResult);
第二个参数需要一个信号(函数)的指针,但是QComboBox::activated实际上有两个重载函数
void activated(const QString &text)
void activated(int index)
而上面的这种形式没有带形参列表,不知道返回第一个信号的指针还是第二个信号的指针
这时候利用QOverLoad通过指定形参列表,来确定返回哪个信号的指针
QOverload<int>::of()会返回一个函数指针
所以其实QComBox::activated(int) 和 QOverload<int>::of(&QComboBox::activated)意思差不多

 

mianwidget.cpp

#include "mainwidget.h"
#include <QDebug>

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    // init
    b1 = new QPushButton("老大", this);
    b1->move(100, 100);

    b2 = new QPushButton;
    b2->setParent(this);
    b2->setText("老二");
    b2->move(200, 200);

    // b1 close window
    // qt 信号和槽他们都是函数
    // 1. 信号只有函数声明, 不需要函数定义
    // 2. 槽函数据需要声明也需要定义, 回调函数
    // connect(b1, &QPushButton::pressed, this, &MainWidget::close);

    // 自定义槽函数
    /*
     * 1. 槽函数在Qt5 可以是任意类成员函数, 全局函数, 静态函数, lambda表达式(隐式函数)
     * 2. 槽函数需要与信号对相应(返回值, 参数)
     * 3. 信号没有返回值, 槽函数返回值: void
     * 4. void mysig(int, double, QString);
     *    void myslot(int, double);
     * 5. 槽函数的参数是为了接受信号传过来的的数据
     * 6. 槽函数的参数应该是不能够大于信号的参数个数, 可以少于信号的参数个数
     * 7. 槽函数可以重载
    */

    connect(b1, &QPushButton::released, this, &MainWidget::slotForMianWidget);


    // b3 显示子窗口SubWidget  -- subW
    b3 = new QPushButton("软件园", this);
    b3->resize(100, 50);
    b3->move(200, 200);

    connect(b3, &QPushButton::clicked, this, &MainWidget::slotHideMe);

    // Qt 5 信号槽的使用方法
    void (SubWidget::*MySigSub)() = &SubWidget::sigSub;// 用函数指针来指定接收的信号是带参数还是不带参数
    connect(&subW, MySigSub, this, &MainWidget::slotShowMe);

    void (SubWidget::*MysigPlus)(int, QString) = &SubWidget::sigSub;// 用于信号函数发生重载的时候,告诉编译器调用哪个函数
    connect(&subW, MysigPlus, this, &MainWidget::slotSubMsg);

    // Q4 信号槽
    // SIGNAL() SLOT() 宏 将函数转换为字符串 宏展开预处理的时候不会报错
//    connect(&subW, SIGNAL(sigSub()), this, SLOT(slotShowMe()));
//    connect(&subW, SIGNAL(sigSub(int , QString)), this, SLOT(ABCDe(bb, aa)));

    // 使用lambda表达式作为槽函数
    connect(b1, &QPushButton::clicked, this, [=]()
    {
        b2->setText("lambda表达式!!!");
        b3->hide();
    });
}

MainWidget::~MainWidget()
{

}

void MainWidget::slotForMianWidget()
{
    b2->setText("我被老大改名了...");
}

void MainWidget::slotHideMe()
{
    // 隐藏自己
    hide();
    // 显示软件园窗口
    subW.show();
}

void MainWidget::slotShowMe()
{
    // 显示自己
    show();
    // 隐藏软件园窗口
    subW.hide();
}

void MainWidget::slotSubMsg(int num, QString str)
{
    // QString --> char*
    // string --> char*   .data()
    qDebug() << num << str.toUtf8().data();

}

 

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

#include <QWidget>
#include <QPushButton>
#include "subwidget.h"


class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = 0);
    ~MainWidget();

    // 自定义槽函数
    void slotForMianWidget();
    void slotHideMe();
    void slotShowMe();
    void slotSubMsg(int num, QString str);

private:
    QPushButton* b1;
    QPushButton* b2;
    QPushButton* b3;    // 显示子窗口
    // 子窗口对象
    SubWidget subW;

};

#endif // MAINWIDGET_H
mainwidget.h
#include "subwidget.h"

SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
    b1= new QPushButton("中腾", this);
    b1->resize(100, 100);

    setWindowTitle("软件园窗口");

    resize(400, 600);

    connect(b1, &QPushButton::clicked, this, &SubWidget::myslot);
}

void SubWidget::myslot()
{
    // 发送信号
    emit sigSub();
    emit sigSub(250, "你是二百五!!!");
}
subwidget.cpp

subwidget.h

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include <QWidget>
#include <QPushButton>

class SubWidget : public QWidget
{
    Q_OBJECT
public:
    explicit SubWidget(QWidget *parent = 0);


signals:
    // 自定义信号, 必须使用signals 声明
    void sigSub();
    void sigSub(int , QString);
    /*
     * 1. 可以有参数
     * 2. 可以重载
     * 3. 返回值为void
     * 4. 发送信号: emit + 信号名;
     * emit sigsub();
    */

public slots:
    void myslot();

private:
    QPushButton* b1;
};

#endif // SUBWIDGET_H

 

posted @ 2019-04-21 09:25  狂奔~  阅读(737)  评论(0编辑  收藏  举报