QT_Day01_应用框架_项目文件_父窗口和子窗口的区别_信号和槽_坐标系统_内存回收机制_菜单栏窗口_对话框

QT_Day01

1.应用框架

1.1main.cpp

```
#include "mywidget.h"
//应用程序类QApplication
//QT头文件木有.h
//头文件和类名一致
#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);//有且只有一个应用程序类的对象
    MyWidget w;//MyWidget继承QWidget,QWidget是一个窗口基类
    //MyWidget也是一个窗口类,w就是一个窗口;
    w.show();//窗口创建默认隐藏,需要人为显示;
    //a.exec();让程序一致执行,等待用户的操作;也就是等待事件的发生;
    return a.exec();//return a.exec();与分开两句是一样的效果,a.exec();和return 0;
}

1.2mywidget.h文件

```
#ifndef MYWIDGET_H
#define MYWIDGET_H

#include <QWidget>

class MyWidget : public QWidget
{
    Q_OBJECT//信号与槽的时候需要

public:
    MyWidget(QWidget *parent = 0);//构造函数。可以按F4跳过去看;
    ~MyWidget();//析构函数;
};

#endif // MYWIDGET_H

2.项目文件

```
#注释是需要用#的;
#模块--到.h文件,光标到QWidget,按F1跳到对应的帮助文档;
#包含头文件需要的模块,需要进行添加
QT       += core gui

#高于4版本,需要添加QT+=widgets,为了兼容QT4;
greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
#应用程序exe的名字;
TARGET = 01_QtTest
#指定makefile的类型,app,可以生成库文件lib
TEMPLATE = app


DEFINES += QT_DEPRECATED_WARNINGS


#源文件.cpp文件
SOURCES += \
        main.cpp \
        mywidget.cpp
#头文件.h文件
HEADERS += \
        mywidget.h

2.1QT5的模块

3.父窗口和子窗口

  • 如何指定子类对象?
    • 通过setParent来指定父窗口: b.setParent(&w);
    • 通过构造函数传参来指定父窗口:b2 = new QPushButton(this);
  • 指定父对象的好处?
    • 子窗口在父窗口上
    • 运行只需要运行父窗口就可以显示,子窗口不用.show();

3.1main.cpp

```
#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.setParent(&w);
    b.move(100,100);//移动坐标;位置;
    QPushButton b1(&w);//通过构造函数传参
    b1.setText("abc");

    w.show();
    /*
     *如果不指定父对象,窗口和窗口是独立的,木有关系的。
     * a指定b作为它的父对象,a放在b上,
     * 指定父对象:有2种方式:
     * (1)setParent(2)通过构造函数传参
     * 指定父对象,只需要父对象显示,上面的子对象自动显示
     */
    app.exec();
    return 0;
}
  • 运行截图:

3.信号和槽signals and slots

在mainWidgets.cpp进行编写代码,类似于分层编写函数;

  • 1.在对应得.h文件,写所需添加的头文件,以及一些成员的声明

  • 2.在mainWidgets.cpp中进行定义,在构造函数或者新建一个函数中定义内容;

  • 3.main()函数中调用函数;

  • 举个点击按钮进行关闭窗口操作:

  • .h文件

    #ifndef MAINWIDGET_H
    #define MAINWIDGET_H
    
     #include <QWidget>
     #include<QPushButton>
     class MainWidget : public QWidget
     {
         Q_OBJECT
    
     public:
         MainWidget(QWidget *parent = 0);
         ~MainWidget();
     private:
         QPushButton b1;
         QPushButton *b2;
     };
    
     #endif // MAINWIDGET_H
    
    
  • mainWidgets.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("HelloWorld");
        connect(&b1,&QPushButton::pressed,this,&MainWidget::close);
        /*&b1:信号发出者,指针类型
         * &QPushButton::pressed:处理的信号,&发送者的类名::信号名
         * this:信号接收者
         * &MainWidget::close:槽函数,信号处理函数,&接收的类名::槽函数名字
            */
    }
    
    MainWidget::~MainWidget()
    {
    
    }
    
    

3.1标准信号和槽

  • 信号和槽用于两个对象之间的通信。是QT的核心,也是不同于其他开发框架的最突出特征;
  • 在GUI中,一个信号发生变化,总希望其他部件也能了解到该变化;
  • 为实现对象间的通信,一些工具包中使用回调callback机制,而在QT中方使用了信号和槽之间来进行对象间的通信。
  • 当一个特殊的事件发生时便可以发射一个信号,比如按钮被单击就发射cliced()信号,而槽就是一个函数,它在信号发射后被调用来相应这个信号。
  • 一个信号一个槽,其实,一个信号可以关联到多个槽上,多个信号也可以关联到同一个槽上,甚至,另一个信号还可以关联到另一个信号上。
  • 如果存在多个槽与某个信号关联,那么,这个信号被发射时,这些槽将会一个接一个地执行,执行顺序与关联顺序相同。
  • 标志信号和槽函数的例子编写:
    #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("HelloWorld");
        connect(&b1,&QPushButton::pressed,this,&MainWidget::close);
        /*&b1:信号发出者,指针类型
         * &QPushButton::pressed:处理的信号,&发送者的类名::信号名
         * this:信号接收者
         * &MainWidget::close:槽函数,信号处理函数,&接收的类名::槽函数名字
            */
    }
    

3.2自定义槽函数

  • mainWidgets.cpp代码:
        MainWidget::MainWidget(QWidget *parent)
         : QWidget(parent)
     {
         b1.setParent(this);
         b1.setText("close");
         b1.move(100,100);
    
         b2 = new QPushButton(this);
         b2->setText("HelloWorld");
         connect(&b1,&QPushButton::pressed,this,&MainWidget::close);
         /*&b1:信号发出者,指针类型
          * &QPushButton::pressed:处理的信号,&发送者的类名::信号名
          * this:信号接收者
          * &MainWidget::close:槽函数,信号处理函数,&接收的类名::槽函数名字
             */
    
         /*
          *自定义槽,普通函数的用法
          * Qt5:任意的成员函数,普通的全局函数,静态函数
          * 槽函数需要和信号一致(参数,返回值)
          * 由于信号都是木有返回值的,所以,槽函数一定木有返回值;
        */
         connect(b2,&QPushButton::released,this,&MainWidget::mySlot);
         //功能:按下b2按键,换成123
          connect(b2,&QPushButton::released,&b1,&QPushButton::hide);
         //抬起按钮时,b1接收信号隐藏按钮;
          /*
           * 信号:短信 
           * 槽函数:接收短信的手机
          */
     }
     void MainWidget::mySlot()
     {
         b2->setText("123");
     }
    
  • .h代码:
    class MainWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        MainWidget(QWidget *parent = 0);
        ~MainWidget();
        void mySlot();
    private:
        QPushButton b1;
        QPushButton *b2;
    };
    

3.3两个独立的窗口

  • 信号发送是 emit released();;connect作为绑定一个信号发送者以及信号的地方,从来都不是它负责发送信号的

  • 子窗体是父窗体的一个成员对象。两个独立的窗体之间不可能建立信息的传递,除非是像这样子在这个主窗体的项目上新建一个窗口。

  • 子窗口是在父窗口内运行的,在子窗口发送信号,父窗口可以收到信号。

  • 为什么把所有的代码都放构造函数?因为程序运行会第一时间执行构造函数,这样子我们的代码就可以运行;

  • 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 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关键字来声明
         * 信号木有返回值,但可以有参数
         * 信号就是函数的声明,只需要声明,无需定义
         * 使用:emit mySignal();
        */
        void mySignal();
    public slots:
    private:
        QPushButton b;
    };
    #endif // SUBWIDGET_H
    
    
  • main.cpp代码:

    #include "mainwidget.h"
    #include <QApplication>
    
    int main(int argc, char *argv[])
    {
        QApplication a(argc, argv);
        MainWidget w;
        w.show();
    
        return a.exec();
    }
    
    
  • mainwidget.cpp代码:

     #include "mainwidget.h"
     #include<QPushButton>
    
    
     MainWidget::MainWidget(QWidget *parent)
         : QWidget(parent)
     {
         b1.setParent(this);
         b1.setText("close");
         b1.move(100,100);
          setWindowTitle("老大");//等价于this->setWindowTitle("老大");
          b3.setParent(this);
          b3.setText("切换到子窗口");
          b3.move(50,50);
    
          //显示子窗口;
        //  w.show();
          connect(&b3,&QPushButton::released,this,&MainWidget::changeWin);
          //处理子窗口的信号
          connect(&w,&SubWidget::mySignal,this,&MainWidget::dealSub);
         resize(400,300);//如果不设置宽度,高度。则窗口跳转过程会窗口缩小;
     }
    
     void MainWidget::changeWin()
     {
        //子窗口显示
         w.show();
         //本窗口隐藏
         this->hide();
     }
    
     void MainWidget::dealSub()
     {
         //子窗口隐藏
          w.hide();
          //本窗口显示
          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);
        //这里connect只是作为绑定一个信号发送者以及信号的地方,
        resize(400,300);//如果不设置宽度,高度。则窗口跳转过程会窗口缩小;
    }
    void SubWidget::sendSlot()
    {
        emit mySignal();
    }
    
    
    
    

如何查看标志的信号函数?

  • 点中控件按钮--QPushButton后按F1,--找到父类QAbstractButton后点击--signals--跳转页面后可以找到标准函数。

3.4带参数的信号

  • 信号也可以重载,重载需要考虑的是二义性的问题;

  • 程序是day01——03_SignalAndSolt:

  • mainWidget.h的代码:

    class MainWidget : public QWidget
    {
        Q_OBJECT
    
    public:
        MainWidget(QWidget *parent = 0);
        ~MainWidget();
    //public slots:
        //QT4所需要访问权限和slots来修饰槽函数;
        void mySlot();
        void changeWin();
        void dealSub();//处理子窗口
        void dealSlot(int,QString);
    private:
        QPushButton b1;
    
        QPushButton b3;
    
        SubWidget sub;
    };
    
    
  • subwidget.h的代码:

    class SubWidget : public QWidget
    {
        Q_OBJECT
    public:
        explicit SubWidget(QWidget *parent = nullptr);
        void sendSlot();
    
    signals:
        //声明一个信号;
        /*
         * 信号必须有signals关键字来声明
         * 信号木有返回值,但可以有参数
         * 信号就是函数的声明,只需要声明,无需定义
         * 使用:emit mySignal();
        */
        void mySignal();
        void mySignal(int,QString);
    public slots:
    private:
        QPushButton b;
    };
    
  • mainWidget.cpp函数:

     connect(&b3,&QPushButton::released,this,&MainWidget::changeWin);
     //处理子窗口的信号
     void (SubWidget::*funSignal)() = &SubWidget::mySignal;
     connect(&sub,funSignal,this,&MainWidget::dealSub);
     //如果重载信号,而且重载的时候会产生二义性;
     void (SubWidget::*testSignal)(int,QString) = &SubWidget::mySignal;//处理二义性语句
     connect(&sub,testSignal,this,&MainWidget::dealSlot);
    
    
    
     //QT4的信号链接比较简单;
     //QT4槽函数必须有slots关键字来修饰
     //connect(&sub,SIGNAL(mySignal()),this,SLOT(dealSub()));
     //connect(&sub,SIGNAL(mySignal(int,QString)),this,SLOT(dealSlot(int,QString)));
     //QT4会容易出错,这是为什么不建议使用的原因:SIGNAL SLOT将函数名字->字符串 不进行错误检查;
    
  • subwidget.cpp的代码:

    SubWidget::SubWidget(QWidget *parent) : QWidget(parent)
    {
        this->setWindowTitle("小弟");
        b.setParent(this);
        b.setText("切换到主窗口");
        connect(&b,&QPushButton::clicked,this,&SubWidget::sendSlot);
        //这里connect只是作为绑定一个信号发送者以及信号的地方,
        resize(400,300);//如果不设置宽度,高度。则窗口跳转过程会窗口缩小;
    }
    void SubWidget::sendSlot()
    {
        emit mySignal();
        //信号有参数,则槽函数也必须有int;
        emit mySignal(250,"我是子窗口");//应用程序输出;
    }
    
    
    

5.Lambda表达式,是一个匿名函数对象

  • C++11增加的新特性,需要在项目文件添加:CONFIG += C++11

  • QT配合信号一起使用,非常方便;方便在于:不用定义常函数,不用指定接收者;

  • 信号无参数的代码:

     /*
      * Lambda表达式,是一个匿名函数对象
        * C++11增加的新特性,需要在项目文件添加:CONFIG += C++11
        * QT配合信号一起使用,非常方便;方便在于:不用定义常函数,不用指定接收者;
    */
     QPushButton *b4 = new QPushButton(this);
     b4->setText("Lambda表达式");
     b4->move(150,150);
     int a = 10,b = 100;
     connect(b4,&QPushButton::released,
     [=]() mutable
             //[]  =:把外部所有局部变量、类中所有成员以值传递方式传进来;常用
             //this:类中所有成员以值传递方式
             //& :引用符号的方式传进,把外部所有局部变量传进;
             //举例子:b4也是一个外部局部变量,如果引用(引用其实就是变量本身)符号,则会出现数据错误,因为在操作b4这个按钮,这个里面的内存还木有释放,则会出现错误;
             //外部局部变量是一个按钮,是动态内存空间,则不要用引用,
     {
         b4->setText("123456");//这样子写(当[]里面什么都木有写的时候)会出现错误,说b4不在这个作用域上,
         //则如何更正这个方法?则[]括号的作用:把外部变量传进来,可以传很多个;但如果很多个参数,一个一个输入则会很麻烦,
         //如何更正?则使用=号,=:把外部所有局部变量、类中所有成员以值传递方式传进来;
         //**但有一个局限性,以值传递的方式默认只修饰为只读,则是不能修改原本值的数据。否则会保错。
         //如何将这个局限性去除呢?在[]()的后面加一个mutable。则说明这是可变的,则里面的变量是可以修改的;
         qDebug()<<"1111111";
         b = 200;
         qDebug()<<a<<b;
     });//有信号发送后立即调用这个qDebug();函数:void fun(){};
     //这个Ladbam是匿名,则木有名字;
    
    
  • 如果信号带有参数,Ladbam表达式该如何去写?代码:

         //如果信号有参数时:
     //clicked:这个函数默认带有参数,无重载,则点击他就会返回一个false
     connect(b4,&QPushButton::clicked,
     [=](bool isCheck)
             //[]  =:把外部所有局部变量、类中所有成员以值传递方式传进来;常用
             //this:类中所有成员以值传递方式
             //& :引用符号的方式传进,把外部所有局部变量传进;
     {
         qDebug()<<isCheck;
    
     });
    
    
  • 注意:不是按钮发送信号,是点击按钮去调用这个发送信号的函数代码;

6.坐标系统

  • 代码:(运行结果如下)
     move(100,100);//为什么按钮和主窗口移动都是用move;
    //因为move是基类继承过来的函数,所有的都可以用他;
    /*
     * 对于父窗口(主窗口),坐标系统相对于屏幕;
     * 原点:相对于屏幕左上角
     * x:往右递增;
     * y:往下递增;
    */
    
    QPushButton *b1 = new QPushButton(this);
    b1->move(0,0);
    b1->setText("壳子");
    b1->resize(200,200);
    /*
     * 子窗口的坐标系统相对于父窗口
     * 原点:相对于窗口空白区域(不包括边框)
     * x:往右递增;
     * y:往下递增;
    */
    
    QPushButton *b2 = new QPushButton(b1);
    b2->move(10,10);
    b2->setText("/(ㄒoㄒ)/~~");
    

7.内存回收机制(day01-04_QT_zuobiao)

  • 创建使用动态分配空间的变量,按照C++的说法,需要手动去释放空间;delete ;不释放内存空间则会内存泄漏;

  • 在QT中,会有一个对象树,但有个条件就是,需要变量或者类都继承于QObject;这个对象树,在程序结束时候自动回收,不需要我们手动去回收;下面是一个QObject树图;

  • 当程序结束的时候,会自动回收,则如何回收呢?先从树的地下开始回收。

  • 如何验证是否是自动释放?

    • 因为那个QPushButton按钮不是我们自己写的,木有办法再析构函数哪里打印验证是否释放了的;

    • 所以我们要自己写个按钮,右点新建一个C++类,MyButton

    • 按钮是QPushButton,所以我们将基类该为QPushButton;在mybutton.h里面也需要改父类成QPushButton;
      ```
      #ifndef MYBUTTON_H
      #define MYBUTTON_H
      #include
      class MyButton : public QPushButton
      {
      Q_OBJECT
      public:
      explicit MyButton(QWidget *parent = nullptr);
      ~MyButton();
      signals:
      public slots:
      };
      #endif // MYBUTTON_H

    • 在mybutton.cpp里面也需要将父类改为QPushButton;
      ```
      #ifndef MYWIDGET_H
      #define MYWIDGET_H

        #include <QWidget>
      
        class MyWidget : public QWidget
        {
            Q_OBJECT
      
        public:
            MyWidget(QWidget *parent = 0);
            ~MyWidget();
        };
      
        #endif // MYWIDGET_H
      

  • 在myButton.c函数代码:

    #include "mybutton.h"
    #include <QDebug>
    MyButton::MyButton(QWidget *parent) : QPushButton(parent)
    {
    
    }
    
    MyButton::~MyButton()
    {
        qDebug()<<"析构函数被调用";
    }
    
    
  • 在mywidget.cpp中的代码:

    MyWidget::MyWidget(QWidget *parent)
    : QWidget(parent)
    

{
move(100,100);//为什么按钮和主窗口移动都是用move;
//因为move是基类继承过来的函数,所有的都可以用他;
/*
* 对于父窗口(主窗口),坐标系统相对于屏幕;
* 原点:相对于屏幕左上角
* x:往右递增;
* y:往下递增;
*/

QPushButton *b1 = new QPushButton(this);
b1->move(0,0);
b1->setText("壳子");
b1->resize(200,200);
/*
 * 子窗口的坐标系统相对于父窗口
 * 原点:相对于窗口空白区域(不包括边框)
 * x:往右递增;
 * y:往下递增;
*/

QPushButton *b2 = new QPushButton(b1);
b2->move(10,10);
b2->setText("/(ㄒoㄒ)/~~");
MyButton *b3 = new MyButton(this);
b3->setText("123");
b3->move(100,100);
//添加:(1)指定父对象后,(2)直接或间接继承于QObject;
//子对象如果是动态分配空间的new,不需要手动释放delete,系统会自动释放;

8.菜单栏——工具栏(day01_05_QMainWindow)

8.1要素

  • 8.1.1基类是QMainWindow
  • 8.1.2菜单栏
    • 代码:
    //菜单栏
    QMenuBar *mBar = menuBar();
    //添加菜单的内容
    QMenu *pFile = mBar->addMenu("文件");
    //点击弹出菜单项目(添加菜单项/动作)
    QAction *pNew = pFile->addAction("新建");
    connect(pNew,&QAction::triggered,
            [=]()
            {
                qDebug()<<"新建被按下";
             }
            );
    //添加分隔线;
    pFile->addSeparator();
    QAction *pOpen = pFile->addAction("打开");
    

  • 8.1.3工具栏
    //工具栏,菜单项的快捷方式;
    QToolBar *toolBar = addToolBar("toolBar");//新建一个工具栏
    //工具栏添加快捷键
    toolBar->addAction(pNew);
    QPushButton *b = new QPushButton(this);
    b->setText("😊");
    toolBar->addWidget(b);//添加小控件
    connect(b,&QPushButton::clicked,
            [=]()
            {
                b->setText("/(ㄒoㄒ)/~~");
             }
            );
    

  • 8.1.4核心控件
    *文本编辑label
    //核心控件:文本编辑器
    QTextEdit *textEdit = new QTextEdit(this);
    setCentralWidget(textEdit);//文件编辑器
    

  • 8.1.5状态栏
    //状态栏
    QStatusBar *sBar = statusBar();
    //标签
    QLabel *label = new QLabel(this);
    label->setText("Normal text file");
    sBar->addWidget(label);
    //addwidget--从左往右添加;
    sBar->addWidget(new QLabel("2",this));
    sBar->addPermanentWidget(new QLabel("33",this));//从右往左;
    

  • 8.1.6 浮动窗口
    • 代码,:
    //浮动窗口
    QDockWidget *dock = new QDockWidget(this);
    addDockWidget(Qt::RightDockWidgetArea,dock);//需要填写东西才可以查看帮助文档,就算数据不对也可;
    // addDockWidget(放置的位置:查看帮助文档F1查看,浮动窗口对象);
    //给浮动窗口添加控件;
    QTextEdit *textEdit1 = new QTextEdit(this);
    dock->setWidget(textEdit1);//在浮动窗口设置一个文本编辑区;
    

  • 8.1.6代码需要添加的头文件如下:
    #include "mainwindow.h"
    #include<QMenuBar>//菜单栏需要包含的头文件
    #include <QMenu>//需要菜单头文件
    #include <QAction>
    #include <QDebug>//打印输出包含头文件;
    #include <QToolBar>//工具栏需要的头文件
    #include <QPushButton>
    #include <QStatusBar>//状态栏;
    #include <QLabel>//标签头文件;
    #include <QTextEdit>//文件编辑器所需要的头文件
    #include <QDockWidget>//浮动窗口所需的头文件
    

9.模态和非模态对话框

  • 模态:只能操作该对话框的内容
  • 非模态:在能操作当前对话框的同时,也能对其他地方的对话框进行操作;
  • 包含的头文件:
    #include <QMenu>
    #include <QMenuBar>
    #include <QAction>
    #include <QDialog>
    #include <QDebug>
    
  • 代码:
    QMenuBar *mBar = menuBar();
    setMenuBar(mBar);//设定菜单栏,不设置也会有;
    QMenu *menu = mBar->addMenu("对话框");
    //模态对话框
    QAction *p1 = menu->addAction("模态对话框");
    connect(p1,&QAction::triggered,
            [=]()
            {
                QDialog dlg;
                dlg.exec();//固定的显示对话框在界面上;
                qDebug()<<"11111";
            }
            );
    
    //非模态对话框
    QAction *p2 = menu->addAction("非模态对话框");
    connect(p2,&QAction::triggered,
            [=]()
            {
        /*
              //QDialog dlg;
                dlg.show();//一闪而过?为什么?是因为运行之后就不存在了,就释放了内存空间,解决方式:可以将对话框对象设置为一个成员
    
                qDebug()<<"22222";
                */
    
                /*
                //如果非要使用局部变量,则给她动态分配空间;
                QDialog *p = new QDialog(this);
                p->show();
                 该方法有一个不会的地方,这个窗口会是在程序结束的时候才释放;
                 * 假如持续性的点击按钮,则会分配很多个内存空间;会导致内存占用很多;
                */
    
                //更正内存占用较多问题:
                QDialog *p = new QDialog;//不指定父对象,因为指定父对象,可以在程序结束后自动释放;那不指定父对象如何释放?
                p->setAttribute(Qt::WA_DeleteOnClose);//setAttribute函数,在窗口关闭的时候自动释放内存空间;
                p->show();
    
            }
            );
    

10.标准对话框和文件对话框

10.1标准对话框

  • 标准对话框的头文件:#include //对话框
  • 代码:
    QAction *p3 = menu->addAction("关于对话框");
    connect(p3,&QAction::triggered,
            [=]()
            {
        //是一个静态。如何调用,通过类名::方法名;
                QMessageBox::about(this,"about","关于QT");//只有一个ok按钮的对话框
            }
            );
             //关于问题的一个对话框
            QAction *p4 = menu->addAction("问题对话框");
            connect(p4,&QAction::triggered,
                    [=]()
                    {
                    //是一个静态。如何调用,通过类名::方法名;
                      int ret =  QMessageBox::question(this,"question","Are you ok?",
                                                       QMessageBox::Ok|QMessageBox::Cancel);//返回的是一个枚举值;
                        //不指定按钮则默认两个按钮:yes no
                      switch (ret) {
                      case QMessageBox::Yes:
                          qDebug()<<"I am ok";
                          break;
                      case QMessageBox::Cancel:
                          qDebug()<<"I am bad";
                          break;
                      default:
                          break;
                      }
    
    
                    }
                    );
    

10.2文件对话框

  • 头文件:#include //文件对话框
  • 代码:
     QAction *p5 = menu->addAction("文件对话框");
            connect(p5,&QAction::triggered,
                    [=]()
                    {
                    QString path = QFileDialog::getOpenFileName(this,"open","../",
                       "souce(*.cpp *.h);;Text(*.txt);;all(*.*)");//参数:指定父对象,标题,打开文件路径,该函数返回值是一个字符串;
                    qDebug()<<path;
                    }
                    );
            //这样子的文件对话框不能指定文件格式咧。
            //getOpenFileName按F1查看帮助文档,就是在该函数的第四个参数里面查看;
            //  tr("Images (*.png *.xpm *.jpg)")--tr是一个转换的字符,以空格分隔;但这个只是图片的格式;
            //"Images (*.png *.xpm *.jpg);;Text files (*.txt);;XML files (*.xml)"
posted @ 2022-04-14 10:22  镜姬  阅读(21)  评论(0编辑  收藏  举报