信号与槽是QT的一大创新,通过自定义信号与槽可以实现自己想实现的功能。
标准的信号与槽写法如下:
connect(&button,&QPushButton::clicked,this,&QWidget::close);
/*
* 对上面的connect信号与槽的说明
* &button :信号发出者,指针类型
* &QPushButton::clicked :处理的信号, &发送者的类名::信号名字 (不用加函数括号,只需要名字即可)
* this : 信号接收者 ,指针类型
* &QWidget::close :&接收者的类名::槽函数名字
*/

自定义槽,普通函数的用法
Qt5:任意的成员函数,普通全局函数,静态函数
槽函数需要和信号一致(参数,返回值)
由于信号都是没有返回值,所以槽函数一般都没有返回值

自定义信号:
信号必须有signals关键字来声明
信号没有返回值,但可以有参数
信号就是函数的声明,只需声明,无需定义
使用:emit (一般都是通过自定义槽函数发送信号出去)

简介:下面代码的梗概是在主窗口定义一个b2按钮,并定义信号与槽来打开子窗口s1,然后在子窗口s1中定义两个按钮sb1和sb2,sb1用来触发自定义的sb1sendSlot槽函数(这个槽函数用来发送sb1Signal()信号),sb2类似,来实现在子窗口中能进行信号广播,然后父类窗口对这个信号感兴趣,进而触发父类窗口的槽函数。(因为父类窗口能控制字类窗口,子类窗口不能反过来控制父类窗口(在子窗口中没有父类的指针),只能发送信号广播,让父类感兴趣)

贴上代码:
Headers文件
①widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QPushButton>
#include "subwidget.h"
namespace Ui {
class Widget;
}

class Widget : public QWidget
{
    Q_OBJECT

public:
    explicit Widget(QWidget *parent = 0);
    subWidget s1;   //头文件引入subwidget.h这个QWidget库,并实例化对象s1


    ~Widget();

private:
    Ui::Widget *ui;
    QPushButton *btn=new QPushButton;
    QPushButton b2;


};

#endif // WIDGET_H

②subwidget.h

#ifndef SUBWIDGET_H
#define SUBWIDGET_H

#include <QWidget>
#include<QPushButton>
class subWidget : public QWidget
{
    Q_OBJECT
public:
    explicit subWidget(QWidget *parent = nullptr);
    QPushButton sb1;
    QPushButton sb2;
    void sb1sendSlot();
    void sb2sendSlot();
signals:
    void sb1Signal();
    void sb2Signal();
public slots:

};

#endif // SUBWIDGET_H

Sources文件:
①main.cpp

#include "widget.h"
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();

    return a.exec();
}

②widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include<QPushButton>

Widget::Widget(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::Widget)
{
    ui->setupUi(this);

    btn->setParent(this);  //btn在widget.h中是new出来的,是个指针,所以用函数得->
    btn->setText("关闭主窗口");
    btn->move(100,100);
    this->resize(400,500);  //this表示调用这个函数的对象,即widget这个主窗口
    connect(btn,&QPushButton::clicked,this,&QWidget::close);
    /*
     * 对上面的connect信号与槽的说明
     * btn :信号发出者,指针类型
     * &QPushButton::clicked :处理的信号, &发送者的类名::信号名字
     * this : 信号接收者 ,指针类型
     * &QWidget::close :&接收者的类名::槽函数名字
    */

    b2.setParent(this);  //b2按钮是widget.h声明的按钮,这里指定父对象为this主窗口
    b2.move(50,50);
    b2.setText("打开新窗口");
    connect(&b2,&QPushButton::released,&s1,&subWidget::show); //在主窗口按下b2按钮,次窗口s1就会show

    //***以下两个conne是接收自定义的信号
    /*
     * sb1Signal是通过自定义槽函数sb1sendSlot发出的信号,
     * 子窗口发出来就会广播,在下面这个this主窗口感兴趣就会调用槽函数
    */
    connect(&s1,&subWidget::sb1Signal,this,&Widget::hide);
    connect(&s1,&subWidget::sb2Signal,this,&Widget::show);
}


Widget::~Widget()
{
    delete ui;
}

③subwidget.cpp

#include "subwidget.h"

subWidget::subWidget(QWidget *parent) : QWidget(parent)
{
    //***sb1和sb2是在subWidget.h中声明的两个按钮
   sb1.setParent(this);
   sb1.move(50,50);
   sb1.setText("关闭主窗口2");
   connect(&sb1,&QPushButton::clicked,this,&subWidget::sb1sendSlot);
   /*
    * 对上面的connect函数声明
    * &sb1 : 信号发出者,指针类型
    * &QPushButton::clicked :处理的信号, &信号发出者的类型::信号名字
    * this :信号接收者,指针类型
    * &subWidget::sb1sendSlot :槽函数,信号处理函数 &接收者类名:槽函数名字
    * 注意:这个槽函数名字是自定义的,在.h中的public下声明void函数,然后在.cpp下面定义。
    */
   sb2.setParent(this);
   sb2.move(20,20);
   sb2.setText("显示主窗口");
   connect(&sb2,&QPushButton::clicked,this,&subWidget::sb2sendSlot);
}

void subWidget::sb1sendSlot()  //这个函数是自定义的槽函数,需要加类名作用域,在此定义
{
    emit sb1Signal();   //在这个槽函数中发送这个信号,信号在.h的signal中声明,在前面加emit即发送
}

void subWidget::sb2sendSlot()
{
    emit sb2Signal();
}

总结:感觉写代码可以debug,写的很清楚,而拖控件感觉不知道实现是怎么样的,后期修改也找不到对象,因此推荐写代码来做界面,便于后期维护,当然也可以先通过design拖控件先实现功能后,再写代码实现同样的功能。

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐