什么是模态和非模态对话框
点不了其他的功能和界面。这种对话框就称为模态对话框。还有一些能够操作其他的窗口属于非模态对话框。
下面新建一个工程,新建好之后,在设计界面中搭建如下图所示窗体(1、在菜单项中添加文件、编辑的菜单, 2、添加一个工具栏,3、在文件菜单中添加菜单项新建,并把新建放到工具栏中。) 现在,点击新建按钮,没有任何的反应,因此,我们要给它添加功能,当点击新建按钮后,跳出一个对话框。这就需要用到信号与槽的机制。
实现模态对话框
在代码中来实现一下。
创建对话框,需要添加头文件 #include <QDialog>
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDialog>
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->actionNew,&QAction::triggered,[=](){
QDialog dlg(this);
dlg.exec();
qDebug() << "模态对话框弹出了";
});
}
MainWindow::~MainWindow()
{
delete ui;
}
运行代码,点击新建按钮。会跳出对话框,如下图所示。 当出现该对话框后,再想要点击其他窗口,不可以做到。而且在应用程序输出窗口也没有打印出调试信息。这是因为我们创建的对话框是模态对话框,当程序运行后,会被阻塞在
dlg.exec();
这句代码,当关闭对话框后,代码接着往下执行,应用程序输出窗口才开始输出调试信息。 此外,还可以指定创建出来的对话框的大小。
connect(ui->actionNew,&QAction::triggered,[=](){
QDialog dlg(this);
dlg.resize(200,200);
dlg.exec();
qDebug() << "模态对话框弹出了";
});
实现非模态对话框
代码如下:
connect(ui->actionOpen,&QAction::triggered,[=](){
QDialog dlg2(this);
dlg2.resize(200,200);
dlg2.show();
qDebug() << "非模态对话框弹出了";
});
运行程序,会发现窗体一闪而过。
是因为执行完 dlg2.show(); 这句代码后,对话框就消失了。本质原因是这个对象被放置在栈上了,我们要把它放置在堆上面。
代码如下:
connect(ui->actionOpen,&QAction::triggered,[=](){
QDialog * dlg2 = new QDialog(this);
dlg2->resize(200,200);
dlg2->show();
qDebug() << "非模态对话框弹出了";
});
非模态对话框可以对其他窗口进行操作。
虽然利用上述代码可以实现一个非模态对话框,但是存在以下问题,一是每次点击都会重新在堆上创建出来一个对话框。 二是关闭对话框并不会释放堆上面的内存,只有关闭(总)窗体,这些堆上的对象才会释放。如果一直点下去,就会一直耗费内存资源。
那怎样解决呢?
可以通过设置这个对象的属性来解决。需要用到设置属性函数 setAttribute ,来查看下帮助文档。
那应该看哪一个下面的 setAttribute 函数介绍呢?我们写的是对话框,所以应该查看 QDialog 类下面的,但是帮助文档中并没有,我们就应该看它父类是谁,
var foo = 'bar';
可知,QDialog 继承与 QWidget ,所以应该看 QWidget 的 setAttribute 。 窗体的属性有很多,点 Qt::WidgetAttribute attribute,这一项进去看下(一般这样的、绿色的就代表着是枚举值。), 枚举值有很多,也代表着属性很多。
这里直接说下应该设置哪个属性,应该使用值为 55 的那个属性。
该属性可以在关闭对话框的时候就将其在堆上的内存给释放掉。
代码如下:
var foo = 'bar';
|