(8)本源代码来自于头文件 qmenu . h :
#ifndef QMENU_H
#define QMENU_H
#include <QtWidgets/qtwidgetsglobal.h>
#include <QtWidgets/qwidget.h>
#include <QtCore/qstring.h>
#include <QtGui/qicon.h>
#include <QtGui/qaction.h>
QT_REQUIRE_CONFIG(menu);
QT_BEGIN_NAMESPACE
class QMenuPrivate;
class QStyleOptionMenuItem;
class QPlatformMenu;
/*
The QMenu class provides a menu widget for use in menu bars,
context menus, and other popup menus.
菜单小部件是一个选择菜单。它可以是菜单栏中的下拉式选单,也可以是独立的上下文选单。
当用户单击相应的项或按下指定的快捷键时,菜单栏会显示下拉菜单。
使用QMenuBar:addMenu()将菜单插入菜单栏。
上下文菜单通常由某个特殊的键盘键或右键单击调用。它们可以用popup()异步执行,也可以用exec()同步执行。
菜单也可以响应按钮按压而被调用;除了调用方式外,这些菜单与上下文菜单类似。
Actions :
菜单由操作项列表组成。使用addAction()、addActions()和插入Action()函数添加操作。
动作垂直表示并由 QStyle渲染。
此外,操作可以有一个文字标签,一个可选的图标画在最左侧,快捷键顺序,如“Ctrl+X”.
可以使用 actions()函数找到菜单中现有的操作 QAction。
QList<QAction *> QWidget::actions() const;
有四种类型的操作项:分隔符、显示子菜单的操作、小部件和执行操作的操作。
分隔符使用addSeparator()插入,子菜单使用addMenu()插入,所有其他项都被视为操作项。
在插入操作项时,通常需要指定接收者和槽位。每当项被触发()时,接收者都会收到通知。
此外,QMenu提供了两个信号,触发()和悬停()triggered() and hovered(),
这些信号表示从菜单触发的QAction。
You clear a menu with clear() and remove individual action items with removeAction().
QMenu还可以提供拆卸菜单。撕掉菜单是一个顶层窗口,包含菜单的副本。
这使得用户可以“撕掉”常用的菜单,并将其放置在屏幕的方便位置。
如果您希望特定菜单具有此功能,请插入带有setTearOffEnabled()的撕掉手柄。
当使用拖拽式菜单时,请记住,这个概念在微软Windows上并不常用,所以一些用户可能并不熟悉它。
可以考虑使用QToolBar。
可以使用 OWidgetAction 类将窗口小部件插入到菜单中。
此类的实例用于保存小部件,并通过采用QAction的 addAction()重载插入到菜单中。
如果QWidgetAction触发triggered ()信号,则菜单将关闭。
警告:要在屏幕上显示QMenu,应使用exec()或popup(),而不是show()或setVisible()。
要隐藏或禁用菜单栏中的菜单,或在其作为子菜单添加的另一个菜单中禁用它,请使用menuAction()的相应属性。
QMenu on macOS with Qt Build Against Cocoa :
QMenu can be inserted only once in a menu/menubar.
Subsequent insertions will have no effect or will result in a disabled menu item.
See the Menus example for an example of how to use QMenuBar
and QMenu in your application.
*/
class Q_WIDGETS_EXPORT QMenu : public QWidget
{
private:
Q_OBJECT
Q_DECLARE_PRIVATE(QMenu)
//This property holds the title of the menu。
//This is equivalent to the QAction::text property of the menuAction().
//By default, this property contains an empty string.
Q_PROPERTY(QString title READ title WRITE setTitle) //菜单栏里菜单的名字。
Q_PROPERTY(QIcon icon READ icon WRITE setIcon) //菜单栏里菜单的图片。其会取代文本
//This property holds the icon of the menu。
//This is equivalent to the QAction::icon property of the menuAction().
//By default, if no icon is explicitly set, this property contains a null icon.
//这个属性表示菜单是否支持被撕下。 // 默认情况下,此属性为假。
//当为真时,菜单包含一个特殊的撕下项(通常显示为菜单顶部的虚线),当触发时创建菜单的副本。
//这个“撕下”的副本存在于一个单独的窗口中。它包含与原始菜单相同的菜单项,除了撕下的手柄。
Q_PROPERTY(bool tearOffEnabled //此属性在 windows系统上没有用
READ isTearOffEnabled WRITE setTearOffEnabled)
//此属性表示是否应折叠连续的分隔符。 默认情况下,此属性为真。
//此属性指定菜单中的连续分隔符是否应视觉上折叠为一个。菜单开头或结尾的分隔符也会被隐藏。
Q_PROPERTY(bool separatorsCollapsible
READ separatorsCollapsible WRITE setSeparatorsCollapsible)
//动态菜单优化:当菜单内容根据上下文动态变化时(如通过用户操作增减菜单项),
// 连续分隔符可能因内容增减而产生冗余。启用此属性可自动合并多余分隔符,保持菜单整洁。
//边缘分隔符隐藏:若分隔符位于菜单开头或结尾,默认情况下会被隐藏,避免视觉上的突兀感。
Q_PROPERTY(bool toolTipsVisible //默认情况下,此属性为假。
READ toolTipsVisible WRITE setToolTipsVisible)
//此属性表示是否应显示菜单操作的提示信息。此属性指定操作菜单项是否显示其提示信息。
//菜单栏里的提示默认是关闭的,因为不必要重复。工具栏里的按钮提示,默认是打开的,因为必要。
private:
Q_DISABLE_COPY(QMenu)
Q_PRIVATE_SLOT(d_func(), void _q_actionTriggered())
Q_PRIVATE_SLOT(d_func(), void _q_actionHovered())
Q_PRIVATE_SLOT(d_func(), void _q_overrideMenuActionDestroyed())
Q_PRIVATE_SLOT(d_func(), void _q_platformMenuAboutToShow())
friend class QMenuBar;
friend class QMenuBarPrivate;
friend class QTornOffMenu;
friend class QComboBox;
friend class QtWidgetsActionPrivate;
friend class QToolButtonPrivate;
friend void qt_mac_emit_menuSignals (QMenu * menu, bool show);
friend void qt_mac_menu_emit_hovered(QMenu * menu, QAction * action);
protected:
bool event(QEvent *) override;
void changeEvent(QEvent *) override;
void keyPressEvent(QKeyEvent *) override;
void mouseReleaseEvent(QMouseEvent *) override;
void mousePressEvent(QMouseEvent *) override;
void mouseMoveEvent(QMouseEvent *) override;
void wheelEvent(QWheelEvent *) override;
void enterEvent(QEnterEvent *) override;
void leaveEvent(QEvent *) override;
void hideEvent(QHideEvent *) override;
void paintEvent(QPaintEvent *) override;
void actionEvent(QActionEvent *) override;
void timerEvent(QTimerEvent *) override;
//如果菜单无法在屏幕上显示,它会自动调整布局以使其适合屏幕。
//布局的含义取决于样式(例如,在Windows上,它将使用多列)。
int columnCount() const; //此函数返回本菜单所需的列数。
//Reimplements: QWidget::focusNextPrevChild(bool next).
bool focusNextPrevChild(bool next) override;
virtual void initStyleOption(QStyleOptionMenuItem * option,
const QAction * action) const;
QMenu(QMenuPrivate & dd, QWidget * parent = nullptr);
private Q_SLOTS:
void internalDelayedPopup(); //无注释
Q_SIGNALS:
void aboutToShow();
//This signal is emitted just before the menu is shown to the user.
//This signal is emitted just before the menu is hidden from the user.
void aboutToHide();
//This signal is emitted when an action in this menu is triggered.
//action is the action that caused the signal to be emitted.
//Normally, you connect each menu action's triggered() signal to its own custom slot,
//but sometimes you will want to connect several actions to a single slot,
//for example, when you have a group of closely related actions,
//such as "left justify", "center", "right justify".
//Note: This signal is emitted for the main parent menu in a hierarchy.
//Hence, only the parent menu needs to be connected to a slot;
//sub-menus need not be connected. // QAction 具有这俩同名信号的。但信号函数的参数设计的不一样。
void triggered(QAction * action); //本菜单里的按钮被 triggerd,本菜单就会发送本信号。
void hovered (QAction * action); //当本菜单被悬停就触发,形参是高亮的菜单项。
//This signal is emitted when a menu action is highlighted;
//action is the action that caused the signal to be emitted.
//Often this is used to update status information.
//补充:QAction { Q_SIGNALS: void triggered(bool checked = false); void hovered(); };
public:
//Constructs a menu with parent parent.
//Although a popup menu is always a top-level widget,
//if a parent is passed,
//the popup menu will be deleted when that parent is destroyed
//(as with any other QObject).
//举例:menu_F = new QMenu(menubar); 传递的实参可以是菜单栏对象
explicit QMenu(QWidget * parent = nullptr);
explicit QMenu(const QString & title, QWidget * parent = nullptr);
//Constructs a menu with a title and a parent.
~QMenu();
// Q_PROPERTY(QString title READ title WRITE setTitle) //菜单栏里菜单的名字。
QString title() const;
void setTitle(const QString & title);
// Q_PROPERTY(QIcon icon READ icon WRITE setIcon) //该图片会取代文本
QIcon icon () const;
void setIcon (const QIcon & icon);
// Q_PROPERTY(bool tearOffEnabled //此属性在 windows系统上没有用
// READ isTearOffEnabled WRITE setTearOffEnabled)
bool isTearOffEnabled () const;
void setTearOffEnabled (bool );
bool isTearOffMenuVisible() const;
void showTearOffMenu();
void showTearOffMenu(const QPoint & pos);
void hideTearOffMenu();
// Q_PROPERTY(bool separatorsCollapsible //此属性默认为真
// READ separatorsCollapsible WRITE setSeparatorsCollapsible)
bool separatorsCollapsible() const;
void setSeparatorsCollapsible(bool collapse);
// Q_PROPERTY(bool toolTipsVisible //默认情况下,此属性为假。
// READ toolTipsVisible WRITE setToolTipsVisible)
bool toolTipsVisible() const;
void setToolTipsVisible(bool visible);
QAction * defaultAction() const; //Returns the current default action.
void setDefaultAction(QAction * act); //This sets the default action to act.
//默认操作可能具有视觉提示,具体取决于当前 QStyle。默认操作通常指示当出现下拉菜单时默认会发生什么。
//设置后,默认的菜单项将会加粗显示。
//Returns the currently highlighted action,
//or nullptr if no action is currently highlighted.
QAction * activeAction() const; //此函数会返回当前菜单里被高亮显示的菜单项
void setActiveAction(QAction * act);
//Sets the currently highlighted action to act.
QPlatformMenu * platformMenu(); //没有关于 QPlatformMenu的源代码
void setPlatformMenu(QPlatformMenu * platformMenu); //这俩函数无注释
QSize sizeHint() const override;
//class QRect { int x1; int y1; int x2; int y2; }; //返回菜单里菜单项的大小
QRect actionGeometry(QAction * act) const; //Returns the geometry of action act.
//class QPoint { int xp; int yp; };
QAction * actionAt(const QPoint & pt ) const; //返回菜单里在某个位置的菜单项
//Returns the item at pt; returns nullptr if there is no item there.
QAction * menuAction() const; //Returns the action associated with this menu.
//举例:menu_E->addAction(menu_Format_BIU->menuAction()); //!!重要:为菜单添加子菜单
//子菜单是菜单 QMenu类型,但同时也是父菜单里的一个菜单项 QAction,
//本函数即是返回与子菜单关联的父菜单里的菜单项。
//Returns true if there are no visible actions inserted into the menu,
// false otherwise.
bool isEmpty() const;
void clear(); //Removes all the menu's actions. //清空菜单里的所有菜单项
//Actions owned by the menu and not shown in any other widget are deleted。
//Displays the menu so that the action atAction will be at the
// specified global position p.
//要将小部件的局部坐标转换为全局坐标,请使用 QWidget::mapToGlobal()。
//在使用exec()或popup()定位菜单时,请记住您不能依赖菜单的当前大小(currentsize)。
//出于性能原因,菜单仅在必要时调整其大小,因此在许多情况下,显示前后的大小会有所不同。
//相反,使用sizeHint(),它根据菜单的当前内容计算适当的大小。
void popup(const QPoint & p, QAction * atAction = nullptr);
QAction * exec (); //This is equivalent to exec(pos()).
QAction * exec (const QPoint & p, QAction * action = nullptr); //同步执行此菜单。
//弹出菜单,使动作action位于指定的全局位置p。
//要将小部件的局部坐标转换为全局坐标,请使用QWidget::mapToGlobal()。
//这将在弹出式菜单或其子菜单中返回触发的事件处理程序,This returns the
// triggered QAction in either the popup menu or one of its submenus,
//如果没有触发任何项目(通常是因为用户按下了 Esc),则返回nullptr。
//请注意,所有信号都会像往常一样发出。如果您将 QAction连接到槽并调用菜单的exec()方法,
// 则可以通过信号-槽连接或在 exec()方法的返回值中获取结果。
//通常的用法是将菜单定位在当前鼠标位置: exec( QCursor::pos() ); 或用于对齐或关联到 event。
static //静态函数,临时构建菜单,以包含形参1 里的菜单项,并使菜单项 at在位置 pos处显示。
QAction * exec (const QList<QAction *> & actions, //同步执行菜单。
const QPoint & pos, QAction * at = nullptr,
QWidget * parent = nullptr);
//The menu's actions are specified by the list of actions。
//菜单将弹出,以便指定的操作 at出现在全局位置 pos处。如果未指定 at,则菜单将出现在位置 pos处。
//parent是菜单的父容器;指定父容器将提供上下文,若 pos本身不足以确定菜单应位于何处
//(例如,在多桌面或当父容器嵌入在OGraphicsView中时)。
//该函数返回弹出式菜单或其子菜单中触发的事件处理程序,
// 如果未触发任何项目(通常是因为用户按下了Esc),则返回 nullptr。
void setNoReplayFor(QWidget * widget); //无官方注释
using QWidget::addAction; //对,此函数确实定义在父类 QWidget中。参数有很大不同
//void QWidget::addAction(QAction * action);
//This convenience function creates a new action with text.
//The function adds the newly created action to the menu's list of actions,
//and returns it. QMenu takes ownership of the returned QAction.
QAction * addAction(const QString & text); //创建并添加具有文本 text的菜单项并返回之。
QAction * addAction(const QString & text ,
const QObject * receiver,
const char * member ,
const QKeySequence & shortcut = {}
);
//将新建的具有文本 text的按钮(菜单项)的 triggered()信号连接到 receiver的 member槽函数上。
//This convenience function creates a new action with the
//text text and an optional shortcut shortcut.
//The action's triggered() signal is connected to the receiver's member slot.
//This convenience function creates a new action with an icon and some text.
QAction * addAction(const QIcon & icon,
const QString & text);
QAction * addAction(const QIcon & icon, //同理,注释略
const QString & text,
const QObject * receiver,
const char * member,
const QKeySequence & shortcut = {}
);
//将新建的具有文本 text,图片 icon的按钮的 triggered()信号连接到 receiver的 member槽函数上。
// addAction(QString): 本函数要求形参 Obj类型是 QObject的子类型。
//Connect to a QObject slot / functor or function pointer (with context)
template<class Obj, typename Func1> // 形参3 slot是形参2 object的槽函数
inline typename std::enable_if<
! std::is_same<const char *, Func1>::value
&& QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value,
QAction *>::type
addAction(const QString & text, const Obj * object,
Func1 slot, const QKeySequence & shortcut = {} )
{
QAction * result = addAction(text);
result->setShortcut(shortcut);
connect(result, & QAction::triggered, object, std::move(slot));
return result;
}
// addAction(QString): 将新按钮的 triggered()信号绑定到槽函数 slot上。
//Connect to a functor or function pointer (without context)
template <typename Func1> //slot 可能是全局函数,而非某个类的成员函数。
inline QAction * addAction(const QString & text,
Func1 slot, const QKeySequence & shortcut = {} )
{
QAction * result = addAction(text);
result->setShortcut(shortcut);
connect(result, & QAction::triggered, std::move(slot));
return result;
}
// addAction(QIcon, QString):
//Connect to a QObject slot / functor or function pointer (with context)
template<class Obj, typename Func1>
inline typename std::enable_if<
! std::is_same<const char *, Func1>::value
&& QtPrivate::IsPointerToTypeDerivedFromQObject<Obj*>::Value,
QAction *>::type
addAction(const QIcon & actionIcon, const QString & text, //带了一个图片
const Obj * object, Func1 slot, const QKeySequence &shortcut = {} )
{
QAction * result = addAction(actionIcon, text);
result->setShortcut(shortcut);
connect(result, & QAction::triggered, object, std::move(slot));
return result;
}
// addAction(QIcon, QString):
//Connect to a functor or function pointer (without context)
template <typename Func1> //形参 slot 可能是全局函数
inline QAction * addAction(const QIcon & actionIcon, const QString & text,
Func1 slot, const QKeySequence &shortcut = {} )
{
QAction * result = addAction(actionIcon, text);
result->setShortcut(shortcut);
connect(result, &QAction::triggered, std::move(slot));
return result;
}
//This convenience function creates a new separator action,
//i.e. an action with QAction::isSeparator() returning true.
//The function inserts the newly created action into this menu's list of
// actions before action before and returns it.
//QMenu takes ownership of the returned QAction.
QAction * insertSeparator(QAction * before); //在按钮 before的前面插入分隔符
QAction * addSeparator(); //在菜单的最后添加一个分隔符
//This convenience function creates a new title action,
//i.e. an action with QAction::isSeparator() returning true but also having text hint.
//The function inserts the newly created action into this menu's list of
//actions before action before and returns it.
//提示的渲染取决于样式和平台。
//Widget样式可以使用渲染中用于部分的文本信息,或者可以选择忽略它并像简单的分隔符一样渲染部分。
//QMenu 获得了返回的 QAction 的所有权。
//总结:看起来依然是在菜单里,在 before前面,创建分隔条,但分隔条具有提示文本 text。
QAction * insertSection(QAction * before, const QString & text);
QAction * insertSection(QAction * before, const QIcon & icon, const QString & text);
QAction * addSection(const QString & text); //追加具有文本 text的分隔条
QAction * addSection(const QIcon & icon, const QString & text);
//This convenience function inserts menu before action before and
//returns the menus menuAction(). 在按钮 before前插入子菜单 menu。返回子菜单对应的菜单项。
QAction * insertMenu(QAction * before, QMenu * menu);
//This convenience function adds menu as a submenu to this menu.
//It returns menu's menuAction(). This menu does not take ownership of menu.
QAction * addMenu( QMenu * menu );
//Appends a new QMenu with title to the menu. The menu takes ownership of the menu.
//Returns the new menu.
QMenu * addMenu( const QString & title);
QMenu * addMenu(const QIcon & icon, const QString & title);
//Appends a new QMenu with icon and title to the menu.
}; //完结 class QMenu : public QWidget
QT_END_NAMESPACE
#endif // QMENU_H
(9)
谢谢