Bootstrap

[Qt]窗口-QDialog、QMessageBox、QColorDialog、QFileDialog、QFontFialog、QInputDialog对话框

目录

一、对话框

介绍

QDialog对象的释放问题

 自定义QDialog的界面内容

 model属性

二、Qt内置对话框

1.QMessageBox对话框

设置图标

内置按钮

自定义按钮

 快速构建消息对话框

2.QColorDialog对话框

使用说明

3.QFileDialog对话框

使用说明

4.QFontFialog对话框

使用说明

5.QInputDialog对话框

使用说明


一、对话框

介绍

        对话框就相当于是弹窗,一些不适合在主窗口实现的功能组件可以上设置在对话框当中,对话框是一个顶层窗口,出现在程序的对上层,用于实现短期任务或者简介的用户交互。最经典的就是文本编辑器,在编辑完毕之后,不保存就退出,在退出之前,会弹出一个对话框问我们是否要保存后在退出。

        在Qt中我们使用QDialog类表示对话框,这也是我们在创建项目的适合,三个版本之一,该类是继承于QWidget类的。针对一个已经有的项目,我们可以创建一些类,继承Dialog实现我们自己的对话框。在Qt中也有很多内置的对话框,也是继承自QDialog。常用的内置对话框有QFiledialog文本对话框、QColorDialog颜色对话框、QFontDialog字体对话框、QInputDialog输入对话框、QMessageBox消息框。

        在实际开发当中,更多的情况不会选择QDialog版本生成项目,而是创建项目之后,创建额外的类去继承这个QDialog类作为对话框的存在。(主窗口一般是不会作为对话框,但是主窗口可以产生出一些对话框)

QDialog对象的释放问题

下面是一个用按钮弹出对话框的简单案例:

void MainWindow::on_pushButton_clicked()
{
    //创建对话框
    QDialog* dialog = new QDialog(this);
    //设置大小和标题
    dialog->resize(400, 300);
    dialog->setWindowTitle("对话框");
    //显示对话框
    dialog->show();
}

        上述代码有一个非常大的问题,每一次点击按钮都会创建一个QDialog对象,虽然说已经添加到对象树中了,但是对于QDialog对象的销毁是在关闭QMainWindow窗口关闭的时候才会释放这些QDialog,所以说多次点击就会创建多个QDialog对象,那么就会出现问题,这也是一种内存泄露问题。

        那么我们如何解决呢?不能直接在该函数中delete,那他会显示后瞬间delete释放,对话框一闪而过了。正确的做法,应该是用户点击对话框的关闭按钮的时候,在去调用delete释放该对话框对象。这样的话就需要绑定信号槽,会比较麻烦,Qt为了我们方便,直接给QDialog设置了一个属性,可以通过设置Qt:;WA_DeleteOnClose属性完成上述的操作。所以对话框我们也是属于手动释放了,所以可以不用添加到对象树中。

void setAttribute(Qt::WidgetAttribute, bool on = true);   

 自定义QDialog的界面内容

        对于QDialog类,只是为我们提供一个对话框窗口的类,但是里面的内容通过QDialog是定义不了的,所以我们需要设计一个单独的类去继承这个QDialog类,在新增的类里面去实现我们想要的效果,那么其实就跟在主窗口中定义效果没有什么区别了,只不过父窗口是QMainWindow,而我们继承自QDialog,那么父窗口就是QDialog罢了。

mainwindow.cpp

void MainWindow::on_pushButton_clicked()
{
    MyDialog* dialog = new MyDialog();
    dialog->resize(500, 300);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->show();
}

mydialog.cpp

#include "mydialog.h"
#include <QPushButton>
#include <QLabel>
#include <QVBoxLayout>

MyDialog::MyDialog(QWidget* parent)
    :QDialog(parent)
{
    //以QDialog为父窗口
    QLabel* label = new QLabel("哈哈哈哈", this);
    QPushButton* button = new QPushButton("按钮", this);

    QVBoxLayout* layout = new QVBoxLayout();
    this->setLayout(layout);

    layout->addWidget(label);
    layout->addWidget(button);
}

        同时也可以使用图形化界面的方式进行设置,为这个对话框创建一个新的ui文件,如果选择Qt 设计师界面类选项的话,还会帮助我们添加类并将ui文件和类进行关联起来。如果不关联的话,ui文件不知道往哪里设置的。

 model属性

        model是对话框的模态/非模态的一个属性,是一个bool值来设定的。设置为模态的话,当弹出对话框之后,是无法操作父窗口的,一般用于用户必须要做出决定的时候,不做的话,程序不知道该如何运行等操作。非模态的话,就没有要求了,有对话框弹出的时候,也是可以进行操作父窗口的。默认的话是非模态的。

        那么如何设置模态对话框呢?通过调用不同的打开对话框的函数来设置模态和非模态。

void show();                //非模态显示    
virtual int exec();         //模态显示

二、Qt内置对话框

1.QMessageBox对话框

        消息对话框是应用程序中最常用的额界面元素,消息对话框主要用于为用户提供重要的信息,强制用户进行操作选择的对话框。当然这个是否强制还是取决于我们打开的方式。

设置图标

        对于QMessageBox对话框,一般都是用于模态的场景,在使用上和QDialog自定义的对话框没有什么太大的区别,祖先都是QWidegt,所以可以用控件的那些属性设置接口。对于图标的设置,QMessageBox内置了4中类型的图标。

Question一般用于正常操作过程中的提问
Information一般用于报告正常运行信息
Warning一般用于报告非关键性的错误
Critical一般用于报告严重错误
内置按钮

        因为需要用户进行操作的选择,所以需要设置按钮,QMessageBox为了方便我们的操作,内部也提供了很多的按钮类型。如下图所示,我们可以通过调用setStandarButtons设置多个按钮放入到消息对话框当中。

void setStandardButtons(StandardButtons buttons);    //设置按钮

void MainWindow::on_pushButton_clicked()
{
    //创建消息对话框
    QMessageBox* messageBox  = new QMessageBox(this);
    messageBox->setWindowTitle("对话框窗口标题");
    messageBox->setText("这是消息对话框的文本内容");
    messageBox->setIcon(QMessageBox::Warning);

    //设置选项按钮
    messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Save | QMessageBox::Cancel);
    //模态显示
    messageBox->exec();
    //释放对话框
    messageBox->setAttribute(Qt::WA_DeleteOnClose);
}

自定义按钮

        当然同样也是可以自己设置自定义按钮的。通过调用addButton可以将我们自定义的按钮传递进去,但是他是有两个参数的,第二个参数表示的是表示按钮的一个用途,按下该按钮表示拒绝啊,还是同意啊这些含义,这些含义用了一个ButtonRole枚举值来定义。

        而且对于模态对话框的调用是有返回值的,这里的返回值其实就是ButtonRole枚举类型的值,通过对值的判断,就知道用户做出了什么决策了。而对于上述的QMessageBox内置ide按钮,他的按钮的枚举值也就是对应的返回值了。

void addButton(QAbstractButton *button, ButtonRole role);

void MainWindow::on_pushButton_clicked()
{
    //创建消息对话框
    QMessageBox* messageBox  = new QMessageBox(this);
    messageBox->setWindowTitle("对话框窗口标题");
    messageBox->setText("这是消息对话框的文本内容");
    messageBox->setIcon(QMessageBox::Warning);

    //设置选项按钮
//    messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Save | QMessageBox::Cancel);
    QPushButton* button1 = new QPushButton("确定");
    QPushButton* button2 = new QPushButton("拒绝");
    messageBox->addButton(button1, QMessageBox::AcceptRole);
    messageBox->addButton(button2, QMessageBox::RejectRole);
    //模态显示
    int ret = messageBox->exec();
    //判断返回值
    if(ret == QMessageBox::AcceptRole)
    {
        //......操作
    }
    else if(ret == QMessageBox::RejectRole)
    {
        //......操作
    }
    //释放对话框
    messageBox->setAttribute(Qt::WA_DeleteOnClose);
}

 快速构建消息对话框

        上述的操作有创建对话框对象,设置标题,图标,按钮等等操作,做起来显然是非常麻烦的,如果我们创建多个消息对话框的时候,每次都要进行这些操作,QMessageBox中为我们内置了静态函数去快速的实现一个消息对话框的创建工作,按照消息对话框的图标类型就行分类, 分别提供了4类静态函数。        

        QMessageBox::Warning函数是一个静态函数,它会创建一个临时的QMessageBox对象,并在用户操作完成后自动管理其生命周期,当用户点击对话框中的按钮后,QMessage会自动关闭并进行相应的清理工作,无需手动设置WA_DeleteOnClose来确保其销毁。

QMessage::question

QMessage::information

QMessage::warning

QMessage::critical

void MainWindow::on_pushButton_clicked()
{
    int ret = QMessageBox::warning(this, "对话框标题", "对话框文本", QMessageBox::Ok | QMessageBox::Cancel);
    //判断返回值
    if(ret == QMessageBox::Ok)
    {
        //......操作
    }
    else if(ret == QMessageBox::Cancel)
    {
        //......操作
    }
}

2.QColorDialog对话框

        计算机的颜色是通过RGB来定义的,但是普通的用户是不了解RGB的,也不可能去记各种颜色对应的RGB的值,所以为了方便用户选择颜色,Qt内置了一个颜色对话框,可以进行颜色的各种设定和选择。

使用说明

        可以使用QDialog内部的创建逻辑,但是QColorDialog内部也有跟消息对话框一样的静态函数,可以使用静态函数QColorDialog::getColor函数来进行创建颜色对话框并打开,当用户选择了颜色之后,会退出对话框并返回一个QColor对象,表示的是用户选择的颜色。这里的QColor表示的颜色是ARGB颜色,A表示的是不透明度,其他的和RGB表示的一样。

    static QColor getColor(const QColor &initial = Qt::white,

                           QWidget *parent = nullptr,

                           const QString &title = QString(),

                           ColorDialogOptions options = ColorDialogOptions());

        那么对于获取的ARGB颜色怎么使用呢?以设置窗口背景颜色为例:

void MainWindow::on_pushButton_clicked()
{
    QColor color = QColorDialog::getColor(QColor(0, 255, 0), this, "选择颜色");
    //使用css方式设置背景颜色
    QString str = "background-color: rgb(" + QString::number(color.red()) +
            ", " + QString::number(color.green()) + ", " + QString::number(color.blue()) + ");";
    this->setStyleSheet(str);
}

3.QFileDialog对话框

        通过该QFileDialog对话框,常用于打开一个外部文件或需要将当前内容存储到指定的外部文件当中的情况。

使用说明

        对于QFileDialog对话框也是有自己的静态函数,对于打开文件操作和保存文件的操作都提供了对应的静态函数来帮助我们创建对话框设置内部的功能等操作。第一个参数是定义父对象,第二个参数是对话框的标题,第三个参数是默认打开的路径,第四个参数是文件过滤器。

static QString getOpenFileName(QWidget *parent = nullptr,

                                   const QString &caption = QString(),

                                   const QString &dir = QString(),

                                   const QString &filter = QString(),

                                   QString *selectedFilter = nullptr,

                                   Options options = Options());

static QString getSaveFileName(QWidget *parent = nullptr,

                                   const QString &caption = QString(),

                                   const QString &dir = QString(),

                                   const QString &filter = QString(),

                                   QString *selectedFilter = nullptr,

                                   Options options = Options());

        其实我们这里调用的打开和保存功能其实都是在选择路径,选择之后给我们返回路径,之后我们根据拿到的路径,使用C++接口进行文件操作来进行读取内容,或者创建文件、写入并保存等等。

4.QFontFialog对话框

        是一个用于选择字体的对话框。

使用说明

        该对话框的静态实现函数是QFontDialog::getFont()。这里跟上述不一样的点在于他需要返回一个QFont对象表示设置的字体,那么谁来表示是否设置了字体呢?因为对话框中确定和取消两个选项,如何知道是否设置呢?所以传递了一个输出型参数ok,用ok来判断。

static QFont getFont(bool *ok, QWidget *parent = nullptr);

static QFont getFont(bool *ok, const QFont &initial, QWidget *parent = nullptr,

                          const &title = QString(),FontDialogOptions options = FontDialogOptions());

        之后在通过调用QFont控件内部的函数就可以获取到各种各样我们设置的字体属性了,之后应用到某一个控件或者窗口内部,就实现了字体切换的功能。

5.QInputDialog对话框

        该对话框用于进行临时数据输入的场景。

使用说明

        该对话框提供了三种类型的输入,也就对应了三种静态函数去实现QInputDialog对话框的使用了。第一种是双精度浮点型输入数据对话框、第二种是整型输入数据对话框、第三种是条目选择对话框,用户可以在设置的条目中选择条目,当然也可以自己设置。返回值就是用户输入的内容了。

static int getInt(QWidget *parent, const QString &title, const QString &label, int value = 0,

                      int minValue = -2147483647, int maxValue = 2147483647,

                      int step = 1, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());

static double getDouble(QWidget *parent, const QString &title, const QString &label,

          double value = 0, double minValue = -2147483647, double maxValue = 2147483647,

           int decimals = 1, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags());

static QString getItem(QWidget *parent, const QString &title, const QString &label,

                           const QStringList &items, int current = 0, bool editable = true,

                           bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags(),

                           Qt::InputMethodHints inputMethodHints = Qt::ImhNone);

;