QMenuBar中item同时显示图标和文字
需求
如图所示,通过设置Icon后只显示图标,不设置Icon只会显示文件,无法让图标和文件同时显示
方法
通过继承QProxyStyle类,通过函数隐藏子类实现父类QProxyStyle的sizeFromContents、drawControl方法;再通过ui->menubar->setStyle(子类实例化的对象),可达到Icon和文字同时显示的效果。
代码
子类实现menuBarIconStyle.h
#ifndef MENUBARICONSTYLE_H
#define MENUBARICONSTYLE_H
#include <QMenuBar>
#include <QMenu>
#include <QAction>
#include <QIcon>
#include <QProxyStyle>
#include <QPainter>
#include <QStyleOptionMenuItem>
#include <QDebug>
#include <QPainterPath>
class menuBarIconStyle : public QProxyStyle
{
public:
QSize sizeFromContents(ContentsType type, const QStyleOption *option, const QSize &size, const QWidget *widget) const override
{
QSize newSize = QProxyStyle::sizeFromContents(type,option,size,widget);
//设置menbaritem的大小 可以根据实际情况进行更改
if(type == QStyle::CT_MenuBarItem)
{
newSize.setWidth(100);
newSize.setHeight(40);
}
return newSize;
}
void drawControl(ControlElement element, const QStyleOption *option,
QPainter *painter, const QWidget *widget) const override
{
if (element == QStyle::CE_MenuBarItem)
{
const QStyleOptionMenuItem *menuItem = qstyleoption_cast<const QStyleOptionMenuItem *>(option);
if (menuItem && menuItem->menuItemType == QStyleOptionMenuItem::Normal)
{
painter->setRenderHint(QPainter::Antialiasing);
QString text = menuItem->text;
QRect optionRect = option->rect;
int x = optionRect.x();
int y = optionRect.y();
int width = optionRect.width();
int height = optionRect.height();
QColor bgColor("#FFFFFF");
if(menuItem->state & QStyle::State_Selected)
{
bgColor = QColor("#4F85FD");
}
else if (menuItem->state & QStyle::State_MouseOver)
{
bgColor = QColor("#4F85FD");
}
painter->setPen(Qt::NoPen); // 无轮廓
painter->setBrush(bgColor);
//圆角
int radius = 5;
//上边框 10px
optionRect.adjust(0, 10, 0, 0);
QPainterPath roundedRectPath;
roundedRectPath.addRoundedRect(optionRect, radius, radius);
painter->drawPath(roundedRectPath);
QColor textColor("#333333");
if (!text.isEmpty())
{
int margin = 30;
int fontSize = 14;
// 计算文字区域
QRect textRect = optionRect;
textRect.setWidth(width);
textRect.setX(x + margin);
QFont font;
font.setPixelSize(fontSize);
painter->setFont(font);
painter->setPen(textColor);
painter->drawText(textRect, Qt::AlignLeft | Qt::AlignVCenter, text);
}
int iconSize = 20;
int iconMargin = 5;
//居中显示
QRect checboxRec(optionRect.left()+iconMargin,optionRect.top() +(optionRect.height()-iconSize)/2,iconSize,iconSize);
const QIcon &icon = menuItem->icon;
QPixmap pix = icon.pixmap(iconSize, iconSize);
painter->drawPixmap(checboxRec, pix);
}
}
}
signals:
};
#endif // MENUBARICONSTYLE_H
主窗口代码
mainwindow.h
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QMainWindow>
#include "menuBarIconStyle.h"
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
MainWindow(QWidget *parent = nullptr);
~MainWindow();
private:
Ui::MainWindow *ui;
menuBarIconStyle *m_menuBarIconStyle;
};
#endif // MAINWINDOW_H
mainwindow.cpp
#include "mainwindow.h"
#include "ui_mainwindow.h"
MainWindow::MainWindow(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::MainWindow)
{
ui->setupUi(this);
ui->menuFile->setIcon(QIcon(QPixmap(":/image/file.png")));
m_menuBarIconStyle = new menuBarIconStyle();
ui->menubar->setStyle(m_menuBarIconStyle);
}
MainWindow::~MainWindow()
{
delete ui;
}
完整工程地址
https://download.csdn.net/download/lyj548926543/90038489