QT信号和槽与Lambda表达式(自定义信号和自定义槽)--子父窗口的切换和独立窗口

subwidget.h

#ifndef SUBQWIDGET_H
#define SUBQWIDGET_H


#include <QWidget>
#include<QPushButton>
class SubQWidget : public QWidget
{
    Q_OBJECT
public:
    explicit SubQWidget(QWidget *parent = nullptr);
    void SendSlot();    //发射信号的槽



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

    void mySignal(); //小弟窗口自定义信号
private:

    QPushButton b;

};

#endif // SUBQWIDGET_H


mainwidget.h

#ifndef MAINWIDGET_H
#define MAINWIDGET_H

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

class MainWidget : public QWidget
{
    Q_OBJECT

public:
    MainWidget(QWidget *parent = nullptr);
    ~MainWidget();
     void MySlot();     //改变b2的内容
     void exchang_Slot();//切换窗口
    void pro();          //老大窗口处理小弟窗口发来的信号
private:
    QPushButton b1;
    QPushButton* b2;    //按钮指针,用来指定父类对象
    QPushButton b3;
    SubQWidget w;//小弟窗口对象


};
#endif // MAINWIDGET_H

subwidget.cpp

#include "subqwidget.h"

SubQWidget::SubQWidget(QWidget *parent) : QWidget(parent)
{
    this->setWindowTitle("小弟");
    b.setParent(this);
    b.setText("切换到父窗口");

    connect(&b,&QPushButton::pressed,this,&SubQWidget::SendSlot); //当按钮按下时,发送信号给老大
    resize(300,300); //设置大小
}

void SubQWidget::SendSlot()
{
    emit mySignal();        //发射信号
}

mainwidget.cpp

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

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{

   //1.通过setparent指定父类对象
   b1.setParent(this);
   b1.setText("close");
   b1.move(100,100);    //移动位置

   //2.通过构造函数指定父类对象MainWdigets,当前对象是MainWidgets
   b2 = new QPushButton(this);//当前MainWidget对象this
   b2->setText("button");
   b2->move(200,200);

   //信号和槽关联
   connect(&b1,&QPushButton::clicked,this,&MainWidget::close);

   /*自定义槽:普通函数的用法
    * QT5:任意的成员函数,普通全局函数,静态函数
    * 槽函数需要和信号一致(参数,返回值)
    * 由于信号都是没有返回值,所以槽函数也没有返回值
    * 一个信号可以关联多个槽(relasead关联Myslot和hide两个槽,
    * released分别代表按钮的按下和抬起
    */
   connect(b2,&QPushButton::released,this,&MainWidget::MySlot);//按钮b2按下时内容改为123
   connect(b2,&QPushButton::released,&b1, &QPushButton::hide);//按钮b2抬起时把b1隐藏

   //信号:短信
   //槽:接收短信的手机

   setWindowTitle("老大");
   b3.setText("切换到子窗口");
   b3.setParent(this);
   b3.move(50,50);
   //w.show();  //此处就是实现窗口独立

   //按钮按下切换到子窗口的关联
   connect(&b3,&QPushButton::released,this,&MainWidget::exchang_Slot);//注意:此处槽函数只能使用类名::进行访问,不能通过对象,否则报错
   connect(&w, &SubQWidget::mySignal, this, &MainWidget::pro);

   resize(300,300);//设置窗口大小

	
  QPushButton * b4 = new QPushButton(this);
  b4->setText("Lambda表达式");
  b4->move(150,150);
  int a = 10, b = 100;
  /*lambda表达式,匿名函数对象,c++11新特性,项目文件CONFIG += C++11
  [](){}组成,[]代表表达式所接受的范围,以值传递方式进行传递[a,b]代表函数体只能使用ab,不能使用其他变量
  []里面通常用=,表示允许传入外部变量,而且这样安全。当然也可以使用 & 或 this以引用的方式传入,this表示将本类的成员传入,
  但是不建议用&,因为会出现内存不完全释放问题。
  
  重点:信号的参数必须和lambda表达式中()里的参数一致。
  
  还有,外部的变量允许被修改,只需在()加上mutable 。示例如下:
  */
 /* connect(b4,&QPushButton::released,this,
          [a,b]() mutable
          {
                qDebug()<<"11111"<<endl;
                a = 11;
                qDebug()<<a<<b<<endl;
          }


          );*/
connect(b4,&QPushButton::released,this,
          [=]() mutable
          {

                qDebug()<<"11111"<<endl;
                b4->setText("lambda");
                a = 11;
                qDebug()<<a<<b<<endl;
          }


          );



}

void MainWidget::MySlot(){
    b2->setText("123");
}

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

    //本窗口显示
    this->show();
}

MainWidget::~MainWidget()
{
}


main.cpp

#include "mainwidget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWidget w;//执行MainWidget的构造函数
    w.show();
    return a.exec();//停在这人
}

在这里插入图片描述
在这里插入图片描述

在这里插入图片描述
当触发Lambda表达式按钮时,应用程序会输出a,b的值。

注意:
在进行窗口切换的时候,父类切换子类窗口直接按钮按下进行关联就可以直接切换(槽函数将自己隐藏,子类显示)connect(&b3,&QPushButton::released,this,&MainWidget::exchang_Slot);,
而子类切父类的时候却不能这样,因为父类中有子类的对象w而子类却没有父类对象,除了自定义槽之外,还需要自定义信号发射给父类,让父类自己对信号进行处理,就像老板和员工的关系,老板可以命令员工,员工不能命令老板一样

2.指定父类窗口的两个方法: 使用setparent(),或者使用构造函数传参。

3.在创建子类窗口对象时,不能在基类构造函数里面创建,因为是局部的,构造函数执行完毕就没有了。

为什么要指定父类对象?有什么好处
答:为了使子类窗口在父类窗口里面。指定父类有两种方式 使用setparent(),或者使用构造函数传参。
好处就是使得子类窗口不用每个都使用show单独显示,只需要对父类窗口使用show就可以把子类父类的窗口显示出来。很方便。

怎样创建子类窗口
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值