QT+信号有参数与无参数的实现+QT4和QT5在信号和槽使用上的区别

在QT5中,信号有参数和无参数

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include <QWidget>
#include <QPushButton>


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

    void sendSlot();

signals:
    /*信号必须有singles关键字来声明
     * 信号没有返回值,但可以有参数
     * 信号就是函数的生命,只需声明,无需定义
     * 使用:emit mySignal();
    */
    void mySignal();

    void mySignal(int , QString);

public slots:


private:
    QPushButton btn4;
};

#endif // SUBWIDGET_H
#include "subwidget.h"

SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
{

    this->setWindowTitle("波老师");

    this->setFixedSize(360,480);
    btn4.setParent(this);
    btn4.setText("切换到苍老师");

    //点击按钮btn4实现给主窗口发送信号
    connect(&btn4,&QPushButton::clicked,this,&SubWidget::sendSlot);


}


void SubWidget::sendSlot()
{
    emit mySignal();
    emit mySignal(250,"我是子窗口");
}

 

 

#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 mySlot();//自定义的槽函数

    void changeWin();

    void dealWin();

    void subSlot(int a,QString str);
private:
    QPushButton btn1;
    QPushButton *btn2;
    QPushButton btn3;
    SubWidget w;//该对象在主窗口中,子窗口没有办法调用,所以需要利用子窗口发送给主窗口消息,进而主窗口进行处理
};

#endif // MAINWIDGET_H

 

 

 

#include "mainwidget.h"

#include <QPushButton>

#include <QDebug>
MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{

//    QPushButton btn1;
//    QPushButton btn2;

    btn1.setParent(this);
    btn1.setText("colse");
    btn1.move(100,100);


    btn2 = new QPushButton(this);//指针没有空间,是需要动态的对其进行空间的分配
    btn2 ->setParent(this);
    btn2 ->setText(" 3 2 1 ");

    connect(&btn1,&QPushButton::pressed,this ,&MainWidget::close);

    /* 对connect的说明:
     * &btn1 :信号发出着,指针类型
     * &QPushButton::pressed:处理信号,  &发送者的类名::信号名字
     * this:信号接收者
     * &MainWidget::close:   槽函数,信号处理函数 &接收者的类名::槽函数名字
    */


    /*自定义槽,说的更加通俗一点,就是普通函数的用法
     * QT5:可以是 任意的成员函数(常用这种方法,直接写成该类的成员函数),普通全局函数,静态函数  都可以是槽函数
     * 槽函数需要和信号一致(参数,返回值)
     * 由于信号都是没有返回值,所以,槽函数一定没有返回值
    */
    //释放按钮btn2实现里面的文本内容发生改变
    connect(btn2,&QPushButton::released,this,&MainWidget::mySlot);//在写自定义信号槽函数的时候,一定要看发送信号函数的类型,这里released信号的函数是:void QAbstractButton::released()
                                                //即released函数没有参数,也没有返回值,槽函数需要和信号一致,也没有参数和返回值

    //释放按钮btn2隐藏按钮btn1
    connect(btn2,&QPushButton::released,&btn1,&QPushButton::hide);

    //互相切换窗口的小游戏
    this->setFixedSize(360,480);
    this ->setWindowTitle("苍老师");
    btn3.setParent(this);
    btn3.setText("换到波老师");
    btn3.move(50,50);


    //显示子窗口
//    w.show();

    //点击按钮btn3实现主窗口隐藏,子窗口显示
    connect(&btn3,&QPushButton::released,this,&MainWidget::changeWin);

    //处理子窗口发送过来的信号
    void (SubWidget::*funSognal)() = &SubWidget::mySignal;
    connect(&w,funSognal,this,&MainWidget::dealWin);
    //处理子窗口发送过来的信号(有参数)
    void (SubWidget::*testSognal)(int ,QString) = &SubWidget::mySignal;
    connect(&w,testSognal,this,&MainWidget::subSlot);
}

//自定义槽函数的实现
void MainWidget::mySlot()
{
    btn2->setText("I LOVE YOU");
}

void MainWidget::changeWin()
{
    //子窗口显示,
    w.show();
    //本窗口隐藏
    this ->hide();

}
void MainWidget::dealWin()
{
    //子窗口隐藏
    w.hide();
    //本窗口显示
    this->show();
}

void MainWidget::subSlot(int a,QString str)
{
    qDebug()<<a<<str;
}
MainWidget::~MainWidget()
{

}

当信号函数发生重载的时候,为了不产生二义性,需要使用函数指针的方式进行区分,(这里需要重点掌握指针函数的用法),同时从这种写法来看,也不难看出其在语法上还是比较难的,在QT4中则没用这么难,方式如下:

  1)对槽函数声明public slots:

  2)其最大的优势是当写connect中的SIGNAL和SLOT时会自动提示信号的类型,

既然QT4在这个方面那么简单简洁,为什么还要用QT5那么难的语法呢(函数指针)?这是因为在QT4中 SIGNAL 和SLOT 将函数名字转化成字符串  不进行错误的检查,只在运行的时候来提示程序不可行,在大的项目中,代码量是非常大的,我们还是尽量希望其能够提示语法的错误,不希望最后运行时提示有错误。

上一篇:Qt 为QPushButton、QLabel添加鼠标移入移出事件


下一篇:Qt通过qss设置按钮图标样式