当前位置: 首页 > 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);                                         // 设置不能浮动// 添加QActionQAction* 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); // 将浮动窗口放置在左边// 创建widget1QWidget*     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);                                                 // 给浮动窗口添加widgetdockWidget->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

相关文章:

Qt MainWindow

文章目录 0. 概述1. 菜单栏 QMenuBar1.1 例子1&#xff0c;使用图形化界面1.2 例子2&#xff0c;使用代码创建1.3 例子3&#xff0c;添加快捷键1.4 例子4&#xff0c;添加子菜单1.5 例子5&#xff0c;添加分割线和图标1.6 内存泄漏问题 2. 工具栏 QToolBar2.1 例子1&#xff0c…...

GDB QUICK REFERENCE (GDB 快速参考手册)

GDB QUICK REFERENCE {GDB 快速参考手册} References GDB QUICK REFERENCE GDB Version 4 https://users.ece.utexas.edu/~adnan/gdb-refcard.pdf 查看方式&#xff1a;在新标签页中打开图片 References [1] Yongqiang Cheng, https://yongqiang.blog.csdn.net/ [2] gdb-refc…...

【数据结构】 栈和队列

在计算机科学的世界里&#xff0c;数据结构是构建高效算法的基础。栈&#xff08;Stack&#xff09;和队列&#xff08;Queue&#xff09;作为两种基本且重要的数据结构&#xff0c;在软件开发、算法设计等众多领域都有着广泛的应用。今天&#xff0c;我们就来深入探讨一下栈和…...

AI视频创作教程:如何用AI让古画动起来。

事情缘由&#xff1a; 如果是简单的图&#xff0c;找原图直接写提示词即可。 如果碰到多人多活动的图&#xff0c;直接出的效果会很不好&#xff0c;那么该怎么做呢&#xff1f; 图片分模块 首先&#xff0c;复杂部分的图&#xff0c;把长图分多个模块。 比如这张图&#xff0…...

撕碎QT面具(1):Tab Widget转到某个Tab页

笔者未系统学过C语法&#xff0c;仅有Java基础&#xff0c;具体写法仿照于大模型以及其它博客。自我感觉&#xff0c;如果会一门对象语言&#xff0c;没必要先刻意学C&#xff0c;因为自己具有对象语言的基础&#xff0c;等需要用什么再学也不迟。毕竟不是专门学C去搞算法。 1…...

DeepSeek24小时写作机器人,持续创作高质量文案

内容创作已成为企业、自媒体和创作者的核心竞争力。面对海量的内容需求&#xff0c;人工创作效率低、成本高、质量参差不齐等问题日益凸显。如何在有限时间内产出高质量内容&#xff1f;DeepSeek写作机器人&#xff0c;一款24小时持续创作的智能工具&#xff0c;为企业和个人提…...

npm安装依赖(npm install)时遇到认证错误的解决方案

问题描述 在使用 npm install 安装依赖时遇到以下错误&#xff1a; npm error code E401 npm error Incorrect or missing password.解决方案 方案一&#xff1a;使用淘宝&#xff08;或其它国内公共&#xff09;镜像&#xff08;如果已经是淘宝镜像跳过此步&#xff09; 设…...

SpringBoot+微信小程序+数据可视化的宠物到家喂宠服务(程序+论文+讲解+安装+调试+售后等)

感兴趣的可以先收藏起来&#xff0c;还有大家在毕设选题&#xff0c;项目以及论文编写等相关问题都可以给我留言咨询&#xff0c;我会一一回复&#xff0c;希望帮助更多的人。 系统介绍 在经济高速发展、物质生活极大丰富的当下&#xff0c;人们的精神需求愈发凸显&#xff0…...

免费大模型网站

腾讯元宝 腾讯元宝 秘塔搜索 秘塔搜索 超算互联网 超算互联网回答速度很慢 Chatbot Arena Chatbot Arena 大模型竞技场。...

OpenCV的主要模块

OpenCV的模块...

使用 Python 爬虫和 FFmpeg 爬取 B 站高清视频

以下是一个完整的 Python 爬虫代码示例&#xff0c;用于爬取 B 站视频并使用 FFmpeg 合成高清视频。 1. 准备工作 确保安装了以下 Python 库和工具&#xff1a; bash复制 pip install requests moviepy2. 爬取视频和音频文件 B 站的视频和音频文件通常是分开存储的&#x…...

Retrieval-Augmented Generation for LargeLanguage Models: A Survey

标题&#xff1a;Retrieval-Augmented Generation for Large Language Models: A Survey 作者&#xff1a;Yunfan Gaoa , Yun Xiongb , Xinyu Gaob , Kangxiang Jiab , Jinliu Panb , Yuxi Bic , Yi Daia , Jiawei Suna , Meng Wangc , and Haofen Wang 1. By referencing ext…...

2025年2月16日(numpy-deepseek)

嗯&#xff0c;用户让我介绍一下这段使用numpy的代码。首先&#xff0c;我需要确认用户的需求是什么。他们可能刚开始学习Python或者数据科学&#xff0c;所以需要基础的解释。让我仔细看一下代码。 第一行是import numpy as np&#xff0c;这应该是导入numpy库&#xff0c;并…...

C#windows窗体人脸识别

一、创建一个数据库&#xff0c;名为TestFaceDB 里面有一张表就OK了&#xff0c;表名Users,表里面有几个字段我说明一下&#xff1a; id--------------------bigint----------------------编号 name--------------varchar(50)-----------------用户名 phone--------------v…...

【第11章:生成式AI与创意应用—11.1 文本生成与创意写作辅助的实现与优化】

凌晨三点的书房,作家李明第27次删除了刚写好的段落。窗外路灯在稿纸上投下斑驳光影,就像他此刻支离破碎的创作灵感。突然,写作软件弹出提示:"检测到情感转折生硬,建议尝试’雨夜独白’场景模板?"这个由生成式AI驱动的建议,不仅拯救了濒临崩溃的章节,更揭开了…...

【Elasticsearch】通过运行时字段在查询阶段动态覆盖索引字段

在 Elasticsearch 中&#xff0c;Override field values at query time是指通过运行时字段&#xff08;runtime fields&#xff09;在查询阶段动态覆盖索引字段的值&#xff0c;而无需修改原始索引数据。这种功能特别适用于以下场景&#xff1a; 1. 动态修改字段值&#xff1a…...

电解电容的参数指标

容量 这个值通常是室温25℃&#xff0c;在一定频率和幅度的交流信号下测得的容量。容量会随着温度、直流电压、交流电压值的变化而改变。 额定电压 施加在电容上的最大直流电压&#xff0c;通常要求降额使用。 例如额定电压是4V&#xff0c;降额到70%使用&#xff0c;最高施…...

linux 内核编译报错 unknown assembler invoked

在编译内核时&#xff0c;出现如下错误 : scripts/gcc-wrapper.py aarch64-linux-gnu-gcc: unknown assembler invoked scripts/Kconfig.include:47: Sorry, this assembler is not supported. make[1]: *** [scripts/kconfig/Makefile:29&#xff1a;menuconfig] 错误 1 make…...

HTML,API,RestFul API基础

一文搞懂RESTful API - bigsai - 博客园 1. API 路径 开头必须 /&#xff0c;表示绝对路径&#xff0c;不支持 . 或 ..&#xff08;相对路径&#xff09;。API 结尾 / 通常不需要&#xff0c;但部分框架会自动处理 / → 无 /。 ✅ 推荐 GET /api/v1/products # 资源集合…...

js 使用缓存判断在规定时间内显示一次弹框

js 使用缓存判断在规定时间内显示一次弹框 功能拆分&#xff0c;新用户注册完成登录跳转首页 &#xff0c; js根据注册时间判断显示一个新手指引的弹窗&#xff0c;只在注册当天登录且显示一次 <script>jQuery(document).ready(function($) {getWinnerModalShow()});// 新…...

docker详细操作--未完待续

docker介绍 docker官网: Docker&#xff1a;加速容器应用程序开发 harbor官网&#xff1a;Harbor - Harbor 中文 使用docker加速器: Docker镜像极速下载服务 - 毫秒镜像 是什么 Docker 是一种开源的容器化平台&#xff0c;用于将应用程序及其依赖项&#xff08;如库、运行时环…...

Admin.Net中的消息通信SignalR解释

定义集线器接口 IOnlineUserHub public interface IOnlineUserHub {/// 在线用户列表Task OnlineUserList(OnlineUserList context);/// 强制下线Task ForceOffline(object context);/// 发布站内消息Task PublicNotice(SysNotice context);/// 接收消息Task ReceiveMessage(…...

.Net框架,除了EF还有很多很多......

文章目录 1. 引言2. Dapper2.1 概述与设计原理2.2 核心功能与代码示例基本查询多映射查询存储过程调用 2.3 性能优化原理2.4 适用场景 3. NHibernate3.1 概述与架构设计3.2 映射配置示例Fluent映射XML映射 3.3 查询示例HQL查询Criteria APILINQ提供程序 3.4 高级特性3.5 适用场…...

Python:操作 Excel 折叠

💖亲爱的技术爱好者们,热烈欢迎来到 Kant2048 的博客!我是 Thomas Kant,很开心能在CSDN上与你们相遇~💖 本博客的精华专栏: 【自动化测试】 【测试经验】 【人工智能】 【Python】 Python 操作 Excel 系列 读取单元格数据按行写入设置行高和列宽自动调整行高和列宽水平…...

【入坑系列】TiDB 强制索引在不同库下不生效问题

文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

Linux简单的操作

ls ls 查看当前目录 ll 查看详细内容 ls -a 查看所有的内容 ls --help 查看方法文档 pwd pwd 查看当前路径 cd cd 转路径 cd .. 转上一级路径 cd 名 转换路径 …...

[ICLR 2022]How Much Can CLIP Benefit Vision-and-Language Tasks?

论文网址&#xff1a;pdf 英文是纯手打的&#xff01;论文原文的summarizing and paraphrasing。可能会出现难以避免的拼写错误和语法错误&#xff0c;若有发现欢迎评论指正&#xff01;文章偏向于笔记&#xff0c;谨慎食用 目录 1. 心得 2. 论文逐段精读 2.1. Abstract 2…...

el-switch文字内置

el-switch文字内置 效果 vue <div style"color:#ffffff;font-size:14px;float:left;margin-bottom:5px;margin-right:5px;">自动加载</div> <el-switch v-model"value" active-color"#3E99FB" inactive-color"#DCDFE6"…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...