Qt学习笔记(一)之QT基础以及两个窗口切换

2019.3.17 视频课程信息:黑马程序员官方网站 的 黑马程序员Qt (B站上自己看的)视频内容1——12

了解基础:

main函数中各个语句的意思:

//所需要头文件
#include "mywidget.h"
//应用程序类
//QT头文件没有.h
//头文件和类名一样
#include <QApplication>
int main(int argc, char *argv[])
{
    //有且只有一个应用程序类的对象
    QApplication a(argc, argv);
    //MyWidget继承于QWidget,QWidget是一个窗口基类
    //所以MyWidget也是窗口类
    //w就是一个窗口
    MyWidget w;
    //窗口创建默认是隐藏的,需要认为显示
    w.show();
    return a.exec();//a.exec()让程序一直执行,等待用户操作,等待事件发生
}

指定父对象

Headers当中建立的是.h文件
Source中建立的是.cpp文件

一、基础

程序运行,都是运行main函数,所以在main函数中先了解一下按钮窗口的使用。但是,程序并不可以全部写在主函数中,不易于看。所以后面我们 改写到了主窗口的构造函数中。

#include <QApplication>
#include <QWidget>//窗口控件基类
#include <QPushButton>//设置按钮

int main (int argc,char **argv)
{
              QApplication app(argc ,argv);

              QWidget w;
              w.setWindowTitle("主要看气质");//设置标题
             // w.show();

              QPushButton b;
              b.setText("^_^");//给按钮设置内容
             // b.show();
              b.setParent(&w);//b的父类设置为w,就是把b放在了w上面,默认位置为左上角
              b.move(100,100);//移动坐标


              QPushButton b1(&w);
              b1.setText("abc");

               w.show();

              /*如果不指定父对象。对象和对象(窗口和窗口)没有关系,独立
               * a指定b为他的父对象,相当于a放在b的上面
               * 指定父对象有两种方式:
               * (1)setParent
               * (2)通过构造函数传参
               * 指定父对象,只需要父对象显示,上面的子对象自动显示
              */

              app.exec();
              return 0;

          }

二、显示两个窗口

**功能:**显示出两个窗口一个是名字为老大的主窗口,一个是名字为小弟的子窗口,点击主窗口中的ABC按钮,close按钮消失,并且ABC按钮变为123按钮,点击close按钮,窗口消失
在这里插入图片描述
mainwidget.h中的代码:

#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();

private :
   QPushButton b1;
   QPushButton *b2;
   QPushButton b3;

   SubWidget w;

};

#endif // MAINWIDGET_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);

signals:

public slots:
private:
    QPushButton b;
};

#endif // SUBWIDGET_H

mainwidget.cpp中代码:

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

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    b1.setParent(this);
    b1.setText("close");
    b1.move(100,100);

    b2 = new QPushButton(this);
    b2->setText("ABC");

    connect(&b1,&QPushButton::pressed,this,&MainWidget::close);
    /*&b1:信号发出者,指针类型
     * &QPushButton::pressed():处理的信号 &发送者类名::信号名字
     * this:信号接受者
     * &MainWidget::close:槽函数,信号处理函数  &接收的类名::槽函数名字
*/

    /*自定义槽:普通函数的用法
     * QT5:任意的成员函数,普通全局函数,静态函数
     * 槽函数需要和信号一致(参数,返回值)
     * 由于信号没有返回值,所以槽函数一定没有返回值
*/
//released是释放时在变化  pressed是按下就变化
    connect(b2,&QPushButton::released,this,&MainWidget::mySlot);//b2本来就是一个指针,不用在取地址

    connect(b2,&QPushButton::released,&b1,&MainWidget::hide);//hide隐藏
    /*信号:短信
     * 槽函数:接收短信的手机*/


    setWindowTitle("老大");
  // this->setWindowTitle("老大")和上面的一句完全等价
    b3.setParent(this);
    b3.setText("切换到自窗口");
    b3.move(50,50);

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


}

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

MainWidget::~MainWidget()
{

}

subwidget.cpp中代码:

#include "subwidget.h"

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

main中代码:(一般main中代码是不变的)

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

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWidget w;//执行MianWidget的构造函数
    
    w.show();

    return a.exec();
}

三、两个窗口进行自由切换

功能:点击主窗口切换按钮切换到子窗口,点击子窗口切换按钮切换到主窗口。
在这里插入图片描述
从主窗口切换到子窗口可以随便命令,因为主窗口包括着子窗口,但是从子窗口切换到主窗口就不那么容易,需要子窗口发射一个信号给主窗口,然后主窗口去处理这个信号才可以。

mainwidget.h中的代码:

#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 dealSub();//处理子窗口函数

private :
   QPushButton b1;
   QPushButton *b2;
   QPushButton b3;

   SubWidget w;

};

#endif // MAINWIDGET_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);

    void sendSlot();

signals:
    /*信号必须有signals这个关键字来声明
     * 信号没有返回值,但是可以有参数
     * 信号就是函数的声明,只需要声明无需定义
     * 使用:mySignal();*/
    //子窗口没有办法调用主窗口,所以让子窗口发射一个信号,然后给主窗口,让主窗口去处理这个信号
    void mySignal();

public slots:
private:
    QPushButton b;
};

#endif // SUBWIDGET_H

mainwidget.cpp中代码:

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

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    b1.setParent(this);
    b1.setText("close");
    b1.move(100,100);

    b2 = new QPushButton(this);
    b2->setText("ABC");

    connect(&b1,&QPushButton::pressed,this,&MainWidget::close);
    /*&b1:信号发出者,指针类型
     * &QPushButton::pressed():处理的信号 &发送者类名::信号名字
     * this:信号接受者
     * &MainWidget::close:槽函数,信号处理函数  &接收的类名::槽函数名字
*/

    /*自定义槽:普通函数的用法
     * QT5:任意的成员函数,普通全局函数,静态函数
     * 槽函数需要和信号一致(参数,返回值)
     * 由于信号没有返回值,所以槽函数一定没有返回值
*/
//released是释放时在变化  pressed是按下就变化
    connect(b2,&QPushButton::released,this,&MainWidget::mySlot);//b2本来就是一个指针,不用在取地址

    connect(b2,&QPushButton::released,&b1,&MainWidget::hide);//hide隐藏
    /*信号:短信
     * 槽函数:接收短信的手机*/


    setWindowTitle("老大");
  // this->setWindowTitle("老大")和上面的一句完全等价
    b3.setParent(this);
    b3.setText("切换到子窗口");
    b3.move(50,50);

    //显示子窗口
    //w.show();
    //这时候是两个窗口都显示出来,到那时我们的目的是按一个显示另一个

    connect(&b3,&QPushButton::released,this,&MainWidget::changeWin);
  //现在可以做到,从主窗口调用子窗口,但是还没有做到子窗口随时调用主窗口,这是需要Signal的

    //处理子窗口的信号
    connect(&w,&SubWidget::mySignal,this,&MainWidget::dealSub);

    resize(400,300);//保证窗口大小
}

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

void MainWidget::changeWin()
{
    //子窗口显示,
    w.show();   //SubWidget w;mainwidget.h中的代码
    //本窗口隐藏
    this->hide();
}

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

MainWidget::~MainWidget()
{

}

subwidget.cpp中代码:

#include "subwidget.h"

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

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

             resize(400,300);
}

void SubWidget::sendSlot()
{**加粗样式**
    emit mySignal();
}

main 中保持不变

四、两个信号处理(指针函数)

mainwidget.h中的代码:

#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 dealSub();//处理子窗口函数
    void dealSlot(int ,QString);

private :
   QPushButton b1;
   QPushButton *b2;
   QPushButton b3;

   SubWidget subWin;

};

#endif // MAINWIDGET_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);

    void sendSlot();

signals:
    /*信号必须有signals这个关键字来声明
     * 信号没有返回值,但是可以有参数
     * 信号就是函数的声明,只需要声明无需定义
     * 使用:mySignal();
      信号可以重载*/
    //子窗口没有办法调用主窗口,所以让子窗口发射一个信号,然后给主窗口,让主窗口去处理这个信号
    void mySignal();
     void mySignal(int,QString);

public slots:
private:
    QPushButton b;
};

#endif // SUBWIDGET_H

mainwidget.cpp中代码:

#include "mainwidget.h"
#include <QPushButton>
#include <QDebug>//打印的头文件

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    b1.setParent(this);
    b1.setText("close");
    b1.move(100,100);

    b2 = new QPushButton(this);
    b2->setText("ABC");

    connect(&b1,&QPushButton::pressed,this,&MainWidget::close);
    /*&b1:信号发出者,指针类型
     * &QPushButton::pressed():处理的信号 &发送者类名::信号名字
     * this:信号接受者
     * &MainWidget::close:槽函数,信号处理函数  &接收的类名::槽函数名字
*/

    /*自定义槽:普通函数的用法
     * QT5:任意的成员函数,普通全局函数,静态函数
     * 槽函数需要和信号一致(参数,返回值)
     * 由于信号没有返回值,所以槽函数一定没有返回值
*/
//released是释放时在变化  pressed是按下就变化
    connect(b2,&QPushButton::released,this,&MainWidget::mySlot);//b2本来就是一个指针,不用在取地址

    connect(b2,&QPushButton::released,&b1,&MainWidget::hide);//hide隐藏
    /*信号:短信
     * 槽函数:接收短信的手机*/


    setWindowTitle("老大");
  // this->setWindowTitle("老大")和上面的一句完全等价
    b3.setParent(this);
    b3.setText("切换到子窗口");
    b3.move(50,50);

    //显示子窗口
    //w.show();
    //这时候是两个窗口都显示出来,到那时我们的目的是按一个显示另一个

    connect(&b3,&QPushButton::released,this,&MainWidget::changeWin);
  //现在可以做到,从主窗口调用子窗口,但是还没有做到子窗口随时调用主窗口,这是需要Signal的

    //处理子窗口的信号
    //函数指针
   void (SubWidget::*funSignal)()=&SubWidget::mySignal;
   connect(&subWin,funSignal,this,&MainWidget::dealSub);

   void (SubWidget::*testSignal)(int ,QString)=&SubWidget::mySignal;
  connect(&subWin,testSignal,this,&MainWidget::dealSlot);
    
    
    resize(400,300);//保证窗口大小
}

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

void MainWidget::changeWin()
{
    //子窗口显示,
    subWin.show();   //SubWidget w;mainwidget.h中的代码
    //本窗口隐藏
    this->hide();
}

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

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

MainWidget::~MainWidget()
{

}

subwidget.cpp中代码:

#include "subwidget.h"

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

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

             resize(400,300);
}

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

main中不变

五、Lambda表达式(传值)

只是改变了mainwidget.cpp

#include "mainwidget.h"
#include <QPushButton>
#include <QDebug>//打印的头文件

MainWidget::MainWidget(QWidget *parent)
    : QWidget(parent)
{
    b1.setParent(this);
    b1.setText("close");
    b1.move(100,100);

    b2 = new QPushButton(this);
    b2->setText("ABC");

    connect(&b1,&QPushButton::pressed,this,&MainWidget::close);
    /*&b1:信号发出者,指针类型
     * &QPushButton::pressed():处理的信号 &发送者类名::信号名字
     * this:信号接受者
     * &MainWidget::close:槽函数,信号处理函数  &接收的类名::槽函数名字
*/

    /*自定义槽:普通函数的用法
     * QT5:任意的成员函数,普通全局函数,静态函数
     * 槽函数需要和信号一致(参数,返回值)
     * 由于信号没有返回值,所以槽函数一定没有返回值
*/
//released是释放时在变化  pressed是按下就变化
    connect(b2,&QPushButton::released,this,&MainWidget::mySlot);//b2本来就是一个指针,不用在取地址

    connect(b2,&QPushButton::released,&b1,&MainWidget::hide);//hide隐藏
    /*信号:短信
     * 槽函数:接收短信的手机*/


    setWindowTitle("老大");
  // this->setWindowTitle("老大")和上面的一句完全等价
    b3.setParent(this);
    b3.setText("切换到子窗口");
    b3.move(50,50);

    //显示子窗口
    //w.show();
    //这时候是两个窗口都显示出来,到那时我们的目的是按一个显示另一个

    connect(&b3,&QPushButton::released,this,&MainWidget::changeWin);
  //现在可以做到,从主窗口调用子窗口,但是还没有做到子窗口随时调用主窗口,这是需要Signal的

    //处理子窗口的信号
    //函数指针
   void (SubWidget::*funSignal)()=&SubWidget::mySignal;
   connect(&subWin,funSignal,this,&MainWidget::dealSub);

   void (SubWidget::*testSignal)(int ,QString)=&SubWidget::mySignal;
  connect(&subWin,testSignal,this,&MainWidget::dealSlot);
   //Lambda表达式,匿名函数对象
  //C++增加的新特征,项目文件:CONFIG += C++11
  //Qt配合信号一起使用,非常方便
       QPushButton *b4= new QPushButton(this);
       b4->setText("Lambda表达式");
        b4->move(150,150);
        int a=10;int b=100;
       connect(b4,&QPushButton::released,
              // [b4]()                   //函数的表达式就是  void 函数名 ()  {    }  就是多了一个[]
               //[]作用就是把外部变量传进来,如果不写[b4],下面{中里面有b4就会报错}
               //=:把外部所有局部变量,类中所有成员值传递进来
               //默认是只读的,如若{a=11}会报错,如果要修改,写[=]() mutable
              // [=]() mutable
               //this指针:类中所有成员以值传递方式
               //&:把外部所有局部变量,引用符号
               [=]()//常用等号
       {
                   b4->setText("1223");
                   qDebug()<<"1111";
                   qDebug()<<a<<b;
                  // a=11;
       }
               );

    resize(400,300);//保证窗口大小
}

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

void MainWidget::changeWin()
{
    //子窗口显示,
    subWin.show();   //SubWidget w;mainwidget.h中的代码
    //本窗口隐藏
    this->hide();
}

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

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

MainWidget::~MainWidget()
{

}

改为clicked:

//Lambda表达式,匿名函数对象
  //C++增加的新特征,项目文件:CONFIG += C++11
  //Qt配合信号一起使用,非常方便

       QPushButton *b4= new QPushButton(this);
       b4->setText("Lambda表达式");
        b4->move(150,150);
        int a=10;int b=100;
       connect(b4,&QPushButton::clicked,
              // [b4]()                   //函数的表达式就是  void 函数名 ()  {    }  就是多了一个[]
               //[]作用就是把外部变量传进来,如果不写[b4],下面{中里面有b4就会报错}
               //=:把外部所有局部变量,类中所有成员值传递进来
               //默认是只读的,如若{a=11}会报错,如果要修改,写[=]() mutable
              // [=]() mutable
               //this指针:类中所有成员以值传递方式
               //&:把外部所有局部变量,引用符号
               [=](bool isCheck)//常用等号
       {
               qDebug()<<isCheck;
       }
               );

总结:

1、指定父对象 和 不指定父对象:
如果不指定父对象。对象和对象(窗口和窗口)没有关系,独立
a指定b为他的父对象,相当于a放在b的上面
指定父对象有两种方式:
(1)setParent
(2)通过构造函数传参
指定父对象,只需要父对象显示,上面的子对象自动显示
2、创建两个独立窗口:
点击项目名字——右击——新建文件——C++——C++class——选择QWidget——自己选择名字
但是没有反应,需要自己去进行关联
3、信号和槽:
处理信号借助connect函数,可以叫做信号链接。
connect(&b1,&QPushButton::pressed,this,&MainWidget::close);
&b1:信号发出者,指针类型
&QPushButton::pressed():处理的信号 &发送者类名::信号名字
this:信号接受者
&MainWidget::close:槽函数,信号处理函数 &接收的类名::槽函数名字
信号和槽:Qt对象之间通信的借口
4、查信号:看帮助文档
点中——F1——在父类中找——Signal——点进去信号会有信号的声明,功能
5、函数
close:关闭窗口
自定义常函数:没有返回值,没有参数
6、自定义信号
小弟没法命令老大,所以要发射信号给老大,让老大去处理信号
signals:
信号必须有signals这个关键字来声明
信号没有返回值,但是可以有参数
信号就是函数的声明,只需要声明无需定义
使用:mySignal();
7、Lambda表达式(传值)
传值尽量用这个函数,而不要用那个信号重载的方式

猜你喜欢

转载自blog.csdn.net/weixin_43384257/article/details/88619322