本文将通过简单示例介绍QMenu样式如何自定义。
QMenu同样支持盒子模型。
QMenu通用属性如下:
QMenu子控件如下:
QMenu只支持子控件item的伪状态,如下:
简单定义QMenu在使用QWidgetAction、QAction以及有子菜单下的样式。
如何使用样式表,请参考QSS系列:设置样式表
* {
outline: none;
}
QDialog {
background: #D6DBE9;
}
QMenu {
border: 1px solid #CCCCCC; /* 边框宽度为1px,颜色为#CCCCCC */
border-radius: 3px; /* 边框圆角 */
background-color: #FAFAFC; /* 背景颜色 */
font-size: 10pt; /* 文本字体大小 */
font-family: "Microsoft YaHei"; /* 文本字体族 */
padding: 5px 0px 5px 0px; /* 菜单项距菜单顶部边界和底部边界分别有5px */
}
QMenu::item { /* 菜单子控件item,为菜单项在default的状态 */
border: 0px solid transparent;
background-color: transparent;
color: black; /* 文本颜色 */
min-height: 40px; /* 菜单项的最小高度 */
margin: 2px 5px 2px 10px; /* 菜单项距其上下菜单项分别有2px,距菜单左右边界分别有10px和5px */
/*padding: 0px 0px 0px 25px;*/ /* 也可使用padding定义菜单项与上下左右的距离 */
}
QMenu::item:selected { /* 为菜单项在selected的状态 */
background-color: #EDEDEF;
}
QMenu::item:disabled{ /* 为菜单项在disabled的状态 */
color: #CCCCCC;
background: none;
}
QMenu::separator { /* 菜单子控件separator,定义菜单项之间的分隔线 */
height: 1px;
background: #CCCCCC;
margin-left: 2px; /* 距离菜单左边界2px */
margin-right: 2px; /* 距离菜单右边界2px */
}
QMenu::right-arrow { /* 菜单子控件right-arrow,定义子菜单指示器 */
width: 24px;
height: 24px;
image: url(:/Resource/right_arrow);
}
QMenu::left-arrow { /* 菜单子控件left-arrow,定义子菜单指示器 */
width: 24px;
height: 24px;
image: url(:/Resource/left_arrow);
}
/*
QMenu::icon:checked {
border: none;
background-color: transparent;
position: absolute;
width: 24px;
height: 24px;
}*/
QMenu::item::indicator { /* 菜单项子控件indicator,定义菜单项在选中状态下的指示器 */
width: 24px;
height: 24px;
}
QMenu::item::indicator:unchecked { /* 定义菜单项未选中的状态 */
image: none;
}
QMenu::item::indicator:checked { /* 定义菜单项选中的状态 */
image: url(:/Resource/checkebox);
}
QPushButton#PlayerButton { /* 自定义菜单项中的按钮 */
border: none;
background-color: transparent;
}
QPushButton#PlayerButton:hover {
padding-top: 2px;
padding-left: 2px;
}
QPushButton#PlayerButton:pressed {
padding: 0px;
}
#include "MainWindow.h"
#include
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
//全局加载样式表
QFile styleFile(":/Resource/DefaultTheme");
if (styleFile.open(QIODevice::ReadOnly))
{
QString string = styleFile.readAll();
qApp->setStyleSheet(string);
}
MainWindow w;
w.show();
return a.exec();
}
#ifndef CUSTOMMENU_H
#define CUSTOMMENU_H
#include
class CustomMenu : public QMenu
{
Q_OBJECT
public:
explicit CustomMenu(QWidget *parent = nullptr);
~CustomMenu();
};
#endif
#include "CustomMenu.h"
CustomMenu::CustomMenu(QWidget *parent)
: QMenu(parent)
{
//自定义QMenu
//取消边框和阴影
this->setWindowFlags(Qt::Popup | Qt::FramelessWindowHint | Qt::NoDropShadowWindowHint);
this->setAttribute(Qt::WA_TranslucentBackground);
}
CustomMenu::~CustomMenu()
{
}
#ifndef MainWindow_H
#define MainWindow_H
#include
#include
#include
#include
#include
#include
#include
#include "CustomMenu.h"
class MainWindow : public QDialog
{
Q_OBJECT
public:
MainWindow(QWidget *parent = Q_NULLPTR);
private:
void Init();
private slots:
void SlotContextMenuRequested(const QPoint& pos);
private:
CustomMenu *m_pPlayerMenu;
QAction *m_pSongNameAction;
QWidgetAction *m_pPlayWidgetAction;
QWidget *m_pPlayWidget;
QPushButton *m_pPlayBackButton;
QPushButton *m_pPlayButton;
QPushButton *m_pPlayForwardButton;
QHBoxLayout *m_pHLayout;
QAction *m_pPlayProcedureAction;
CustomMenu *m_pProcedureMenu;
QAction *m_pListCycleAction;
QAction *m_pSingleCycleAction;
QAction *m_pRandomPlayAction;
QAction *m_pOrderPlayAction;
QActionGroup *m_pProcedureActionGroup;
QAction *m_pFavoriteAction;
QAction *m_pSettingsAction;
QAction *m_pExitAction;
};
#endif // !MainWindow_H
#include "MainWindow.h"
#include "CommonDefines.h"
#include "MenuWidget.h"
MainWindow::MainWindow(QWidget *parent)
: QDialog(parent)
{
Init();
}
void MainWindow::Init()
{
m_pPlayerMenu = new CustomMenu(this); //使用自定义菜单
m_pPlayerMenu->setMinimumWidth(220);
m_pSongNameAction = new QAction("凡人修仙传", this);
m_pSongNameAction->setIcon(QIcon(":/Resource/contacter")); //定义菜单项的图标
//
m_pPlayWidgetAction = new QWidgetAction(this); //使用QWidgetAction可以定义复杂的菜单项
m_pPlayWidget = new QWidget(this); //存放自定义菜单项所需的控件及设置布局
m_pPlayBackButton = new QPushButton(this);
m_pPlayBackButton->setObjectName("PlayerButton");
m_pPlayBackButton->setIcon(QIcon(":/Resource/previous"));
m_pPlayBackButton->setIconSize(QSize(32, 32));
m_pPlayButton = new QPushButton(this);
m_pPlayButton->setObjectName("PlayerButton");
m_pPlayButton->setIcon(QIcon(":/Resource/play"));
m_pPlayButton->setIconSize(QSize(32, 32));
m_pPlayForwardButton = new QPushButton(this);
m_pPlayForwardButton->setObjectName("PlayerButton");
m_pPlayForwardButton->setIcon(QIcon(":/Resource/next"));
m_pPlayForwardButton->setIconSize(QSize(32, 32));
m_pHLayout = new QHBoxLayout(m_pPlayWidget);
m_pHLayout->addWidget(m_pPlayBackButton);
m_pHLayout->addWidget(m_pPlayButton);
m_pHLayout->addWidget(m_pPlayForwardButton);
m_pPlayWidgetAction->setDefaultWidget(m_pPlayWidget); //为QWidgetAction设置默认QWidget
//
m_pPlayProcedureAction = new QAction("顺序播放", this); //此为子菜单项
m_pPlayProcedureAction->setIcon(QIcon(":/Resource/order"));
m_pProcedureMenu = new CustomMenu(this); //子菜单
m_pProcedureMenu->setMinimumWidth(150);
m_pListCycleAction = new QAction("列表循环", this);
m_pListCycleAction->setIcon(QIcon(":/Resource/listcycle"));
m_pListCycleAction->setCheckable(true); //菜单项可选中
m_pListCycleAction->setChecked(false); //菜单项处于未选中状态
m_pSingleCycleAction = new QAction("单曲循环", this);
m_pSingleCycleAction->setIcon(QIcon(":/Resource/singlecycle"));
m_pSingleCycleAction->setCheckable(true);
m_pSingleCycleAction->setChecked(false);
m_pRandomPlayAction = new QAction("随机播放", this);
m_pRandomPlayAction->setIcon(QIcon(":/Resource/randomplay"));
m_pRandomPlayAction->setCheckable(true);
m_pRandomPlayAction->setChecked(false);
m_pOrderPlayAction = new QAction("顺序播放", this);
m_pOrderPlayAction->setIcon(QIcon(":/Resource/order"));
m_pOrderPlayAction->setCheckable(true);
m_pOrderPlayAction->setChecked(true); //菜单项处于选中状态
m_pProcedureActionGroup = new QActionGroup(this); //QActionGroup,为组中的QAction设置exclusive状态
m_pProcedureActionGroup->setExclusive(true);
m_pProcedureActionGroup->addAction(m_pListCycleAction);
m_pProcedureActionGroup->addAction(m_pSingleCycleAction);
m_pProcedureActionGroup->addAction(m_pRandomPlayAction);
m_pProcedureActionGroup->addAction(m_pOrderPlayAction);
m_pProcedureMenu->addAction(m_pListCycleAction);
m_pProcedureMenu->addAction(m_pSingleCycleAction);
m_pProcedureMenu->addAction(m_pRandomPlayAction);
m_pProcedureMenu->addAction(m_pOrderPlayAction);
m_pPlayProcedureAction->setMenu(m_pProcedureMenu);
//
m_pFavoriteAction = new QAction("喜欢", this);
m_pFavoriteAction->setIcon(QIcon(":/Resource/favorite"));
m_pSettingsAction = new QAction("设置", this);
m_pSettingsAction->setIcon(QIcon(":/Resource/setting"));
m_pExitAction = new QAction("退出", this);
m_pExitAction->setIcon(QIcon(":/Resource/exit"));
//
m_pPlayerMenu->addAction(m_pSongNameAction);
m_pPlayerMenu->addSeparator(); //添加分隔线
m_pPlayerMenu->addAction(m_pPlayWidgetAction);
m_pPlayerMenu->addSeparator();
m_pPlayerMenu->addAction(m_pPlayProcedureAction);
m_pPlayerMenu->addSeparator();
m_pPlayerMenu->addAction(m_pFavoriteAction);
m_pPlayerMenu->addAction(m_pSettingsAction);
m_pPlayerMenu->addAction(m_pExitAction);
this->setContextMenuPolicy(Qt::CustomContextMenu); //可显示右键菜单
connect(this, SIGNAL(customContextMenuRequested(const QPoint&)), this, SLOT(SlotContextMenuRequested(const QPoint&)));
this->setMinimumSize(600, 500);
}
void MainWindow::SlotContextMenuRequested(const QPoint& pos)
{
m_pPlayerMenu->exec(mapToGlobal(pos)); //显示菜单
}
参考Qt助手,如有错误,请指正,谢谢!