Qt QMenu 使用详解
QMenu 简介
QMenu
是 Qt 中用于创建菜单的组件,通常作为下拉菜单出现在菜单栏(QMenuBar
)或上下文菜单(右键菜单)中。它可以包含子菜单、动作项(QAction
)、分隔符等。
基础用法
1. 创建菜单栏(QMenuBar)
菜单栏通常位于窗口顶部。以下是一个简单的菜单栏和菜单项的创建示例:
#include <QMainWindow>
#include <QMenuBar>
#include <QMenu>
#include <QAction>
class MainWindow : public QMainWindow {
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
// 创建菜单栏
QMenuBar *menuBar = new QMenuBar(this);
setMenuBar(menuBar);
// 创建菜单(文件菜单)
QMenu *fileMenu = menuBar->addMenu("文件(&F)");
// 添加动作项
QAction *openAction = new QAction("打开", this);
QAction *saveAction = new QAction("保存", this);
QAction *exitAction = new QAction("退出", this);
fileMenu->addAction(openAction);
fileMenu->addAction(saveAction);
fileMenu->addSeparator(); // 添加分隔符
fileMenu->addAction(exitAction);
// 连接信号槽
connect(exitAction, &QAction::triggered, this, &QMainWindow::close);
}
};
2. 创建上下文菜单(右键菜单)
通过重写 contextMenuEvent
事件实现右键菜单
class MyWidget : public QWidget {
protected:
void contextMenuEvent(QContextMenuEvent *event) override {
QMenu menu(this);
menu.addAction("复制");
menu.addAction("粘贴");
menu.addSeparator();
menu.addAction("设置");
// 在鼠标位置显示菜单(Qt 5+ 推荐使用 exec())
menu.exec(event->globalPos());
}
};
3. 添加分隔线
QAction *actionNew = fileMenu->addAction("新建");
QAction *actionOpen = fileMenu->addAction("打开");
fileMenu->addSeparator();//添加分隔线
QAction *actionExit = fileMenu->addAction("退出");
fileMenu->addAction(actionExit);
进阶功能
1. 子菜单(嵌套菜单)
QMenu *fileMenu = menuBar->addMenu("文件(&F)");
QMenu *recentFilesMenu = new QMenu("最近打开", this);
fileMenu->addMenu(recentFilesMenu);
// 添加子菜单项
recentFilesMenu->addAction("file1.txt");
recentFilesMenu->addAction("file2.txt");
2. 图标和快捷键
QAction *openAction = new QAction("打开", this);
openAction->setIcon(QIcon(":/icons/open.png")); // 设置图标
openAction->setShortcut(QKeySequence::Open); // 设置快捷键(如 Ctrl+O)
fileMenu->addAction(openAction);
3. 单选/多选菜单项
使用 QActionGroup
实现单选效果:
QMenu *viewMenu = menuBar->addMenu("视图(&V)");
QActionGroup *alignmentGroup = new QActionGroup(this);
QAction *leftAlign = new QAction("左对齐", this);
leftAlign->setCheckable(true); // 设置为可选中
QAction *centerAlign = new QAction("居中", this);
centerAlign->setCheckable(true);
alignmentGroup->addAction(leftAlign);
alignmentGroup->addAction(centerAlign);
alignmentGroup->setExclusive(true); // 设置互斥(单选)
viewMenu->addActions(alignmentGroup->actions());
3. 单选/多选菜单项
使用 QActionGroup
实现单选效果:
QMenu *viewMenu = menuBar->addMenu("视图(&V)");
QActionGroup *alignmentGroup = new QActionGroup(this);
QAction *leftAlign = new QAction("左对齐", this);
leftAlign->setCheckable(true); // 设置为可选中
QAction *centerAlign = new QAction("居中", this);
centerAlign->setCheckable(true);
alignmentGroup->addAction(leftAlign);
alignmentGroup->addAction(centerAlign);
alignmentGroup->setExclusive(true); // 设置互斥(单选)
viewMenu->addActions(alignmentGroup->actions());
4. 动态更新菜单
在菜单显示前更新内容(例如最近打开的文件列表):
connect(fileMenu, &QMenu::aboutToShow, [this]() {
recentFilesMenu->clear();
for (const QString &file : m_recentFiles) {
recentFilesMenu->addAction(file);
}
});
信号与槽
QAction
的常用信号:
-
triggered()
:当用户点击菜单项时触发。 -
hovered()
:当鼠标悬停在菜单项上时触发。
connect(openAction, &QAction::triggered, this, [this]() {
QString file = QFileDialog::getOpenFileName(this);
if (!file.isEmpty()) {
// 处理打开文件
}
});
样式自定义
通过 Qt 样式表(QSS)美化菜单:
menu.setStyleSheet(
"QMenu { background-color: #333; color: white; }"
"QMenu::item:selected { background-color: #666; }"
"QMenu::separator { height: 1px; background: #555; }"
);
常见问题
-
菜单项不可见?
-
确保父对象正确设置(如
QMenu
的父对象是窗口或部件)。 -
检查菜单是否被正确添加到菜单栏或父菜单中。
-
-
跨平台差异
-
macOS 会将第一个菜单的标题设为应用名,需注意国际化。
-
-
内存泄漏
-
确保菜单和动作项的父对象正确管理生命周期。
-
完整示例
#include <QApplication>
#include <QMainWindow>
#include <QMenuBar>
#include <QAction>
#include <QMessageBox>
class MainWindow : public QMainWindow {
public:
MainWindow(QWidget *parent = nullptr) : QMainWindow(parent) {
setupMenu();
}
private:
void setupMenu() {
QMenuBar *menuBar = new QMenuBar(this);
setMenuBar(menuBar);
// 文件菜单
QMenu *fileMenu = menuBar->addMenu("文件(&F)");
QAction *openAction = fileMenu->addAction("打开");
QAction *exitAction = fileMenu->addAction("退出");
connect(exitAction, &QAction::triggered, qApp, &QApplication::quit);
// 帮助菜单
QMenu *helpMenu = menuBar->addMenu("帮助(&H)");
QAction *aboutAction = helpMenu->addAction("关于");
connect(aboutAction, &QAction::triggered, []() {
QMessageBox::information(nullptr, "关于", "Qt QMenu 示例");
});
}
};
int main(int argc, char *argv[]) {
QApplication app(argc, argv);
MainWindow window;
window.resize(800, 600);
window.show();
return app.exec();
}
通过以上教程,你可以掌握 QMenu
的核心用法。如需更复杂的交互,可参考 Qt 官方文档:QMenu Class。