其他分享
首页 > 其他分享> > QT_5-QDialog

QT_5-QDialog

作者:互联网

QT_5-QDialog

基本概念

对话框是 GUI 程序中不可或缺的组成部分。很多不能或者不适合放入主窗口的功能组件都必须放在对话框中设置。对话框通常会是一个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互。
Qt 中使用QDialog类实现对话框。就像主窗口一样,我们通常会设计一个类继承QDialog。QDialog(及其子类,以及所有Qt::Dialog类型的类)的对于其 parent 指针都有额外的解释:

标准对话框

所谓标准对话框,是 Qt 内置的一系列对话框,用于简化开发。事实上,有很多对话框都是通用的,比如打开文件、设置颜色、打印设置等。这些对话框在所有程序中几乎相同,因此没有必要在每一个程序中都自己实现这么一个对话框。
Qt 的内置对话框大致分为以下几类:

自定义消息框

Qt 支持模态对话框和非模态对话框。
模态与非模态的实现:

void MainWindow::open() {
        QDialog dialog;
        dialog.setWindowTitle(tr("Hello, dialog!"));
dialog.exec();
}
非模态对话框

下面我们试着将exec()修改为show(),看看非模态对话框:

void MainWindow::open() {
    QDialog dialog(this);
    dialog.setWindowTitle(tr("Hello, dialog!"));
    dialog.show();
}

是不是事与愿违?对话框竟然一闪而过!这是因为,show()函数不会阻塞当前线程,对话框会显示出来,然后函数立即返回,代码继续执行。注意,dialog 是建立在栈上的,show()函数返回,MainWindow::open()函数结束,dialog 超出作用域被析构,因此对话框消失了。知道了原因就好改了,我们将 dialog 改成堆上建立,当然就没有这个问题了:

void MainWindow::open()
{
    QDialog *dialog = new QDialog;
    dialog->setWindowTitle(tr("Hello, dialog!"));
    dialog->show();
}

如果你足够细心,应该发现上面的代码是有问题的:dialog 存在内存泄露!dialog 使用 new 在堆上分配空间,却一直没有 delete。解决方案也很简单:将 MainWindow 的指针赋给 dialog 即可。还记得我们前面说过的 Qt 的对象系统吗?
不过,这样做有一个问题:如果我们的对话框不是在一个界面类中出现呢?由于QWidget的 parent 必须是QWidget指针,那就限制了我们不能将一个普通的 C++ 类指针传给 Qt 对话框。另外,如果对内存占用有严格限制的话,当我们将主窗口作为 parent 时,主窗口不关闭,对话框就不会被销毁,所以会一直占用内存。在这种情景下,我们可以设置 dialog 的WindowAttribute:

void MainWindow::open()
{
    QDialog *dialog = new QDialog;
     //setAttribute() 函数设置对话框关闭时,自动销
     ### 消息对话框毁对话框
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->setWindowTitle(tr("Hello, dialog!"));
    dialog->show();
}

消息对话框

QMessageBox用于显示消息提示。我们一般会使用其提供的几个 static 函数:

显示关于对话框。

void about(QWidget * parent, const QString & title, const QString & text)
这是一个最简单的对话框,其标题是 title,内容是 text,父窗口是 parent。对话框只有一个 OK 按钮。

if (QMessageBox::Yes == QMessageBox::question(this,
              tr("Question"), tr("Are you OK?"),
              QMessageBox::Yes | QMessageBox::No,
              QMessageBox::Yes)) 
{
    QMessageBox::information(this, tr("Hmmm..."), 
tr("I'm glad to hear that!"));
} 
else 
{
    QMessageBox::information(this, tr("Hmmm..."), 
tr("I'm sorry!"));
}

我们使用QMessageBox::question()来询问一个问题。

QMessageBox msgBox;
msgBox.setText(tr("The document has been modified."));
msgBox.setInformativeText(tr("Do you want to save your changes?"));
msgBox.setDetailedText(tr("Differences here..."));
msgBox.setStandardButtons(QMessageBox::Save
                          | QMessageBox::Discard
                          | QMessageBox::Cancel);
msgBox.setDefaultButton(QMessageBox::Save);
int ret = msgBox.exec();
switch (ret) 
{
case QMessageBox::Save:
    qDebug() << "Save document!";
    break;
case QMessageBox::Discard:
    qDebug() << "Discard changes!";
    break;
case QMessageBox::Cancel:
    qDebug() << "Close document!";
    break;
}

msgBox 是一个建立在栈上的QMessageBox实例。我们设置其主要文本信息为“The document has been modified.”,informativeText 则是会在对话框中显示的简单说明文字。下面我们使用了一个detailedText,也就是详细信息,当我们点击了详细信息按钮时,对话框可以自动显示更多信息。我们自己定义的对话框的按钮有三个:保存、丢弃和取消。然后我们使用了exec()是其成为一个模态对话框,根据其返回值进行相应的操作。

标准文件对话框

在openFile()函数中,我们使用QFileDialog::getOpenFileName()来获取需要打开的文件的路径。这个函数原型如下:

QString getOpenFileName(QWidget * parent = 0,
                        const QString & caption = QString(),
                        const QString & dir = QString(),
                        const QString & filter = QString(),
                        QString * selectedFilter = 0,
                        Options options = 0)

不过注意,它的所有参数都是可选的,因此在一定程度上说,这个函数也是简单的。这六个参数分别是:

综合实例:

功能: 模态与非模态的区别, 打开一个个文件获取路径
文件包括:
 mainwindow.h
 mainwindow.cpp
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QDialog>
#include <QDebug>
#include <QMessageBox>
#include <QFileDialog>
class MainWindow : public QMainWindow {
    Q_OBJECT
public:
    MainWindow(QWidget *parent = 0);
    ~MainWindow();
private:
    QDialog *dlg;
};

#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent) {
    QMenuBar *mBar = menuBar();
    setMenuBar(mBar);
    QMenu *menu = mBar->addMenu("File");
    QAction *p1 = menu->addAction("Modal_Dialog");
    connect(p1, &QAction::triggered,
            [=](){
        QDialog dlg;
        dlg.exec();
        qDebug() << "finish!1";
    });
    QAction *p2 = menu->addAction("Modaless_Dialog");
    connect(p2, &QAction::triggered,
            [=](){
        dlg = new QDialog;
        dlg->setAttribute(Qt::WA_DeleteOnClose);
        this->dlg->show();  //
        qDebug() << "finish!2";

    });
    QAction *p3 = menu->addAction("Messagebox");
    connect(p3, &QAction::triggered,
            [=](){
        QMessageBox::about(this,"Hello", "About QT");

    });
    QAction *p4 = menu->addAction("Messagebox2");
    connect(p4, &QAction::triggered,
            [=](){
        int ret = QMessageBox::question(this, "Question",
                                        "Are you OK?"
                                        ,QMessageBox::Apply|QMessageBox::Cancel);
        switch (ret) {
        case QMessageBox::Apply:
            qDebug() << "Apply";
            break;
        case QMessageBox::Cancel:
            qDebug() << "Cancel";
            break;
        default:
            break;
        }
    });
//File Dialog
    QAction *p5 = menu->addAction("FileDialog");
    p5->setShortcut(QKeySequence::Open);
    p5->setStatusTip(tr("Open a new file"));

    connect(p5, &QAction::triggered,
            [=](){
        qDebug() << "OK";
        QString path = QFileDialog::getOpenFileName( //获取路径
                    this,
                    "open file",
                    "../",
                    tr("images (*.png *.jpg);;Text (*.txt *.pro);;all (*.*)"));
        qDebug() << path;
    });
}
MainWindow::~MainWindow(){
}

标签:模态,QT,对话框,QDialog,QString,dialog,QMessageBox
来源: https://www.cnblogs.com/lyxf/p/12264684.html