Qt窗口控件之对话框QDialog

发布于:2025-03-22 ⋅ 阅读:(12) ⋅ 点赞:(0)

对话框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 的所有方法了:

QDialog1

注意生成的文件可能还是有点问题,父类的头文件还需要自己手动包含:

QDialog2

如果想要将自定义的类型能够挂载到对象树上,还可以改造一下构造函数:

QDialog3


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

QDialog4

5. 新建ui文件使用图形化编辑对话框

也可以通过新建 ui 文件来使用 ui 界面设计对话框,首先新建文件:

QDialog5

点击一路点击下一步可以看到多了一个 ui 界面:

QDialog6

点击进入对话框的 ui 界面可以对其进行编辑:

QDialog7

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

QDialog8

6. 模态对话框与非模态对话框

模态对话框,是弹出对话框时,用户无法对父窗口进行操作,必须完成对话框的操作,关闭对话框后才能操作父窗口。一般用于对话框弹出重要信息时使用。

非模态对话框则相反,弹出对话框时,也可以对父窗口进行操作。

切换模态对话框与非模态对话框的方法很简单,只需要将 show() 改为 exec() 即可。

QDialog* dialog1 = new QDialog(this);
dialog1->show();	//非模态对话框

Dialog* dialog2 = new QDialog(this);
dialog1->exec();	//模态对话框