Qt5教程: (4) 带参数信号与槽

在subwidget.h中声明一个signal. 和之前的信号函数重名但是有参数:

    void  backSignal(QString);

之后在subwidget.cpp的槽函数sendSignal()中也发送该信号:

    emit backSignal("子窗口请求返回");

在mainwidget.h中声明一个槽函数来响应该信号:

    void logSlot(QString);

并在mainwidget.cpp中定义该槽函数, 打印信号传过来的字符串:

void MainWidget::logSlot(QString log)
{
    qDebug() << log;
}

因为使用到了qDebug, 所以需要在mainwidget.h中添加头文件:

#include <QDebug>

下面在mainwidget.cpp中建立连接即可:

connect(&subWin, backSignal, this, &MainWidget::logSlot);

如果没有重名信号的话, 这样写是没有问题的, 但是我们现在由两个backSignal信号, 一个不带参数, 一个带参数, 编译器是没办法区分的, 需要我们告诉它, 所以, 删掉那两条信号都是backSignal的connect语句重新建立连接:

    void(SubWidget::*backSignal)() = &SubWidget::backSignal;  // 我是没有参数的backSignal, 叫backSignal1
    connect(&subWin, backSignal, this, &MainWidget::backSlot);
    
    void(SubWidget::*backSigna2)(QString) = &SubWidget::backSignal;  // 我是带一个QString参数的backSignal, 叫backSignal2
    connect(&subWin, backSigna2, this, &MainWidget::logSlot);

保存后 Ctrl + R运行, 点击Back按钮, 会输出信号发送的字符串:

如果用Qt4的语法的话, 会十分简单:

    connect(&subWin, SIGNAL(backSignal()), this, SLOT(backSlot()));
    connect(&subWin, SIGNAL(backSignal(QString)), this, SLOT(logSlot(QString)));

但是Qt4这种写法在编译时是不进行错误, 也就是如果你信号和槽函数名字写错了, 也是可以编译通过的. 在运行时才会报错. 而Qt5新写法在编译时就会报错, 所以Qt4更简单Qt5会更安全.

附录

mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

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

class MainWidget : public QWidget
{
    Q_OBJECT

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

public slots:
    void nextSlot();
    void backSlot();
    void logSlot(QString);

private:
    QPushButton b1;
    QPushButton *b2;

    SubWidget subWin;
};

#endif // MAINWIDGET_H

mainwidget.cpp

#include "mainwidget.h"

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    this->setWindowTitle("Window1");
    this->resize(300, 200);
    b1.setParent(this);
    b1.setText("Close");
    b1.move(50, 50);

    b2 = new QPushButton(this);
    b2->setText("Next");
    b2->move(150, 50);

    connect(&b1, &QPushButton::clicked, this, &MainWidget::close);
    connect(b2, &QPushButton::clicked, this, &MainWidget::nextSlot);

    void(SubWidget::*backSignal)() = &SubWidget::backSignal;
    connect(&subWin, backSignal, this, &MainWidget::backSlot);

    void(SubWidget::*backSigna2)(QString) = &SubWidget::backSignal;
    connect(&subWin, backSigna2, this, &MainWidget::logSlot);
    /*
    connect(&subWin, SIGNAL(backSignal()), this, SLOT(backSlot()));
    connect(&subWin, SIGNAL(backSignal(QString)), this, SLOT(logSlot(QString)));
    */
}

void MainWidget::nextSlot()
{
    subWin.show();
    this->hide();
}

void MainWidget::backSlot()
{
    subWin.hide();
    this->show();
}
void MainWidget::logSlot(QString log)
{
    qDebug() << log;
}

MainWidget::~MainWidget()
{

}

subwidget.h

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include <QWidget>
#include <QPushButton>

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

signals:
    void backSignal();
    void  backSignal(QString);

public slots:
    void sendSignal();

private:
    QPushButton b;
};

#endif // SUBWIDGET_H

subwidget.cpp

#include "subwidget.h"

SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle("Windows2");
    this->resize(300, 200);

    b.setParent(this);
    b.setText("Back");
    b.move(150, 50);

    connect(&b, &QPushButton::clicked, this, &SubWidget::sendSignal);
}

void SubWidget::sendSignal()
{
    emit backSignal();
    emit backSignal("子窗口请求返回");
}


此文原创禁止转载,转载文章请联系博主并注明来源和出处,谢谢!
作者: Raina_RLN https://www.cnblogs.com/raina/

posted @ 2019-08-07 20:42  Raina_R  阅读(9594)  评论(0编辑  收藏  举报