对话框QDialog
QDialog
用于表示 Qt 中的对话框,对话框也可以是一个项目的主控件,但更多会在 Widget 或 Main Windows 中创建出来使用。QDialog
是所有对话框的父类,其他对话框都继承自 QDialog
,因此 QDialog
拥有的方法和属性,其他对话框也拥有。
1. QDialog方法
方法 | 说明 |
---|---|
setAttribute() | 这是 QWidget 的方法,在 QDialog 一般用于在非模态窗口中控制对话框的释放时机。 |
exec() | 模态方式显示对话框,调用后会阻塞,直到对话框关闭,并返回结果。 |
show() | 非模态方式显示对话框,调用后不会阻塞。 |
2. QDialog信号
信号 | 说明 |
---|---|
void accepted() | 当对话框被接受时发出。 |
void rejected() | 当对话框被拒绝时发出。 |
void finished(int result) | 当对话框被关闭时发出。 |
3. QDialog的内存泄漏问题
QDialog
通过代码创建时,有可能将其挂载到父控件上,调用 show()
后就不管它了。但这其实存在内存泄漏的问题,因为创建一个 QDialog
是在堆上创建,其生命周期是随程序结束的。 但是在一个项目中,往往会需要弹出很多对话框,但又不会结束整个项目,所以 QDialog
的析构问题是必须要解决的问题。
我们希望的效果是,QDialog
在点击右上角关闭后,就调用析构将它的空间释放。实际 Qt 也提供了的接口来方便程序员设置,使用 setAttribute(Qt::WA_DeleteOnClose)
就可以实现在关闭 QDialog
时释放空间 :
QDialog* dialog = new QDialog(this);
dialog->show();
dialog->setAttribute(Qt::WA_DeleteOnClose);
4. 自定义类继承QDialog实现自定义对话框
新建一个 C++ 并选择继承自 QDialog
类,这样我们的自定义类型就能使用 QDialog
的所有方法了:
注意生成的文件可能还是有点问题,父类的头文件还需要自己手动包含:
如果想要将自定义的类型能够挂载到对象树上,还可以改造一下构造函数:
mainwindows.cpp:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
void handler();
private slots:
void on_pushButton_clicked();
private:
Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H
dialog.cpp:
#include "dialog.h"
#include <QVBoxLayout>
#include <QPushButton>
#include <QLabel>
Dialog::Dialog(QWidget* parent):QDialog(parent)
{
QVBoxLayout* Vlayout=new QVBoxLayout();
this->setLayout(Vlayout);
QPushButton* button=new QPushButton("关闭");
QLabel* label=new QLabel("对话框标签");
Vlayout->addWidget(label);
Vlayout->addWidget(button);
connect(button,&QPushButton::clicked,this,&Dialog::handler);
}
void Dialog::handler()
{
this->close();
}
5. 新建ui文件使用图形化编辑对话框
也可以通过新建 ui 文件来使用 ui 界面设计对话框,首先新建文件:
点击一路点击下一步可以看到多了一个 ui 界面:
点击进入对话框的 ui 界面可以对其进行编辑:
mainwindows.cpp:
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include "dialog.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
}
MainWindow::~MainWindow()
{
delete ui;
}
void MainWindow::on_pushButton_clicked()
{
Dialog* dialog=new Dialog(this);
dialog->show();
dialog->setAttribute(Qt::WA_DeleteOnClose);
}
dialog.cpp:
#include "dialog.h"
#include "ui_dialog.h"
Dialog::Dialog(QWidget *parent) :
QDialog(parent),
ui(new Ui::Dialog)
{
ui->setupUi(this);
}
Dialog::~Dialog()
{
delete ui;
}
void Dialog::on_pushButton_clicked()
{
this->close();
}
6. 模态对话框与非模态对话框
模态对话框,是弹出对话框时,用户无法对父窗口进行操作,必须完成对话框的操作,关闭对话框后才能操作父窗口。一般用于对话框弹出重要信息时使用。
非模态对话框则相反,弹出对话框时,也可以对父窗口进行操作。
切换模态对话框与非模态对话框的方法很简单,只需要将 show()
改为 exec()
即可。
QDialog* dialog1 = new QDialog(this);
dialog1->show(); //非模态对话框
Dialog* dialog2 = new QDialog(this);
dialog1->exec(); //模态对话框