当前位置: 首页 > news >正文

Qt MainWindow

文章目录

  • 0. 概述
  • 1. 菜单栏 QMenuBar
    • 1.1 例子1,使用图形化界面
    • 1.2 例子2,使用代码创建
    • 1.3 例子3,添加快捷键
    • 1.4 例子4,添加子菜单
    • 1.5 例子5,添加分割线和图标
    • 1.6 内存泄漏问题
  • 2. 工具栏 QToolBar
    • 2.1 例子1,创建工具栏
    • 2.2 例子2,加入菜单栏
    • 2.3 例子3,设置多个工具栏
  • 3. 状态栏 QStatusBar
    • 3.1 例子1,创建状态栏
  • 4. 浮动窗口 QDockWidget
    • 4.1 例子1,创建浮动窗口
  • 5. 对话框 QDialog
    • 5.1 非模态对话框
      • 5.1.1 例子1,创建非模态对话框
      • 5.1.2 例子2,自定义对话框界面
      • 5.1.3 例子3,通过图形化界面自定义对话框
    • 5.2 模态对话框
    • 5.3 内置对话框
      • 5.3.1 消息对话框 QMessageBox
        • 5.3.1.1 例子1,简单使用
        • 5.3.1.2 例子2,自定义按钮
        • 5.3.1.3 例子3,快速创建
      • 5.3.2 颜色对话框 QColorDialog
      • 5.3.3 文件对话框 QFileDialog
      • 5.3.4 字体对话框 QFontDialog
      • 5.3.5 输入对话框 QInputDialog

0. 概述

QMainWindow的组成

  • 一个菜单栏:menu bar
  • 多个工具栏:tool bars,工具栏就是把菜单栏中一些比较常用的选项直接放进来了,点击它就能快速生效
  • 多个浮动窗口(铆接部件):dock Widget
  • 一个状态栏:status bar
  • 一个中心部件:central widget

1. 菜单栏 QMenuBar

一个窗口最多只有一个菜单栏,菜单栏(QMenuBar)包含菜单(QMenu)菜单(QMenu)包含菜单项(QAction)

1.1 例子1,使用图形化界面

Qt Designer中创建几个菜单,比较简单

image-20250212215625857

1.2 例子2,使用代码创建

mainwindow.cpp如下

#include "mainwindow.h"
#include <QDebug>
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 创建菜单栏
    QMenuBar* menuBar = new QMenuBar();
    this->setMenuBar(menuBar);
    // 创建菜单,将其添加到菜单栏中
    QMenu* menu1 = new QMenu("文件");
    QMenu* menu2 = new QMenu("新建");
    QMenu* menu3 = new QMenu("编辑");
    menuBar->addMenu(menu1);
    menuBar->addMenu(menu2);
    menuBar->addMenu(menu3);
    // 创建菜单项,将其添加到菜单中
    QAction* action1 = new QAction("新建");
    QAction* action2 = new QAction("保存");
    QAction* action3 = new QAction("退出");
    menu1->addAction(action1);
    menu1->addAction(action2);
    menu1->addAction(action3);
    // 设置槽函数
    connect(action1, &QAction::triggered, this, &MainWindow::handler_new_page);
    connect(action2, &QAction::triggered, this, &MainWindow::handler_edit_page);
    connect(action3, &QAction::triggered, this, &MainWindow::close);
}

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

void MainWindow::handler_new_page()
{
    qDebug() << "void MainWindow::handler_new_page()";
}

void MainWindow::handler_edit_page()
{
    qDebug() << "void MainWindow::handler_edit_page()";
}

执行效果与1.1一样,不过添加了几个槽函数

1.3 例子3,添加快捷键

这种方法添加比较简单,当然也可以使用QShortcut来设置

#include "mainwindow.h"
#include <QDebug>
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 创建菜单栏
    QMenuBar* menuBar = new QMenuBar();
    this->setMenuBar(menuBar);
    // 创建菜单,将其添加到菜单栏中
    QMenu* menu1 = new QMenu("文件(&F)");
    QMenu* menu2 = new QMenu("编辑(&E)");
    QMenu* menu3 = new QMenu("查看(&V)");
    menuBar->addMenu(menu1);
    menuBar->addMenu(menu2);
    menuBar->addMenu(menu3);
    // 创建菜单项,将其添加到菜单中
    QAction* action1 = new QAction("新建标签(&1)");
    QAction* action2 = new QAction("保存(&2)");
    QAction* action3 = new QAction("退出(&3)");
    menu1->addAction(action1);
    menu2->addAction(action2);
    menu3->addAction(action3);
    // 设置槽函数
    connect(action1, &QAction::triggered, this, &MainWindow::handler_new_page);
    connect(action2, &QAction::triggered, this, &MainWindow::handler_save_page);
    connect(action3, &QAction::triggered, this, &MainWindow::close);
}

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

void MainWindow::handler_new_page()
{
    qDebug() << "void MainWindow::handler_new_page()";
}

void MainWindow::handler_save_page()
{
    qDebug() << "void MainWindow::handler_save_page()";
}

可以使用快捷键选中

image-20250213125954536

1.4 例子4,添加子菜单

菜单中可以添加子菜单,QMenu通过调用QAction *QMenu::addMenu(QMenu *menu)即可,下面是一个例子

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
      , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 菜单栏
    QMenuBar* menuBar = new QMenuBar();
    this->setMenuBar(menuBar);
    // 菜单
    QMenu* menu1 = new QMenu("menu1");
    menuBar->addMenu(menu1);
    // 子菜单
    QMenu* child_Menu1 = new QMenu("child_Menu1");
    QMenu* child_Menu2 = new QMenu("child_Menu2");
    QMenu* child_child_Menu1 = new QMenu("child_child_Menu1");
    QMenu* child_child_Menu2 = new QMenu("child_child_Menu2");
    // 设置父子关系
    menu1->addMenu(child_Menu1);
    menu1->addMenu(child_Menu2);
    child_Menu1->addMenu(child_child_Menu1);
    child_Menu2->addMenu(child_child_Menu2);
    // 菜单项
    QAction* action1 = new QAction("action1");
    QAction* action2 = new QAction("action2");
    child_child_Menu1->addAction(action1);
    child_child_Menu2->addAction(action2);
}

运行结果如下,child_child_Menu2下有一个action2,截图没有截出来

image-20250213132803340

1.5 例子5,添加分割线和图标

QMenu中的不同菜单添加分割线,可以使用QAction *QMenu::addSeparator()函数,设置图标使用void setIcon(const QIcon &icon)函数,下面是例子,已经在qrc中导入了图片

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 菜单栏
    QMenuBar* menuBar = new QMenuBar();
    this->setMenuBar(menuBar);
    // 菜单和菜单项
    QMenu*   menu1 = new QMenu("文件");
    menuBar->addMenu(menu1);
    QAction* action1 = new QAction("新建");
    menu1->addAction(action1);
    menu1->addSeparator();
    QAction* action2 = new QAction("保存");
    menu1->addAction(action2);
    menu1->addSeparator();
    QAction* action3 = new QAction("退出");
    menu1->addAction(action3);
    menu1->addSeparator();
    // 设置图标
    action1->setIcon(QIcon(":/img/new.png"));
    action2->setIcon(QIcon(":/img/save.png"));
    action3->setIcon(QIcon(":/img/exit.png"));
}

运行结果如下

image-20250213143011500

1.6 内存泄漏问题

上面几个例子中,都写了这样的代码

QMenuBar* menuBar = new QMenuBar();
this->setMenuBar(menuBar);

如果我们勾选的是不自动生成ui文件,就不会有问题,但是勾选自动生成ui之后,Qt会帮我们生成一个默认的QMenuBar,当调用上面的代码后,我们自己创建的menuBar会替换默认的菜单栏,这样,Qt帮我们生成的默认的菜单栏就失去控制了,造成内存泄漏。一种比较好的写法如下:

QMenuBar* menuBar = this->menuBar();
// this->setMenuBar(menuBar);

QMenuBar *QMainWindow::menuBar() const会返回当前窗口的菜单栏,如果没有就会创建一个。

2. 工具栏 QToolBar

工具栏是应用程序中集成各种功能实现快捷键使用的区域。可以有多个,也可以没有,它并不是应用程序中必须存在的组件。它是一个可以动的组件,它的元素可以是各种窗口组件,通常以图标按钮的方式存在,下图是一个工具栏的示意图。

image-20250213170726693

2.1 例子1,创建工具栏

#include "mainwindow.h"
#include "qtoolbar.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 创建工具栏
    QToolBar* toolBar = new QToolBar();
    this->addToolBar(toolBar);
    // 创建QAction, 设置图标
    QAction* action1 = new QAction("新建");
    QAction* action2 = new QAction("保存");
    action1->setIcon(QIcon(":/new.png"));
    action2->setIcon(QIcon(":/save.png"));
    // 将QAction添加到QToolBar中
    toolBar->addAction(action1);
    toolBar->addAction(action2);
    // 设置槽函数
    connect(action1, &QAction::triggered, this, &MainWindow::handler_new_file);
    connect(action2, &QAction::triggered, this, &MainWindow::handler_save_file);
}

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

void MainWindow::handler_new_file()
{
    qDebug() << "void MainWindow::handler_new_file()";
}

void MainWindow::handler_save_file()
{
    qDebug() << "void MainWindow::handler_save_file()";
}

运行结果如下

image-20250213180418026

可以看到,图标把文字给覆盖了,但当我们鼠标移到该图标上时,仍会看到我们当时设置的文字
image-20250213201032577

可以通过void setToolTip(const QString &tip)来设置提示信息,给上面的代码添加

// 添加toolTip
action1->setToolTip("新建操作!!!");
action2->setToolTip("保存操作!!!");

结果变为:

image-20250213201242690

2.2 例子2,加入菜单栏

工具栏经常和菜单栏组合使用,如下面的例子

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 创建菜单栏
    QMenuBar* menuBar = new QMenuBar();
    this->setMenuBar(menuBar);
    // 创建菜单
    QMenu* menu1 = new QMenu("文件");
    QMenu* menu2 = new QMenu("编辑");
    // 添加菜单
    menuBar->addMenu(menu1);
    menuBar->addMenu(menu2);
    // 创建工具栏
    QToolBar* toolBar = new QToolBar();
    this->addToolBar(toolBar);
    // 创建QAction, 设置图标
    QAction* action1 = new QAction("新建");
    QAction* action2 = new QAction("保存");
    action1->setIcon(QIcon(":/new.png"));
    action2->setIcon(QIcon(":/save.png"));
    // 将QAction添加到QMenu中
    menu1->addAction(action1);
    menu1->addAction(action2);
    // 将QAction添加到QToolBar中
    toolBar->addAction(action1);
    toolBar->addAction(action2);
    // 设置槽函数
    connect(action1, &QAction::triggered, this, &MainWindow::handler_new_file);
    connect(action2, &QAction::triggered, this, &MainWindow::handler_save_file);
}

运行结果如下

image-20250213202434251

2.3 例子3,设置多个工具栏

  • 使用void QMainWindow::addToolBar(Qt::ToolBarArea area, QToolBar *toolbar)可以将工具栏添加到主窗口的指定位置中,下面是Qt::ToolBarArea一些值

    常量名称解释
    Qt::LeftToolBarArea0x1工具栏位于主窗口的左侧
    Qt::RightToolBarArea0x2工具栏位于主窗口的右侧
    Qt::TopToolBarArea0x4工具栏位于主窗口的顶部
    Qt::BottomToolBarArea0x8工具栏位于主窗口的底部
    Qt::AllToolBarAreasToolBarArea_Mask包含所有工具栏区域
    Qt::NoToolBarArea0不包含任何工具栏区域
  • void setAllowedAreas(Qt::ToolBarAreas areas)可以设置QToolBar的停靠位置

  • void setMovable(bool movable)可以设置QToolBar能否移动

  • void setFloatable(bool floatable)可以设置QToolBar能否浮动在窗口中间

mainwindow.cpp部分代码如下

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 创建工具栏并添加
    QToolBar* toolBar1 = new QToolBar();
    QToolBar* toolBar2 = new QToolBar();
    this->addToolBar(Qt::TopToolBarArea, toolBar1);                        // 最初停靠在上面
    this->addToolBar(Qt::LeftToolBarArea, toolBar2);                       // 最初停靠在左边
    toolBar1->setMovable(false);                                           // 设置不能移动
    toolBar2->setAllowedAreas(Qt::LeftToolBarArea | Qt::RightToolBarArea); // 设置能停靠在左边和右边
    toolBar2->setFloatable(false);                                         // 设置不能浮动
    // 添加QAction
    QAction* action1 = new QAction("action1");
    QAction* action2 = new QAction("action2");
    QAction* action3 = new QAction("action3");
    QAction* action4 = new QAction("action4");
    toolBar1->addAction(action1);
    toolBar1->addAction(action2);
    toolBar2->addAction(action3);
    toolBar2->addAction(action4);
}

运行截图如下

image-20250213212115155

3. 状态栏 QStatusBar

状态栏一般位于主窗口的最底部,一个窗口最多只能有一个状态栏。在Qt中,状态栏中可以显示的信息有

  • 实时信息:如当前程序状态
  • 永久信息:如程序版本号,机构名称
  • 进度信息:如进度条提示,百分比提示

3.1 例子1,创建状态栏

  • void QStatusBar::showMessage(const QString &message, int timeout = 0)用于在状态栏显示临时消息的函数。timeout用于指定消息显示的持续时间(以毫秒为单位)。(这是个槽函数)
  • void QStatusBar::addWidget(QWidget *widget, int stretch = 0),用于向状态栏中添加一个部件,(放在左侧)
  • void QStatusBar::addPermanentWidget(QWidget *widget, int stretch = 0)这个添加的部件位于右侧,不会被状态栏的消息(如 showMessage() 显示的消息)覆盖。
MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 状态栏
    QStatusBar* statusBar = this->statusBar(); // 有就获取,没有就创建
    // this->setStatusBar(statusBar);
    // // 显示实时信息
    // statusBar->showMessage("正在保存中...", 3000);
    // 添加部件
    QLabel* label = new QLabel("状态栏标签"); // 标签
    progress      = new QProgressBar();       // 进度条
    timer         = new QTimer(progress);     // 定时器
    timer->start(100);                        // 每100ms发送一次信号
    progress->setRange(0, 100);               // 设置最小值和最大值
    connect(timer, &QTimer::timeout, this, &MainWindow::timerHandler);
    statusBar->addWidget(label, 1);
    statusBar->addWidget(progress, 2);
    // 添加永久信息
    QLabel* label2 = new QLabel("PermanentWidge...");
    statusBar->addPermanentWidget(label2, 3);
}

void MainWindow::timerHandler()
{
    int val = progress->value();
    if (val >= 100 || val == 99) {
        progress->setValue(100);
        timer->stop();
        QTimer::singleShot(1000, this, [this]() { // 停留1秒后重置
            progress->setValue(0);
            timer->start(100);
        });
    } else {
        progress->setValue(val + 5);
    }
}

运行结果如下,两个lable,一个进度条

image-20250213225252698

4. 浮动窗口 QDockWidget

浮动窗口也叫做铆接部件,可以有多个,一般位于核心部件的周围

4.1 例子1,创建浮动窗口

  • 使用void QMainWindow::addDockWidget(Qt::DockWidgetArea area, QDockWidget *dockwidget)向窗口中添加浮动窗口,下面是Qt::DockWidgetArea的取值

    常量名称说明
    Qt::LeftDockWidgetArea0x1主窗口的左侧区域
    Qt::RightDockWidgetArea0x2主窗口的右侧区域
    Qt::TopDockWidgetArea0x4主窗口的顶部区域
    Qt::BottomDockWidgetArea0x8主窗口的底部区域
    Qt::AllDockWidgetAreasDockWidgetArea_Mask包含所有停靠区域
    Qt::NoDockWidgetArea0不允许停靠任何区域
  • void QDockWidget::setWidget(QWidget *widget)用于将一个 QWidget 对象设置为 QDockWidget 的内容部件。

  • void setAllowedAreas(Qt::DockWidgetAreas areas)可以设置浮动窗口可以移动的位置

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    // 创建浮动窗口
    QDockWidget* dockWidget = new QDockWidget("my_dock_widget", this);
    this->addDockWidget(Qt::LeftDockWidgetArea, dockWidget); // 将浮动窗口放置在左边
    // 创建widget1
    QWidget*     widget = new QWidget();
    QVBoxLayout* layout = new QVBoxLayout();
    QLabel*      label  = new QLabel("这是一段文字描述...", widget);
    QPushButton* btn    = new QPushButton("按钮...", widget);
    layout->addWidget(label);
    layout->addWidget(btn);
    widget->setLayout(layout);                                                     // 设置布局
    dockWidget->setWidget(widget);                                                 // 给浮动窗口添加widget
    dockWidget->setAllowedAreas(Qt::LeftDockWidgetArea | Qt::RightDockWidgetArea); // 允许放在左边或者右边
}

运行结果如下

image-20250214144415418

5. 对话框 QDialog

一些不适合在主窗口上实现的功能组件可以设置在对话框中。对话框是一个顶层窗口,出现在程序最上层,用于实现短期任务或者简洁的用户交互。常用的对话框有QFiledialog(文件对话框),QColorDialog(颜色对话框),QFontDialog(字体对话框),QInputDialog(输入对话框),QMessageBox(消息框)

分为模态对话框和非模态对话框

5.1 非模态对话框

非模态对话框显示后独立存在,可以与父窗口进行交互,是一种非阻塞式的对话框。需要在堆上创建(在栈上创建后一闪而过),同时需要调用void QWidget::setAttributeQt::WidgetAttribute attribut*, bool on = true)函数来设置Qt::WA_DeleteOnClose,表示点击关闭按钮时释放内存,调用void QWidget::show()来显示对话框

5.1.1 例子1,创建非模态对话框

Qt Designer中创建一个按钮,让该按钮按下后创建满屏幕的对话框

#include "mainwindow.h"
#include <QDialog>
#include "ui_mainwindow.h"
#include <windows.h>

MainWindow::MainWindow(QWidget* parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

void MainWindow::handleDialog()
{
    for (int i = 0; i < 10; ++i) {
        for (int j = 0; j < 10; ++j) {
            QDialog* dialog = new QDialog(this);
            dialog->resize(192, 108);
            dialog->move(192 * j, 108 * i);
            dialog->setWindowTitle("对话框");
            Sleep(500);
            dialog->show();
            ::MessageBeep(MB_ICONERROR); // 播放声音
            dialog->setAttribute(Qt::WA_DeleteOnClose);
        }
    }
}

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

void MainWindow::on_pushButton_clicked()
{
    handleDialog();
}

5.1.2 例子2,自定义对话框界面

下面有一个dialog.h

#ifndef DIALOG_H
#define DIALOG_H

#include <QDialog>

class Dialog : public QDialog
{
    Q_OBJECT
public:
    Dialog(QWidget* parent);
    ~Dialog();
};

#endif // DIALOG_H

dialog.cpp

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

Dialog::Dialog(QWidget* parent)
    : QDialog(parent)
{
    this->setAttribute(Qt::WA_DeleteOnClose); // 设置自动销毁
    // 创建布局
    QVBoxLayout* layout = new QVBoxLayout();
    this->setLayout(layout);
    // 添加一个QLabel和一个按钮
    QLabel*      label  = new QLabel("显示文本...");
    QPushButton* button = new QPushButton("关闭");
    layout->addWidget(label);
    layout->addWidget(button);
    connect(button, &QPushButton::clicked, this, [this]() { this->close(); });
}

Dialog::~Dialog()
{
    qDebug() << "Dialog::~Dialog()";
}

mainwindow.cpp

#include "mainwindow.h"
#include "dialog.h"
#include "ui_mainwindow.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(300, 200);
    dialog->show();
}

如上,就可以使用自己创建的Dialog了。

image-20250214170446039

5.1.3 例子3,通过图形化界面自定义对话框

首先,新建文件选择如下选项

image-20250214172955903

接着,模版选择Dialog without buttons(选其它的也可以)

image-20250214173033919

接着一直点击下一步,最后会发现Qt帮我们生成了一个ui文件,一个.h和一个.cpp文件
image-20250214173204892

dialog.ui中创建一个QLabel和一个QPushButton
image-20250214173423439

dialog.cpp代码如下

#include "dialog.h"
#include "ui_dialog.h"

Dialog::Dialog(QWidget* parent)
    : QDialog(parent), ui(new Ui::Dialog)
{
    ui->setupUi(this);
    this->setAttribute(Qt::WA_DeleteOnClose); // 关闭时销毁
    connect(ui->pushButton, &QPushButton::clicked, this, [this]() { this->close(); });
}

Dialog::~Dialog()
{
    qDebug() << "Dialog::~Dialog()";
    delete ui;
}

mainwindow.ui中创建一个按钮,设置槽函数。mainwindow.cpp的槽函数如下

void MainWindow::on_pushButton_clicked()
{
    Dialog* dialog = new Dialog(this);
    dialog->show();
}

运行结果如下
image-20250214173957228

5.2 模态对话框

模态对话框,显示后无法与父窗口进行交互,是一种阻塞式的对话框。使用int QDialog::exec()来调用。使用void setModal(bool modal)可以设置模态,modal==false非模态。使用int QDialog::exec()会忽略该设置,直接就是模态。

5.3 内置对话框

5.3.1 消息对话框 QMessageBox

消息对话框主要为用户提示重要信息,让用户进行选择操作

5.3.1.1 例子1,简单使用

下面是用到的几个函数

  • void setIcon(QMessageBox::Icon)可以设置 QMessageBox 消息框的图标。下面是QMessageBox::Icon的取值

    image-20250214202953658

  • QMessageBox::setStandardButtons(QMessageBox::StandardButtons buttons) 是一个用于设置 QMessageBox 消息框中显示的标准按钮的。下面是buttons的取值

    • QMessageBox::Ok:显示“确定”按钮。
    • QMessageBox::Cancel:显示“取消”按钮。
    • QMessageBox::Yes:显示“是”按钮。
    • QMessageBox::No:显示“否”按钮。
    • QMessageBox::Save:显示“保存”按钮。
    • QMessageBox::SaveAll:显示“全部保存”按钮。
    • QMessageBox::Open:显示“打开”按钮。
    • QMessageBox::YesToAll:显示“全部是”按钮。
    • QMessageBox::NoToAll:显示“全部否”按钮。
    • QMessageBox::Abort:显示“中断”按钮。
    • QMessageBox::Retry:显示“重试”按钮。
    • QMessageBox::Ignore:显示“忽略”按钮。
    • QMessageBox::Close:显示“关闭”按钮。
    • QMessageBox::Help:显示“帮助”按钮。
  • QMessageBox::setText(const QString &text) 是一个用于设置 QMessageBox 消息框中主要消息文本。

  • QMessageBox::setInformativeText 用于在消息框中添加一段补充信息文本,通常用于提供更多上下文或解释,以帮助用户理解消息的内容。

  • int QMessageBox::exec() 用于显示对话框并返回用户选择的按钮。返回值是 QMessageBox::StandardButton 枚举类型或自定义按钮的角色值

下面是一个例子

void MainWindow::on_pushButton_clicked()
{
    QMessageBox* message = new QMessageBox();
    message->setWindowTitle("提示信息");
    message->setIcon(QMessageBox::Information);
    message->setText("文件已经被修改了");
    message->setInformativeText("补充文本...");
    message->setStandardButtons(QMessageBox::Ok | QMessageBox::Cancel | QMessageBox::Ignore);
    auto ret = message->exec();
    switch (ret){
    case QMessageBox::Ok:
        qDebug() << "Ok clicked!";
        break;
    case QMessageBox::Cancel:
        qDebug() << "Cancel clicked!";
        break;
    case QMessageBox::Ignore:
        qDebug() << "Ignore clicked!";
        break;
    default:
        qDebug() << "what?!!";
        break;
    }
    message->setAttribute(Qt::WA_DeleteOnClose); // 关闭后进行清理
}

运行结果如下图

image-20250214204224170

5.3.1.2 例子2,自定义按钮
  • QMessageBox::addButton(QAbstractButton *button, QMessageBox::ButtonRole role) 用于向 QMessageBox 消息框中添加自定义按钮,role指定按钮在消息框中的角色。下面是role的取值
    • QMessageBox::AcceptRole:接受操作(如“确定”按钮)。
    • QMessageBox::RejectRole:拒绝操作(如“取消”按钮)。
    • QMessageBox::DestructiveRole:破坏性操作(如“删除”按钮)。
    • QMessageBox::ActionRole:特定操作(如“保存”、“打开”按钮)。
    • QMessageBox::HelpRole:帮助操作(如“帮助”按钮)。
    • QMessageBox::YesRole:问题的“是”选项。
    • QMessageBox::NoRole:问题的“否”选项。
  • QMessageBox::clickedButton() const 用于获取用户在消息框中点击的按钮。
    • 如果用户点击了某个按钮,返回该按钮的指针。
    • 如果用户关闭了消息框而未点击任何按钮,返回 nullptr

下面是一个例子

void MainWindow::on_pushButton_clicked()
{
    QMessageBox* message = new QMessageBox();
    message->setWindowTitle("提示信息");
    message->setIcon(QMessageBox::Information);
    message->setText("文件已经被修改了");
    message->setInformativeText("补充文本...");
    // 设置自定义按钮
    QPushButton* btn1 = new QPushButton("确认");
    message->addButton(btn1, QMessageBox::AcceptRole);
    QPushButton* btn2 = new QPushButton("取消");
    message->addButton(btn2, QMessageBox::RejectRole);
	message->exec();
    if (message->clickedButton() == btn1) {
        qDebug() << "btn1 clicked!";
    } else if (message->clickedButton() == btn2) {
        qDebug() << "btn2 clicked!";
    } else {
        qDebug() << "you clicked what?";
    }
    message->setAttribute(Qt::WA_DeleteOnClose); // 关闭后进行清理
}

运行结果如下

image-20250214213433414

5.3.1.3 例子3,快速创建

QMessageBox::criticalQMessageBox 提供的静态函数,用于快速显示一个带有“错误”图标的对话框。

参数

  • QWidget *parent:消息框的父窗口。
  • const QString &title:消息框的标题。
  • const QString &text:消息框的主要文本。
  • QMessageBox::StandardButtons buttons = QMessageBox::Ok:可选参数,指定消息框中的按钮,QMessageBox::Ok 是默认值。
  • QMessageBox::StandardButton defaultButton = QMessageBox::NoButton:可选参数,指定消息框的默认按钮。

返回值

  • 返回值为 QMessageBox::StandardButton,表示用户点击的按钮。

同样的函数还有warning,question,information,下面是使用例子

void MainWindow::on_pushButton_clicked()
{
    int res = QMessageBox::critical(this, "错误窗口", "发生错误!", QMessageBox::Ok | QMessageBox::Ignore);
    if(res == QMessageBox::Ok) {
        qDebug() << "QMessageBox::Ok";
    } else if(res == QMessageBox::Ignore) {
        qDebug() << "QMessageBox::Ignore";
    } else {
        qDebug() << "what?!!!";
    }
}

很简单的就创建除了一个对话框

image-20250214220710058

5.3.2 颜色对话框 QColorDialog

使用如下的静态函数

QColor QColorDialog::getColor(const QColor &initial = Qt::white, QWidget *parent = nullptr, const QString &title = QString(), QColorDialog::ColorDialogOptions options = ColorDialogOptions()) 是 Qt 中用于获取颜色的函数,它会打开一个颜色对话框,让用户选择颜色。

功能

  • 打开一个颜色对话框。
  • 返回用户选择的颜色。
  • 如果用户取消对话框,返回初始颜色。

参数

  1. const QColor &initial = Qt::white

    • 指定对话框中初始显示的颜色,默认值为白色 (Qt::white)。
  2. QWidget *parent = nullptr

    • 指定对话框的父窗口。
    • 如果不指定,对话框将作为顶层窗口。
  3. const QString &title = QString()

    • 对话框的标题,默认为空字符串。
  4. QColorDialog::ColorDialogOptions options = ColorDialogOptions()

    • 对话框的附加选项,可以通过 QColorDialog::ColorDialogOptions 枚举指定。下面是枚举的值

      • QColorDialog::ShowAlphaChannel

        • 0x00000001
        • 描述:允许用户在颜色对话框中选择颜色的透明度(alpha 通道)。这使得用户可以选择带有透明度的颜色值。

        QColorDialog::NoButtons

        • 0x00000002
        • 描述:不显示“确定”和“取消”按钮。这通常是用于“实时”对话框,例如在不关闭对话框的情况下直接应用所选颜色,通过其他方式(如键盘快捷键或控件交互)关闭对话框。

        QColorDialog::DontUseNativeDialog

        • 0x00000004
        • 描述:不使用操作系统的原生颜色对话框,而是使用 Qt 提供的标准颜色对话框。这在某些情况下可能更灵活,例如当需要自定义对话框行为或在跨平台开发中确保一致的外观和行为时。

返回值

返回用户选择的颜色。如果用户取消对话框,返回invalid


用户选择颜色更换背景,下面是一个例子。

void MainWindow::on_pushButton_clicked()
{
    // QColorDialog* color = new QColorDialog();
    // color->exec();
    QColor color = QColorDialog::getColor(QColor(Qt::white), this, "颜色选择");
    if (!color.isValid())
        return; // 没有选择,就什么都不做
    qDebug() << color;
    // 更换背景颜色
    char style[1024];
    sprintf(style, "background-color: rgb(%d, %d, %d);", color.red(), color.green(), color.blue());
    this->setStyleSheet(style);
}

运行结果如下

image-20250215142341420

image-20250215142347522

5.3.3 文件对话框 QFileDialog

使用如下的静态函数:

QString QFileDialog::getOpenFileName()QFileDialog ,用于打开一个文件选择对话框,并返回用户选择的文件路径。以下是该函数的详细信息:

功能

  • 打开一个文件选择对话框,允许用户选择一个文件。
  • 如果用户取消了对话框,返回一个空字符串。
  • 返回值是一个 QString,表示用户选择的文件路径。

参数

  1. QWidget *parent = nullptr

    • 指定文件对话框的父窗口。
    • 如果不指定,对话框将作为顶层窗口。
  2. const QString &caption = QString()

    • 设置对话框的标题。
  3. const QString &dir = QString()

    • 设置对话框打开时的默认目录。
  4. const QString &filter = QString()

    • 设置文件过滤器,用于过滤文件类型。
    • 例如,"Images (*.png *.jpg)" 表示只显示 .png.jpg 文件。
  5. QString *selectedFilter = nullptr

    • 指向一个 QString 指针,用于存储用户选择的过滤器。
    • 如果用户更改了过滤器,可以通过此参数获取新的过滤器。
  6. QFileDialog::Options options = Options()

    • 对话框的附加选项,可以通过 QFileDialog::Options 枚举指定。下面是该枚举的部分值

    • 常量值描述
      QFileDialog::ShowDirsOnly0x00000001指示文件对话框只显示目录,不允许选择文件。
      QFileDialog::DontResolveSymlinks0x00000002不自动解析符号链接的内容。
      QFileDialog::DontConfirmOverwrite0x00000004在保存文件时,QFileDialog::accept() 不会弹出确认覆盖对话框。
      QFileDialog::DontUseNativeDialog0x00000008不使用操作系统的原生文件对话框,改用 Qt 的实现。
      QFileDialog::ReadOnly0x00000010对话框以只读模式打开。
      QFileDialog::HideNameFilterDetails0x00000020隐藏文件过滤器的详细信息,仅显示名称。
      QFileDialog::DontClickOpenButtons0x00000040在文件预览中,用户单击文件不会自动激活 “Open” 按钮。
      QFileDialog::OptionMask0x0000FFFF用于掩码选项值。
      QFileDialog::DontUseSheet0x00010000在 macOS 上不作为工作表显示文件对话框。

返回值

  • 返回用户选择的文件路径,类型为 QString
  • 如果用户取消对话框,返回空字符串 (QString())。

getSaveFileName()与该函数类似,只不过打开的是保存文件

void MainWindow::on_pushButton_clicked()
{
    QFileDialog::getOpenFileName(this, "打开文件", "E:\\data");
}

void MainWindow::on_pushButton_2_clicked()
{
    QFileDialog::getSaveFileName(this, "保存文件", "E:\\data");
}

运行结果如下
image-20250215145504097

image-20250215145521701

5.3.4 字体对话框 QFontDialog

QFont QFontDialog::getFont(bool *ok, const QFont &initial, QWidget *parent = nullptr, const QString &title = QString(), QFontDialog::FontDialogOptions options = FontDialogOptions()) 用于显示字体选择对话框的函数,以下是对它的详细介绍:

功能

  • 打开一个字体选择对话框,允许用户选择字体。
  • 返回用户选择的字体。
  • 如果用户取消了对话框,返回初始字体或默认字体。

参数

  1. bool *ok
    • 指向一个布尔值的指针,用于指示用户是否点击了 “确定” 按钮。
    • 如果用户点击了 “确定”,ok 的值为 true;如果用户取消了对话框或关闭了窗口,ok 的值为 false
  2. const QFont &initial
    • 指定对话框中初始显示的字体,默认值为当前应用程序的字体。
  3. QWidget *parent = nullptr
    • 指定对话框的父窗口。如果为 nullptr,对话框将作为顶层窗口。
  4. const QString &title = QString()
    • 设置对话框的标题。默认为空字符串。
  5. QFontDialog::FontDialogOptions options = FontDialogOptions()
    • 指定对话框的附加选项,可以通过 QFontDialog::FontDialogOptions 枚举指定。

返回值

  • 返回用户选择的字体,类型为 QFont
  • 如果用户取消了对话框,返回初始字体或默认字体。

下面是一个例子,更换按钮的字体

void MainWindow::on_pushButton_clicked()
{
    bool  ok;
    QFont font = QFontDialog::getFont(&ok);
    if (ok) {
        ui->pushButton->setFont(font);
    } else {
        qDebug() << "you canceled the dialog.";
    }
}

运行结果如下

image-20250215153356774

image-20250215153359944

5.3.5 输入对话框 QInputDialog

这几个函数都是类似的,只介绍其中1个

int getInt(QWidget *parent, const QString &title, const QString &label, int value = 0, int min = -2147483647, int max = 2147483647, int step = 1, bool *ok = nullptr, Qt::WindowFlags flags = Qt::WindowFlags())

  • getInt 是 Qt 框架中的一个便捷函数,用于显示一个输入对话框,让用户输入一个整数值。以下是关于这个函数的详细信息:

    功能

    • 显示一个输入对话框,提示用户输入一个整数值。
    • 返回用户输入的整数值。
    • 如果用户取消了对话框,返回默认值(通常是 0 或指定的初始值)。

    参数

    1. QWidget *parent = nullptr
      • 指定输入对话框的父窗口。如果为 nullptr,对话框将作为顶层窗口。
    2. const QString &title
      • 设置输入对话框的标题。
    3. const QString &label
      • 设置输入对话框中的提示标签,用于描述输入的内容。
    4. int value = 0
      • 指定输入对话框中初始显示的值,默认为 0
    5. int min = -2147483647
      • 指定输入值的最小范围,默认为 -2147483647(32 位整数的最小值)。
    6. int max = 2147483647
      • 指定输入值的最大范围,默认为 2147483647(32 位整数的最大值)。
    7. int step = 1
      • 指定输入值的步长,默认为 1
    8. bool *ok = nullptr
      • 指向一个布尔值的指针,用于指示用户是否点击了“确定”按钮。
      • 如果用户点击了“确定”,*ok 的值为 true;如果用户取消了对话框或关闭了窗口,*ok 的值为 false
    9. Qt::WindowFlags flags = Qt::WindowFlags()
      • 指定输入对话框的窗口标志,用于控制对话框的外观和行为。

    返回值

    • 返回用户输入的整数值。如果用户取消了对话框,返回值为 value(初始值)。

下面是一个例子,在mainwindow.ui中创建几个按钮
image-20250215165328044

设置槽函数

void MainWindow::on_pushButton_clicked()
{
    auto res = QInputDialog::getInt(this, "整形输入", "请输入一个整数");
    qDebug() << res;
}

void MainWindow::on_pushButton_2_clicked()
{
    auto res = QInputDialog::getMultiLineText(this, "多行输入", "请输入文本: ");
    qDebug() << res;
}

void MainWindow::on_pushButton_3_clicked()
{
    QStringList items;
    items << "Spring" << "Summer" << "Fall" << "Winter";
    auto res = QInputDialog::getItem(this, "条目输入", "请输入提条目: ", items);
    qDebug() << res;
}

void MainWindow::on_pushButton_4_clicked()
{
    auto res = QInputDialog::getText(this, "字符串输入", "请输入字符串");
    qDebug() << res;
}

运行结果如下,按顺序点击
image-20250215165513154

相关文章:

  • java集合框架之Map系列
  • 华为IPD简介
  • LeetCode 232: 用栈实现队列
  • w210基于Springboot开发的精简博客系统的设计与实现
  • windows10本地的JMeter+Influxdb+Grafana压测性能测试,【亲测,避坑】
  • 梅花易数【邵雍】起卦方法
  • OpenMetadata 获取 MySQL 数据库表血缘关系详解
  • 【kafka系列】broker
  • DeepSeek官方推荐的AI集成系统
  • Windows安装Rust环境(详细教程)
  • 解读 Flink Source 接口重构后的 KafkaSource
  • AcWing——61. 最长不含重复字符的子字符串
  • 基于AIOHTTP、Websocket和Vue3一步步实现web部署平台,无延迟控制台输出,接近原生SSH连接
  • 刷题记录(回顾)HOT100 二叉树-10: ​199. 二叉树的右视图
  • 【仪器仪表专题】案例:示波器控制通道开关SCPI命令不同的原因
  • 使用verilog 实现cordic 算法 ---- 向量模式
  • 【java】方法--拷贝数组
  • Hami项目开发笔记
  • 1.从零开始学会Vue--{{基础指令}}
  • 浅介绍redis特性
  • 央行谈MLF:逐步退出政策利率属性回归流动性投放工具
  • 印巴冲突升级,巴基斯坦股市重挫7.29%,创5年来最大单日跌幅
  • 上海科创“八杰”赋能新兴产业链:硬核科技,形成良好盈利模式
  • 上市不足一年,吉利汽车拟私有化极氪并合并:整合资源,杜绝重复投入
  • 马上评|不再提“智驾”,新能源车企回归理性
  • 4月外汇储备增加410亿美元,黄金储备连续6个月增加