对话框

对话框可以理解成一个弹窗,用于短期任务或者简洁的用户交互

Qt内置对话框:

  • QFiledialog文件对话框
  • QColorDialog颜色对话框
  • QFontDialog字体对话框
  • QInputDialog输入对话框
  • QMessageBox消息框

继承QDialog:
在这里插入图片描述
在这里插入图片描述

实际开发都是创建额外的类,让额外的类继承QDialog

继承QMainWindow:

往ui文件里面添加一个按钮,设置槽,点击按钮就会弹出对话框:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QDialog>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    QDialog* dialog = new QDialog(this);
    dialog->setWindowTitle("弹窗");
    dialog->resize(300,400);
    dialog->show();
}

GIF 2024-9-21 12-33-50

内存泄漏问题:

点击一次按钮,就弹出一个对话框,即每次点击都会创建新的QDialog对象。

如果无数次点击这个按钮,就会产生无数次这个对象,进而引发内存泄漏。

如果将delete操作直接放入:

void MainWindow::on_pushButton_clicked()
{
    QDialog* dialog = new QDialog(this);
    dialog->setWindowTitle("弹窗");
    dialog->resize(300,400);
    dialog->show();
    delete dialog;
}

这样弹窗一闪而过,正确的做法是将delete和关闭按钮的信号关联起来。

Qt给QDialog设置了属性,通过设置属性,完成上述效果

void MainWindow::on_pushButton_clicked()
{
    QDialog* dialog = new QDialog(this);
    dialog->setWindowTitle("弹窗");
    dialog->resize(300,400);
    dialog->show();
    
    dialog->setAttribute(Qt::WA_DeleteOnClose);
}

自定义对话框

要想自定义对话框,就要继承QDialog创建类

纯代码:

创建一个C++类,继承自QDialog

image-20240921125947229

dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QWidget>
#include<QDialog>
class Dialog : public QDialog
{
    Q_OBJECT
public:
    Dialog(QWidget* parent);
    
    void handle();
};

#endif // DIALOG_H

dialog.cpp

#include "dialog.h"
#include<QPushButton>
#include<QLabel>
#include<QVBoxLayout>
Dialog::Dialog(QWidget* parent) : QDialog(parent)
{
    //创建控件加入dialog当中
    QVBoxLayout* layout = new QVBoxLayout();
    this->setLayout(layout);
    QLabel* label = new QLabel("对话框");
    QPushButton* button = new QPushButton("关闭");
    layout->addWidget(label);
    layout->addWidget(button);
    
    connect(button, &QPushButton::clicked, this, &Dialog::handle);
}

void Dialog::handle()
{
    this->close();
}
#include "dialog.h"
#include<QPushButton>
#include<QLabel>
#include<QVBoxLayout>
Dialog::Dialog(QWidget* parent) : QDialog(parent)
{
    //创建控件加入dialog当中
    QVBoxLayout* layout = new QVBoxLayout();
    this->setLayout(layout);
    QLabel* label = new QLabel("对话框");
    QPushButton* button = new QPushButton("关闭");
    layout->addWidget(label);
    layout->addWidget(button);
    
    connect(button, &QPushButton::clicked, this, &Dialog::handle);
}

void Dialog::handle()
{
    this->close();
}

mianwindow.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->resize(400, 300);
    dialog->setAttribute(Qt::WA_DeleteOnClose);
    dialog->show();
}

GIF 2024-9-21 13-26-36

图形化:

创建新的ui文件:

image-20240921132926374

image-20240921135018533

对话框分类

  • 模态对话框: 表示弹出对话框的时候,此时用户无法操作父窗口,必须完成对话框内部的操作,关闭之后,才可进行操作父窗口
    一般用于关键的场合,用户必须做出决策
  • 非模态: 弹出对话框之后,用户可以操作父窗口
    上面写的对话框,都是非模态

QDialog::exec()表示模态

QDialog::show()表示非模态

消息对话框QMessageBox

弹出一个对话框,给用户显示消息,并让用户进行一个简单的选择

使用示例

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QMessageBox>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    //创建
    QMessageBox* messageBox = new QMessageBox();
    messageBox->setWindowTitle("对话框标题");
    messageBox->setText("对话框文本");
    messageBox->setIcon(QMessageBox::Warning);
    messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Save | QMessageBox::Cancel);
    messageBox->exec();
    //模态对话框一直处于阻塞状态,知道对话框关闭,使用可以直接在后面delete
    delete messageBox;
}

QMessageBox内置的图标:

image-20240921140634754

QMessageBox内置按钮:

image-20240921140702394

用户点击按钮的时候,可以通过exec的返回值(按钮枚举的值)来知道用户点击的是哪个按钮,从而执行了哪些操作

image-20240921140903918

自定义按钮

void MainWindow::on_pushButton_clicked()
{
    //创建
    QMessageBox* messageBox = new QMessageBox();
    messageBox->setWindowTitle("对话框标题");
    messageBox->setText("对话框文本");
    messageBox->setIcon(QMessageBox::Warning);
    //messageBox->setStandardButtons(QMessageBox::Ok | QMessageBox::Save | QMessageBox::Cancel);
    
    QPushButton* button = new QPushButton("按钮", messageBox);
    messageBox->addButton(button, QMessageBox::AcceptRole);
    
    messageBox->exec();

    delete messageBox;
}

image-20240921142835383

快速构造对话框

QMessageBox提供了静态函数,可以快速构造对话框

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QMessageBox>
#include<QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    int ret = QMessageBox::warning(this, "标题", "文本", QMessageBox::Ok | QMessageBox::Cancel);
    if(ret == QMessageBox::Ok)
    {
        qDebug() << "Ok";   
    }
    else if(ret == QMessageBox::Cancel)
    {
        qDebug() << "Cancel";
    }
}

颜色对话框QColorDialog

QColorDialog颜色对话框的功能是允许用户选择颜色,相当于调色板,继承自QDialog

常用方法:

  • QColorDialog(QWidget* parent = nullptr)创建对象的同时设置父对象

  • QColorDialog(const QColor &initial, QWidget* parent = nullptr)创建对象的同时通过QColor对象设置默认颜色和父对象

  • void setCurrentColor(const QColor &color)设置当前颜色对话框

  • QColor getColor(const QColor &initial = Qt::white, QWidget *parent = nullptr, const QString &title = QString(), QColorDialog::ColorDialogOptions options = ColorDialogOptions())打开颜色对话框,返回一个QColor对象

    是一个静态函数,不必创建对话框对象就可以直接使用

    参数说明:
    initial设置默认颜色
    parent设置父对象
    title设置对话框标题
    options设置选项

  • void open(QObject *receiver, const char* member)打开颜色对话框

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QColorDialog>
#include<QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    QColor color = QColorDialog::getColor(QColor(0, 255, 0), this, "选择颜色");
    qDebug() << color;
}

image-20240921150052826

这里的a表示alpha不透明度

后面的就表示RGB的值,范围是[0, 1]

1对应整数255;0对应整数0

修改窗口颜色:

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QColorDialog>
#include<QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    QColor color = QColorDialog::getColor(QColor(0, 255, 0), this, "选择颜色");
    qDebug() << color;
    //QSS方式设置
//    QString style = "background-color: rgb(" +
//            QString::number(color.red()) + ", "
//            + QString::number(color.green()) + ", "
//            + QString::number(color.blue()) + ");";
    char style[1024] = { 0 };
    sprintf(style, "background-color: rgb(%d, %d, %d)", color.red(), color.green(), color.blue());
    this->setStyleSheet(style);
}

GIF 2024-9-21 15-07-00

文件对话框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 QStringList getOpenFileNames(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());
    

    参数说明:

    1. parent父亲
    2. caption对话框标题
    3. dir默认打开路径
    4. filter文件过滤器
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QFileDialog>
#include<QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    QString filePath = QFileDialog::getOpenFileName(this);
    qDebug() << filePath;
}

void MainWindow::on_pushButton_2_clicked()
{
    QString filePath = QFileDialog::getSaveFileName(this);
    qDebug() << filePath;
}

此处的打开/保存的功能都是需要额外实现的,并不是说按下就打开/保存了

GIF 2024-9-21 15-17-51

字体对话框QFontDialog

QFontDialog用于让用户选择字体的属性

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QFontDialog>
#include<QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    bool ok = false;
    QFont font = QFontDialog::getFont(&ok);
    qDebug() << "ok = " << ok;
    qDebug() << font;
    
    //选择的字体相关属性设置到按钮上
    ui->pushButton->setFont(font);
}

GIF 2024-9-21 15-28-32

输入对话框QInputDialog

QInputDialog允许用户输入一个具体的数据(整数、浮点数、字符串)

常用方法:

  • 双精度浮动型输入数据对话框

    static double getDouble(QWidget *parent, const QString &title, const QString &label, double value,
                            double minValue, double maxValue, int decimals, bool *ok, Qt::WindowFlags flags,
                            double step);
    
  • 整数输入数据对话框

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

    参数说明:

    1. parent父亲
    2. title对话框标题
    3. label对话框标签
    4. items可选择条目
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include<QInputDialog>
#include<QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

MainWindow::~MainWindow()
{
    delete ui;
}


void MainWindow::on_pushButton_clicked()
{
    int ret = QInputDialog::getInt(this, "整数输入对话框", "输入整数: ");
    qDebug() << ret;
}

void MainWindow::on_pushButton_2_clicked()
{
    QStringList items;
    items.push_back("123");
    items.push_back("456");
    items.push_back("789");
    QString item = QInputDialog::getItem(this, "条目输入对话框", "输入条目:", items);
    qDebug() << item;
}

GIF 2024-9-21 15-40-17

Logo

开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!

更多推荐