
在 Qt 桌面应用开发中,菜单栏是人机交互的核心组件之一。无论是记事本、浏览器还是专业的开发工具,菜单栏都承载着核心功能入口的重要角色。QMainWindow 作为 Qt 主窗口的核心类,为菜单栏提供了完善的封装与灵活的扩展能力。本文将从基础创建到实战开发,手把手带你掌握 Qt 菜单栏的所有核心技能,让你快速打造出美观、实用的专业级菜单栏。下面就让我们正式开始吧!
在深入代码之前,我们首先要理清 Qt 菜单栏的核心组成部分。Qt 的菜单栏体系由三个核心元素构成:菜单栏(QMenuBar)、菜单(QMenu)和菜单项(QAction),三者层层递进、各司其职,共同构成完整的菜单交互系统。

QMenuBar 是菜单栏的容器,一个 QMainWindow 主窗口最多只能有一个菜单栏,它默认位于主窗口标题栏下方,是所有菜单的 “总载体”。QMenu 则是具体的菜单选项,比如我们常见的 “文件”“编辑”“帮助” 等,一个菜单栏可以包含多个菜单。而 QAction 是菜单项的抽象表示,它不仅可以作为菜单中的选项(如 “新建”“保存”),还能被工具栏复用,实现菜单与工具栏功能的统一。
这里需要特别注意的是:Qt 中并没有专门的 “菜单项类”,QAction 作为动作抽象类,承担了菜单项的功能。这种设计的优势在于,同一个 QAction 对象可以同时关联菜单栏、工具栏甚至快捷键,避免了功能重复实现,极大提升了代码复用性。

另外,Qt 菜单栏支持分割线(Separator)功能,通过简单的 API 调用就能在菜单项之间添加分割线,让菜单结构更清晰,便于用户快速区分不同功能模块。接下来,我们将从最基础的创建开始,逐步构建完整的菜单栏系统。
创建菜单栏是使用菜单系统的第一步,Qt 提供了两种灵活的创建方式,分别适用于不同的开发场景。无论哪种方式,最终都需要通过 setMenuBar () 函数将菜单栏添加到 QMainWindow 主窗口中。
QMainWindow 类内置了 menuBar () 函数,该函数会自动创建一个 QMenuBar 对象(如果尚未创建),并返回该对象的指针。这种方式无需手动管理内存(Qt 父对象机制会自动处理),是最简洁、推荐的使用方式。
函数原型:
QMenuBar *menuBar() const;实现代码:
// 主窗口构造函数中实现
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 1. 通过menuBar()函数获取或创建菜单栏对象
QMenuBar *menubar = this->menuBar();
// 2. 将菜单栏设置到主窗口(必不可少的一步)
this->setMenuBar(menubar);
// 验证菜单栏是否创建成功(可选,调试用)
if (menubar) {
qDebug() << "菜单栏创建成功(方式一)";
}
}适用场景:大多数常规开发场景,尤其是不需要自定义菜单栏父对象或特殊属性时。优点是代码简洁、内存管理省心,符合 Qt 的设计规范。
如果需要对菜单栏进行更灵活的控制(比如自定义父对象、设置特殊样式等),可以手动在堆上创建 QMenuBar 对象。这种方式需要明确指定父对象(通常是主窗口),确保内存能够被正确释放。
实现代码:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 1. 在堆上动态创建菜单栏对象,指定主窗口为父对象
QMenuBar *menuBar = new QMenuBar(this);
// 2. 将菜单栏设置到主窗口
this->setMenuBar(menuBar);
// 验证菜单栏是否创建成功(可选,调试用)
if (menuBar) {
qDebug() << "菜单栏创建成功(方式二)";
}
}注意事项:
创建方式 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
方式一(menuBar () 函数) | 代码简洁、自动内存管理、无需手动创建 | 灵活性稍弱 | 常规开发、无需特殊配置 |
方式二(手动创建) | 灵活性高、支持自定义配置 | 需手动指定父对象、代码量稍多 | 个性化配置、特殊样式需求 |
无论选择哪种方式,后续添加菜单、菜单项的操作完全一致。在实际开发中,推荐优先使用方式一,除非有特殊需求。
创建菜单栏后,下一步就是添加具体的菜单(如 “文件”“编辑”“构建” 等)。菜单通过 QMenu 类创建,然后通过 QMenuBar 的 addMenu () 函数添加到菜单栏中。
实现代码:
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 第一步:创建菜单栏(使用推荐的方式一)
QMenuBar *menubar = this->menuBar();
this->setMenuBar(menubar);
// 第二步:创建多个菜单对象
// 参数1:菜单名称(显示在菜单栏上的文本)
// 参数2:父对象(指定为菜单栏,确保内存正确管理)
QMenu *menuFile = new QMenu("文件(&F)", menubar); // &F表示快捷键Alt+F
QMenu *menuEdit = new QMenu("编辑(&E)", menubar); // &E表示快捷键Alt+E
QMenu *menuBuild = new QMenu("构建(&B)", menubar); // &B表示快捷键Alt+B
QMenu *menuHelp = new QMenu("帮助(&H)", menubar); // &H表示快捷键Alt+H
// 第三步:将菜单添加到菜单栏中(添加顺序决定菜单显示顺序)
menubar->addMenu(menuFile);
menubar->addMenu(menuEdit);
menubar->addMenu(menuBuild);
menubar->addMenu(menuHelp);
// 可选:设置菜单的提示信息(鼠标悬停时显示)
menuFile->setToolTip("文件操作:新建、打开、保存、退出等");
menuEdit->setToolTip("编辑操作:复制、粘贴、撤销、查找等");
}在菜单名称中添加 “&+ 字母”(如 “文件 (&F)”),可以为菜单设置 Alt + 字母的快捷键。这是 Qt 的标准用法,无需额外编写代码,就能实现菜单的快速激活,提升用户体验。
例如:
菜单的显示顺序由 addMenu () 函数的调用顺序决定。先调用 addMenu () 的菜单会显示在菜单栏的左侧,后调用的则依次向右排列。
如果需要调整菜单顺序,可以:
// 在menuFile和menuEdit之间插入一个“视图”菜单
QMenu *menuView = new QMenu("视图(&V)", menubar);
menubar->insertMenu(menuEdit, menuView); // 在menuEdit之前插入menuViewQT += core gui widgets并确保编译器支持中文。菜单项是菜单的核心内容,用于触发具体的功能(如 “新建文件”“保存文件”)。Qt 中通过 QAction 类实现菜单项,一个 QAction 对象可以同时被菜单和工具栏使用,实现功能复用。
QAction 不仅是菜单项的载体,还支持设置图标、快捷键、提示信息等,核心 API 如下:
QAction(const QString &text, QObject *parent):创建菜单项,指定显示文本和父对象。MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 第一步:创建菜单栏和菜单(延续之前的代码)
QMenuBar *menubar = this->menuBar();
this->setMenuBar(menubar);
QMenu *menuFile = new QMenu("文件(&F)", menubar);
menubar->addMenu(menuFile);
// 第二步:创建菜单项(QAction对象)
// 1. 新建文件菜单项
QAction *actNew = new QAction(QIcon(":/icons/new.png"), "新建文件(&N)", menuFile);
actNew->setShortcut(QKeySequence::New); // 标准快捷键:Ctrl+N
actNew->setToolTip("新建一个空白文件(Ctrl+N)");
actNew->setStatusTip("新建空白文件");
// 2. 打开文件菜单项
QAction *actOpen = new QAction(QIcon(":/icons/open.png"), "打开文件(&O)", menuFile);
actOpen->setShortcut(QKeySequence::Open); // 标准快捷键:Ctrl+O
actOpen->setToolTip("打开已存在的文件(Ctrl+O)");
actNew->setStatusTip("打开文件");
// 3. 保存文件菜单项
QAction *actSave = new QAction(QIcon(":/icons/save.png"), "保存文件(&S)", menuFile);
actSave->setShortcut(QKeySequence::Save); // 标准快捷键:Ctrl+S
actSave->setToolTip("保存当前文件(Ctrl+S)");
actNew->setStatusTip("保存文件");
// 4. 退出程序菜单项
QAction *actExit = new QAction(QIcon(":/icons/exit.png"), "退出(&X)", menuFile);
actExit->setShortcut(QKeySequence::Quit); // 标准快捷键:Ctrl+Q
actExit->setToolTip("退出应用程序(Ctrl+Q)");
actNew->setStatusTip("退出程序");
// 第三步:将菜单项添加到菜单中(添加顺序决定菜单项显示顺序)
menuFile->addAction(actNew);
menuFile->addAction(actOpen);
menuFile->addAction(actSave);
menuFile->addAction(actExit);
// 第四步:关联菜单项的触发信号(triggered())与槽函数(后续实战部分详细讲解)
connect(actNew, &QAction::triggered, this, &MainWindow::onActNewTriggered);
connect(actOpen, &QAction::triggered, this, &MainWindow::onActOpenTriggered);
connect(actSave, &QAction::triggered, this, &MainWindow::onActSaveTriggered);
connect(actExit, &QAction::triggered, this, &MainWindow::close); // 直接关联主窗口的close()函数
}
// 槽函数实现(示例)
void MainWindow::onActNewTriggered()
{
qDebug() << "新建文件菜单项被触发";
// 实际开发中添加新建文件的逻辑
}
void MainWindow::onActOpenTriggered()
{
qDebug() << "打开文件菜单项被触发";
// 实际开发中添加打开文件的逻辑
}
void MainWindow::onActSaveTriggered()
{
qDebug() << "保存文件菜单项被触发";
// 实际开发中添加保存文件的逻辑
}QKeySequence 类提供了大量标准快捷键的枚举值,使用这些标准快捷键可以让应用程序更符合用户的使用习惯,提升兼容性。常见的标准快捷键如下:
为菜单项添加图标可以让界面更直观,Qt 支持多种图标格式(如.png、.svg、.ico 等)。设置图标时,推荐使用 Qt 的资源文件(.qrc)管理图标,避免文件路径问题。
资源文件使用步骤:
QIcon(":/icons/图标文件名.png")引用图标。当一个菜单包含多个功能模块的菜单项时,使用分割线可以将不同模块的菜单项分隔开,让菜单结构更清晰,便于用户快速定位功能。Qt 中通过 QMenu 的 addSeparator () 函数添加分割线,使用非常简单。
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
// 第一步:创建菜单栏和菜单
QMenuBar *menubar = this->menuBar();
this->setMenuBar(menubar);
QMenu *menuFile = new QMenu("文件(&F)", menubar);
menubar->addMenu(menuFile);
// 第二步:创建菜单项
QAction *actNew = new QAction(QIcon(":/icons/new.png"), "新建文件(&N)", menuFile);
QAction *actOpen = new QAction(QIcon(":/icons/open.png"), "打开文件(&O)", menuFile);
QAction *actSave = new QAction(QIcon(":/icons/save.png"), "保存文件(&S)", menuFile);
QAction *actSaveAs = new QAction("另存为(&A)", menuFile);
QAction *actPageSetup = new QAction("页面设置(&U)", menuFile);
QAction *actPrint = new QAction("打印(&P)", menuFile);
QAction *actExit = new QAction(QIcon(":/icons/exit.png"), "退出(&X)", menuFile);
// 第三步:添加菜单项并插入分割线
// 第一组:文件操作(新建、打开、保存、另存为)
menuFile->addAction(actNew);
menuFile->addAction(actOpen);
menuFile->addAction(actSave);
menuFile->addAction(actSaveAs);
// 添加分割线(分隔文件操作与页面设置)
menuFile->addSeparator();
// 第二组:打印相关(页面设置、打印)
menuFile->addAction(actPageSetup);
menuFile->addAction(actPrint);
// 添加分割线(分隔打印相关与退出)
menuFile->addSeparator();
// 第三组:退出程序
menuFile->addAction(actExit);
// 关联信号槽(省略,同之前的代码)
}添加分割线后,菜单会呈现出清晰的分组结构:

前面我们已经学习了菜单栏、菜单、菜单项、分割线的核心用法,现在通过一个实战案例,将这些知识整合起来,打造一个完整的菜单栏,并在其中添加一些菜单项。
我们将实现一个简易记事本,菜单栏包含 “文件”“编辑”“帮助” 三个菜单,具体功能如下:
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QTextEdit>
#include <QFileDialog>
#include <QMessageBox>
#include <QKeySequence>
#include <fstream>
#include <string>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private slots:
// 文件菜单槽函数
void onActNewTriggered(); // 新建文件
void onActOpenTriggered(); // 打开文件
void onActSaveTriggered(); // 保存文件
void onActSaveAsTriggered(); // 另存为
void onActExitTriggered(); // 退出程序
// 编辑菜单槽函数
void onActCopyTriggered(); // 复制
void onActPasteTriggered(); // 粘贴
void onActUndoTriggered(); // 撤销
void onActRedoTriggered(); // 重做
void onActFindTriggered(); // 查找
// 帮助菜单槽函数
void onActAboutTriggered(); // 关于记事本
private:
Ui::MainWindow *ui;
QTextEdit *m_textEdit; // 文本编辑区域
QString m_currentFileName; // 当前打开的文件名(含路径)
};
#endif // MAINWINDOW_H#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
, m_currentFileName("") // 初始化当前文件名为空
{
ui->setupUi(this);
// 1. 设置主窗口属性
this->setWindowTitle("我的记事本 - Qt菜单栏实战");
this->resize(800, 600); // 设置窗口大小
// 2. 创建中央文本编辑控件
m_textEdit = new QTextEdit(this);
m_textEdit->setPlaceholderText("请在此输入文本内容...");
m_textEdit->setFont(QFont("微软雅黑", 12)); // 设置默认字体
this->setCentralWidget(m_textEdit); // 设置为中央控件
// 3. 创建菜单栏
QMenuBar *menubar = this->menuBar();
this->setMenuBar(menubar);
// 4. 创建菜单
QMenu *menuFile = new QMenu("文件(&F)", menubar);
QMenu *menuEdit = new QMenu("编辑(&E)", menubar);
QMenu *menuHelp = new QMenu("帮助(&H)", menubar);
menubar->addMenu(menuFile);
menubar->addMenu(menuEdit);
menubar->addMenu(menuHelp);
// 5. 创建文件菜单的菜单项
QAction *actNew = new QAction(QIcon(":/icons/new.png"), "新建(&N)", menuFile);
QAction *actOpen = new QAction(QIcon(":/icons/open.png"), "打开(&O)", menuFile);
QAction *actSave = new QAction(QIcon(":/icons/save.png"), "保存(&S)", menuFile);
QAction *actSaveAs = new QAction("另存为(&A)", menuFile);
QAction *actExit = new QAction(QIcon(":/icons/exit.png"), "退出(&X)", menuFile);
// 设置文件菜单项快捷键
actNew->setShortcut(QKeySequence::New);
actOpen->setShortcut(QKeySequence::Open);
actSave->setShortcut(QKeySequence::Save);
actSaveAs->setShortcut(QKeySequence::SaveAs);
actExit->setShortcut(QKeySequence::Quit);
// 设置文件菜单项提示信息
actNew->setToolTip("新建空白文件(Ctrl+N)");
actOpen->setToolTip("打开已存在的文件(Ctrl+O)");
actSave->setToolTip("保存当前文件(Ctrl+S)");
actSaveAs->setToolTip("将当前文件另存为(Ctrl+Shift+S)");
actExit->setToolTip("退出记事本应用(Ctrl+Q)");
// 添加文件菜单项和分割线
menuFile->addAction(actNew);
menuFile->addAction(actOpen);
menuFile->addAction(actSave);
menuFile->addAction(actSaveAs);
menuFile->addSeparator();
menuFile->addAction(actExit);
// 6. 创建编辑菜单的菜单项
QAction *actUndo = new QAction("撤销(&U)", menuEdit);
QAction *actRedo = new QAction("重做(&R)", menuEdit);
QAction *actCopy = new QAction("复制(&C)", menuEdit);
QAction *actPaste = new QAction("粘贴(&V)", menuEdit);
QAction *actFind = new QAction("查找(&F)", menuEdit);
// 设置编辑菜单项快捷键
actUndo->setShortcut(QKeySequence::Undo);
actRedo->setShortcut(QKeySequence::Redo);
actCopy->setShortcut(QKeySequence::Copy);
actPaste->setShortcut(QKeySequence::Paste);
actFind->setShortcut(QKeySequence::Find);
// 设置编辑菜单项提示信息
actUndo->setToolTip("撤销上一步操作(Ctrl+Z)");
actRedo->setToolTip("重做上一步操作(Ctrl+Shift+Z)");
actCopy->setToolTip("复制选中的文本(Ctrl+C)");
actPaste->setToolTip("粘贴复制的文本(Ctrl+V)");
actFind->setToolTip("查找文本内容(Ctrl+F)");
// 添加编辑菜单项和分割线
menuEdit->addAction(actUndo);
menuEdit->addAction(actRedo);
menuEdit->addSeparator();
menuEdit->addAction(actCopy);
menuEdit->addAction(actPaste);
menuEdit->addSeparator();
menuEdit->addAction(actFind);
// 7. 创建帮助菜单的菜单项
QAction *actAbout = new QAction("关于记事本(&A)", menuHelp);
actAbout->setToolTip("查看记事本的版本信息和作者");
menuHelp->addAction(actAbout);
// 8. 关联所有菜单项的信号槽
// 文件菜单
connect(actNew, &QAction::triggered, this, &MainWindow::onActNewTriggered);
connect(actOpen, &QAction::triggered, this, &MainWindow::onActOpenTriggered);
connect(actSave, &QAction::triggered, this, &MainWindow::onActSaveTriggered);
connect(actSaveAs, &QAction::triggered, this, &MainWindow::onActSaveAsTriggered);
connect(actExit, &QAction::triggered, this, &MainWindow::onActExitTriggered);
// 编辑菜单
connect(actUndo, &QAction::triggered, this, &MainWindow::onActUndoTriggered);
connect(actRedo, &QAction::triggered, this, &MainWindow::onActRedoTriggered);
connect(actCopy, &QAction::triggered, this, &MainWindow::onActCopyTriggered);
connect(actPaste, &QAction::triggered, this, &MainWindow::onActPasteTriggered);
connect(actFind, &QAction::triggered, this, &MainWindow::onActFindTriggered);
// 帮助菜单
connect(actAbout, &QAction::triggered, this, &MainWindow::onActAboutTriggered);
}
MainWindow::~MainWindow()
{
delete ui;
}
// 新建文件槽函数
void MainWindow::onActNewTriggered()
{
// 询问用户是否保存当前文件(如果有内容)
if (!m_textEdit->toPlainText().isEmpty()) {
QMessageBox::StandardButton ret = QMessageBox::question(this, "提示", "当前文件内容未保存,是否保存?",
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if (ret == QMessageBox::Save) {
onActSaveTriggered(); // 调用保存文件函数
} else if (ret == QMessageBox::Cancel) {
return; // 取消新建操作
}
// 若选择Discard,则直接放弃保存,继续新建
}
// 清空文本编辑区域和当前文件名
m_textEdit->clear();
m_currentFileName = "";
this->setWindowTitle("我的记事本 - Qt菜单栏实战");
}
// 打开文件槽函数
void MainWindow::onActOpenTriggered()
{
// 弹出文件选择对话框,只允许选择文本文件
QString fileName = QFileDialog::getOpenFileName(this, "打开文件", QDir::homePath(),
"文本文件 (*.txt);;所有文件 (*.*)");
if (fileName.isEmpty()) {
return; // 用户取消选择
}
// 询问用户是否保存当前文件(如果有内容)
if (!m_textEdit->toPlainText().isEmpty()) {
QMessageBox::StandardButton ret = QMessageBox::question(this, "提示", "当前文件内容未保存,是否保存?",
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if (ret == QMessageBox::Save) {
onActSaveTriggered(); // 调用保存文件函数
} else if (ret == QMessageBox::Cancel) {
return; // 取消打开操作
}
}
// 读取选中的文件内容
std::ifstream file(fileName.toStdString().c_str());
if (!file.is_open()) {
QMessageBox::critical(this, "错误", "无法打开文件!");
return;
}
// 读取文件内容到字符串
std::string content;
std::string line;
while (std::getline(file, line)) {
content += line + "\n";
}
file.close();
// 将内容显示到文本编辑区域
m_textEdit->setPlainText(QString::fromStdString(content));
m_currentFileName = fileName;
// 更新窗口标题,显示当前打开的文件名
this->setWindowTitle(QString("我的记事本 - %1").arg(fileName));
}
// 保存文件槽函数
void MainWindow::onActSaveTriggered()
{
// 如果当前文件未保存过(文件名为空),则调用另存为
if (m_currentFileName.isEmpty()) {
onActSaveAsTriggered();
return;
}
// 写入文件
std::ofstream file(m_currentFileName.toStdString().c_str());
if (!file.is_open()) {
QMessageBox::critical(this, "错误", "无法保存文件!");
return;
}
// 将文本编辑区域的内容写入文件
QString text = m_textEdit->toPlainText();
file << text.toStdString();
file.close();
// 显示保存成功提示
QMessageBox::information(this, "提示", "文件保存成功!");
}
// 另存为槽函数
void MainWindow::onActSaveAsTriggered()
{
// 弹出保存文件对话框
QString fileName = QFileDialog::getSaveFileName(this, "另存为", QDir::homePath(),
"文本文件 (*.txt);;所有文件 (*.*)");
if (fileName.isEmpty()) {
return; // 用户取消保存
}
// 写入文件
std::ofstream file(fileName.toStdString().c_str());
if (!file.is_open()) {
QMessageBox::critical(this, "错误", "无法保存文件!");
return;
}
// 将文本编辑区域的内容写入文件
QString text = m_textEdit->toPlainText();
file << text.toStdString();
file.close();
// 更新当前文件名和窗口标题
m_currentFileName = fileName;
this->setWindowTitle(QString("我的记事本 - %1").arg(fileName));
// 显示保存成功提示
QMessageBox::information(this, "提示", "文件保存成功!");
}
// 退出程序槽函数
void MainWindow::onActExitTriggered()
{
// 询问用户是否保存当前文件(如果有内容)
if (!m_textEdit->toPlainText().isEmpty()) {
QMessageBox::StandardButton ret = QMessageBox::question(this, "提示", "当前文件内容未保存,是否保存?",
QMessageBox::Save | QMessageBox::Discard | QMessageBox::Cancel);
if (ret == QMessageBox::Save) {
onActSaveTriggered(); // 调用保存文件函数
} else if (ret == QMessageBox::Cancel) {
return; // 取消退出操作
}
}
// 关闭主窗口(退出程序)
this->close();
}
// 撤销槽函数
void MainWindow::onActUndoTriggered()
{
m_textEdit->undo();
}
// 重做槽函数
void MainWindow::onActRedoTriggered()
{
m_textEdit->redo();
}
// 复制槽函数
void MainWindow::onActCopyTriggered()
{
m_textEdit->copy();
}
// 粘贴槽函数
void MainWindow::onActPasteTriggered()
{
m_textEdit->paste();
}
// 查找槽函数(简易实现)
void MainWindow::onActFindTriggered()
{
// 弹出输入对话框,让用户输入要查找的文本
QString findText = QInputDialog::getText(this, "查找", "请输入要查找的文本:");
if (findText.isEmpty()) {
return;
}
// 在文本编辑区域中查找文本
bool found = m_textEdit->find(findText, QTextDocument::FindCaseSensitively);
if (!found) {
QMessageBox::information(this, "提示", "未找到指定文本!");
}
}
// 关于记事本槽函数
void MainWindow::onActAboutTriggered()
{
// 弹出关于对话框
QMessageBox::about(this, "关于我的记事本",
"<h2>我的记事本 v1.0</h2>"
"<p>基于Qt 5.14开发的简易记事本应用</p>"
"<p>核心功能:文件读写、文本编辑、查找</p>"
"<p>作者:Qt学习爱好者</p>"
"<p>版权所有 © 2024</p>");
}首先创建资源文件:


添加一个简单的前缀:

然后把所需的图标的图片文件导入:






std::ifstream(读文件)和std::ofstream(写文件),结合 Qt 的QFileDialog选择文件路径。QMessageBox弹出提示、确认、错误对话框,QInputDialog获取用户输入的查找文本。QKeySequence的标准快捷键枚举,让菜单项支持系统统一的快捷键。m_currentFileName变量记录当前打开的文件路径,实现保存和另存为的逻辑区分。除了基础功能,Qt 还支持对菜单栏进行多种个性化定制,让你的应用界面更具特色。以下是几个常用的高级技巧:
Qt Style Sheets(QSS)是 Qt 的样式表技术,类似于 CSS,可以快速定制控件的外观。通过 QSS 可以修改菜单栏的背景色、字体、选中样式等。
示例代码:
// 在主窗口构造函数中添加
// 设置菜单栏样式
menubar->setStyleSheet(R"(
QMenuBar {
background-color: #f0f0f0;
border-bottom: 2px solid #cccccc;
}
QMenuBar::item {
padding: 4px 16px;
font-size: 14px;
color: #333333;
}
QMenuBar::item:selected {
background-color: #4a90e2;
color: white;
}
QMenu {
background-color: white;
border: 1px solid #cccccc;
font-size: 13px;
}
QMenu::item {
padding: 6px 24px;
}
QMenu::item:selected {
background-color: #4a90e2;
color: white;
}
)"); 在某些场景下(如全屏模式),可能需要隐藏菜单栏。可以通过setMenuBar(nullptr)或menuBar()->hide()实现。
示例代码:
// 隐藏菜单栏
this->setMenuBar(nullptr);
// 或者
// menuBar()->hide();
// 显示菜单栏(如需恢复)
// this->setMenuBar(menubar);
// menuBar()->show(); 当某些功能不可用时(如文本编辑区域无选中内容时,复制功能禁用),可以通过 QAction 的setEnabled(false)禁用菜单项。
示例代码:
// 连接文本编辑区域的selectionChanged信号,动态启用/禁用复制菜单项
connect(m_textEdit, &QTextEdit::selectionChanged, [=]() {
// 如果有选中的文本,则启用复制菜单项,否则禁用
actCopy->setEnabled(!m_textEdit->textCursor().selectedText().isEmpty());
});在程序运行过程中,可以根据需要动态添加或删除菜单项,实现灵活的功能扩展。
示例代码:
// 动态添加菜单项
QAction *actDynamic = new QAction("动态添加的菜单项", menuFile);
menuFile->insertAction(actSaveAs, actDynamic); // 插入到“另存为”之前
// 动态删除菜单项
menuFile->removeAction(actDynamic);
delete actDynamic; // 手动删除,因为是动态创建的在 Qt 菜单栏开发过程中,可能会遇到各种问题,以下是一些常见问题的解决方案:
setMenuBar()函数将菜单栏添加到主窗口。 this->setMenuBar(menubar)。QKeySequence的标准枚举值,避免手动输入快捷键字符串。addAction()和addMenu()的调用是否正确。QFileDialog选择文件,确保文件路径正确;检查文件是否存在且有读写权限。<fstream>)。 #include <fstream>和#include <string>。Qt 的菜单栏系统是桌面应用开发的基础,掌握好这些技能可以为你的应用提供专业、友好的用户交互体验。建议在实际开发中多尝试不同的功能组合,灵活运用 Qt 的 API,打造出更具特色的应用程序。 如果你在开发过程中遇到问题,欢迎在评论区留言交流。也可以参考 Qt 官方文档(https://doc.qt.io/qt-5/qmenubar.html)获取更详细的 API 说明和示例代码。