QMenu理论总结
- 一、概述
- 二、常用操作
- 1. 添加Action
- 2. 信号槽
- 3. 可撕下菜单
- 4. 展示菜单
一、概述
QMenu其实就是菜单控件,菜单控件本质上就是一个选择项目。它可以是菜单栏中的下拉菜单,也可以是独立的上下文菜单。当用户单击相应的位置或按下指定的快捷键时,下拉菜单由菜单栏显示。使用QMenuBar::addMenu()向菜单栏插入一个菜单。当然菜单同样也是可以嵌套使用,也就是按钮里面嵌套按钮的。
样子就像这种单层菜单
还有嵌套的菜单
二、常用操作
1. 添加Action
菜单由一系列 QAction 组成。其实就是一个菜单下面要么是QAction, 或者是 QMenu, Action 是通过addAction()、addActions()和insertAction()函数添加的。一个 Action 由QStyle 按照垂直表示并渲染。此外, Action 可以有一个文本标签,在最左边绘制一个可选的图标,以及快捷键序列,如“Ctrl+X”。可以用 actions() 找到菜单中现有的操作。
在QMenu 里面有四种类型的 Action:分隔符、子菜单。、Widget,普通 Action。分隔符是用addSeparator()插入的,子菜单是用addMenu()插入的,所有其他项都被认为是 QAction 。
我们可以使用clear()清除菜单,使用removeAction()删除单个 QAction 。
2. 信号槽
当插入 Action 项时,我们一般会指定 槽函数用于给这个 QAction连接好,当这个菜单项目也即是 QAction 被点击的时候有一个函数来处理点击的响应,每当项目被triggered()时,槽函数就会收到通知。此外,QMenu提供了两个信号:triggered()和hover(),它们表示从菜单中触发的QAction。
信号 | 含义 |
---|---|
void aboutToHide() | 就是这个被激活后,马上要隐藏这个菜单项时,触发的信号 |
void aboutToShow() | 就是被激活时,马上要展示这个菜单时,发射的信号 |
void hovered(QAction *action) | 就是鼠标移到这个QAction的上面是 |
void triggered(QAction *action) | 被快捷键、或者被点击的时候触发 |
3. 可撕下菜单
QMenu还可以提供一个可撕下的菜单。可撕下菜单是一个顶层窗口,其中包含该菜单的副本。这使得用户可以“撕下”经常使用的菜单,并将它们放置在屏幕上方便的位置。这个用的少些,其实就是把菜单从之前依附的窗口分离出来。
像 icon,title 这些属性就是可以设置这个分离出来的菜单的窗口的图标和标题之类的。就像这种,但是里面内容是 Action而已。
如果你想为特定的菜单提供此功能,可以使用setTearOffEnabled()插入一个撕下句柄。当使用可撕式菜单时,请记住这个概念通常在Microsoft Windows上不使用,所以一些用户可能不熟悉它。考虑改用QToolBar。
控件可以用QWidgetAction类插入到菜单中。该类的实例用于保存控件,并通过addAction()重载插入到菜单中,该重载接受一个QAction。同样的,我们可以使用addAction()、addActions()和insertAction()函数向部件添加操作。
4. 展示菜单
context 菜单通常通过一些特殊的键盘键或右键单击(比如QPushButton用的右键菜单)来调用。它们可以通过popup()异步执行,也可以通过exec()同步执行。也可以在按下按钮时调用菜单;除了调用方式不同之外,它们类似于上下文菜单。
- exec() 方式
QAction *QMenu::exec() 同步显示这个菜单。这等价于exec(pos())。返回值其实就是在弹出菜单或其中一个子菜单中触发的QAction,如果没有项被触发(通常是因为用户按了Esc),则返回nullptr。
在大多数情况下,你需要自己指定位置,例如,
//当前鼠标位置:
exec(QCursor::pos());
//或者与某个窗口对象指定对齐到 0,0 就是左上对齐
exec(somewidget.mapToGlobal(QPoint(0,0)));
//或者和鼠标事件的位置相匹配 QMouseEvent *e:
exec(e->globalPos());
- popup() 方式
void QMenu::popup(const QPoint &p, QAction *atAction = nullptr) 异步显示菜单,以便操作atAction位于指定的全局位置p。要将控件的局部坐标转换为全局坐标,使用QWidget::mapToGlobal()。
当使用exec()或popup()定位菜单时,请记住,不能依赖菜单的当前size()。出于性能原因,菜单只在必要时调整其大小,因此在许多情况下,显示前后的大小是不同的。相反,使用sizeHint(),它根据菜单的当前内容计算适当的大小。
- 注意:要使QMenu在屏幕上可见,应该使用exec()或popup()而不是show()