QMenu是Qt框架中的一个类,主要用于创建和管理弹出式菜单。这些菜单常用于应用程序的右键上下文菜单、工具栏按钮下拉菜单以及主菜单栏等场景。以下是对QMenu的详细解析和使用指南:
一、QMenu的基本使用
-
创建QMenu对象
创建一个QMenu对象时,通常需要指定其父窗口或控件。例如:
QMenu *menu = new QMenu("My Menu", parentWidget);
其中,
parentWidget
是菜单所属的父窗口或控件。 -
添加菜单项
使用
addAction
方法可以向菜单中添加动作(QAction对象)。这些动作可以代表各种命令或操作。例如:QAction *openAction = new QAction("Open", menu);
menu->addAction(openAction);
同样地,可以添加分隔符和子菜单来丰富菜单的结构。
-
关联信号与槽
为了响应用户的点击操作,需要将菜单项的动作与相应的槽函数关联起来。例如:
connect(openAction, &QAction::triggered, this, &YourClass::openFile);
其中,
openFile
是YourClass中定义的槽函数。 -
显示菜单
菜单可以在适当的位置(如鼠标右击时)显示。使用
popup
方法可以在指定位置弹出菜单。例如:QPoint pos = QCursor::pos(); // 获取当前鼠标位置
menu->popup(pos); // 弹出菜单
二、QMenu样式表
在Qt中,QMenu
的样式表设置允许你自定义菜单的外观,包括背景颜色、文本颜色、边框、分隔符等。由于QMenu
不是直接继承自QWidget
,它的样式表设置稍有不同,通常是通过全局样式表(例如通过QApplication
设置)来应用的。
以下是一些常用的QMenu
样式表属性及其示例:
背景颜色和文本颜色
QMenu { |
background-color: #333333; /* 菜单背景颜色 */ |
color: white; /* 菜单项文本颜色 */ |
} |
菜单项(QMenu::item)
QMenu::item { |
padding: 10px 30px; /* 菜单项的填充 */ |
background-color: transparent; /* 菜单项背景颜色(通常设置为透明,以便显示QMenu的背景色) */ |
} |
选中状态的菜单项(QMenu::item:selected)
QMenu::item:selected { |
background-color: #606060; /* 选中菜单项的背景颜色 */ |
} |
分隔符(QMenu::separator)
QMenu::separator { |
height: 1px; /* 分隔符的高度 */ |
background: #555555; /* 分隔符的颜色 */ |
margin: 5px 0px; /* 分隔符的边距 */ |
} |
禁用状态的菜单项(QMenu::item:disabled)
QMenu::item:disabled { |
color: #888888; /* 禁用菜单项的文本颜色 */ |
} |
字体设置
你可以通过font-family
、font-size
和font-weight
等属性来设置菜单项的字体。
QMenu { |
font-family: Arial, sans-serif; /* 字体家族 */ |
font-size: 12pt; /* 字体大小 */ |
font-weight: bold; /* 字体粗细 */ |
} |
注意:QMenu
本身的文本通常不会直接显示(除非是通过某种自定义方式),因此QMenu
的color
属性主要影响的是菜单项的文本颜色。同样地,QMenu
的font-
属性也主要影响菜单项的字体设置。
应用样式表
你可以通过QApplication
的setStyleSheet
方法来应用全局样式表,这样应用程序中的所有QMenu
都会采用这些样式设置。
QApplication app(argc, argv); |
app.setStyleSheet("/* 样式表内容 */"); |
或者,如果你只想为特定的QMenu
设置样式,你可以尝试将该QMenu
的父组件(例如一个QWidget
或QMainWindow
)作为样式表的作用域,但这通常不如全局样式表方便和可靠。
三、QMenu高级使用
3.1. 使用工具栏按钮(QToolBar)
你可以将QMenu添加到QToolBar中,这样当用户点击工具栏按钮时,就会显示关联的QMenu。这通常通过QToolBar的addAction
方法实现,其中传递一个包含QMenu的QAction。
QToolBar *toolbar = new QToolBar(this);
QMenu *menu = new QMenu("Options", this);
QAction *menuAction = menu->menuAction(); // 获取代表QMenu的QAction
toolbar->addAction(menuAction); // 将QAction添加到工具栏
然而,需要注意的是,上面的代码实际上是将代表QMenu的QAction添加到工具栏中,而不是直接将QMenu添加到工具栏。当用户点击这个QAction时,QMenu会以弹出菜单的形式显示。
3.2. 使用自定义控件
如果你想要将QMenu直接附加到自定义控件上(例如,一个自定义的按钮或面板),你可以通过在该控件上处理鼠标事件或其他触发事件来显示QMenu。
例如,你可以创建一个自定义按钮,并在其mousePressEvent
方法中显示QMenu:
class CustomButton : public QPushButton {
Q_OBJECT
public:
CustomButton(QWidget *parent = nullptr) : QPushButton(parent) {}
protected:
void mousePressEvent(QMouseEvent *event) override {
if (event->button() == Qt::RightButton) { // 检查是否是右键点击
QMenu *menu = new QMenu(this);
QAction *action1 = new QAction("Action 1", menu);
QAction *action2 = new QAction("Action 2", menu);
menu->addAction(action1);
menu->addAction(action2);
menu->popup(event->globalPos()); // 在鼠标位置显示菜单
} else {
QPushButton::mousePressEvent(event); // 处理左键点击等其他情况
}
}
};
在这个例子中,当用户右键点击自定义按钮时,会显示一个包含两个动作的QMenu。
3.3. 使用上下文菜单事件(ContextMenuEvent)
对于许多控件(如QWidget、QTreeView等),你可以通过重写其contextMenuEvent
方法来显示QMenu。当用户在这些控件上右击时,contextMenuEvent
方法会被调用,你可以在这个方法中创建并显示QMenu。
class MyWidget : public QWidget {
Q_OBJECT
protected:
void contextMenuEvent(QContextMenuEvent *event) override {
QMenu *menu = new QMenu(this);
QAction *action1 = new QAction("Action 1", menu);
QAction *action2 = new QAction("Action 2", menu);
menu->addAction(action1);
menu->addAction(action2);
menu->exec(event->globalPos()); // 在鼠标位置执行菜单
}
};
在这个例子中,当用户右击MyWidget
时,会显示一个包含两个动作的QMenu。
3.4 QPushbutton添加menu
QPushButton* pBtn = new QPushButton();
QMenu* pMenu = new QMenu(this);
pBtn->setMenu(pMenu);
QAction* pAction = new QAction(this);
pMenu->addAction(pAction);
pAction->setText(tr("save as ..."));
connect(pAction, SIGNAL(triggered()), this, SLOT(slot_menuClicked()));
3.5 QPushButton添加QMenu,及向上弹出
void test_a::slotShowMenu()
{
QMenu *m_menu = new QMenu(this);
QAction *m_ClearZeroX = new QAction(m_menu);
m_ClearZeroX->setText(QObject::tr("X"));
//--向上弹出
QPoint pos;
pos.setX(0);
pos.setY(-m_menu->sizeHint().height());
m_menu->exec(ui.pushButton_up->mapToGlobal(pos));
}
3.6、QMenu添加QAction设置图标位置和大小
自定义Style修改icon大小:
#include <QProxyStyle>
class IconSizeProxyStyle : public QProxyStyle {
Q_OBJECT
public:
IconSizeProxyStyle(QStyle *style = nullptr, int iconSize = 28) :
QProxyStyle(style), m_iconSize(iconSize){};
IconSizeProxyStyle(const QString &key) :
QProxyStyle(key){};
~IconSizeProxyStyle(){};
int pixelMetric(QStyle::PixelMetric metric, const QStyleOption *option = 0, const QWidget *widget = 0) const override
{
if (metric == QStyle::PM_SmallIconSize) { return m_iconSize; }
return QProxyStyle::pixelMetric(metric, option, widget);
};
private:
int m_iconSize = 28;
};
使用:
QMenu *menu = new QMenu(this);
// 使用new的方式要注意内存泄漏
static IconSizeProxyStyle iconSizeStyle(menu->style(), 26/*图标大小*/);
menu->setStyle(&iconSizeStyle);
设置的图标津贴左边,可以通过qss设置图标的边距:
QMenu::item{ padding-left:25px; }/* 文字的边距,不影响图标 */
QMenu::icon{ padding-left:50px; }/* 图标的边距,不影响文字 */
QMenu::icon{ subcontrol-position: center right; }/* 图标的位置 */
参考:
- QMenu添加QAction设置图标位置和大小_qaction 设置图标-优快云博客
- 点击QPushButton上方弹出QMenu菜单源码实现 - 代码先锋网
- QPushButton添加QMenu,及向上弹出_qmenu向上弹出-优快云博客
- 点击QPushButton上方弹出QMenu菜单源码实现_qpushbutton::menu-indicator-优快云博客
- QMenu样式美化-优快云博客
- https://www.bytezonex.com/archives/BnJE9NsT.html
- QPushButton 样式使用示例(以及按钮setmenu添加下拉菜单的方法)_qpushbutton setmenu样式-优快云博客
- 【QT入门】 Qt自定义控件与样式设计之QPushButton点击按钮弹出菜单_qpushbutton如何设置点击按钮出现选择框-优快云博客
- Qt QPushButton设置菜单_qpushbutton setmenu-优快云博客