QMenu 样式优化 添加阴影

继承QMenu重写它的paintEvent

代码示例

CustomMenu::CustomMenu(QWidget *parent)
    : QMenu(parent)
{
    this->setWindowFlag(Qt::FramelessWindowHint);//无边框
    this->setWindowFlag(Qt::NoDropShadowWindowHint);//取消windows自带阴影
    this->setAttribute(Qt::WA_TranslucentBackground);//透明背景

    m_ShadowWidth = 10;//m_ShadowWidth与菜单的margin保持一致

    //主要是给menu添加一定的margin用来显示阴影,其余的样式就根据自己的需要来写吧
    m_StyleSheet = "QMenu {margin:10px;/*……*/}";

    this->setStyleSheet(m_StyleSheet);
}

void CustomMenu::paintEvent(QPaintEvent *e) {
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing, true);
    //绘制阴影
    painter.drawPixmap(this->rect(), ninePatchScalePixmap(":/Resources/shadow_10px.png", m_ShadowWidth, m_ShadowWidth, this->width(), this->height()+ m_ShadowWidth));//m_ShadowWidth与菜单的margin保持一致
    //绘制主体
    QMenu::paintEvent(e);
}

QPixmap CDMLCustomMenu::ninePatchScalePixmap(QString picName, int iHorzSplit, int iVertSplit, int DstWidth, int DstHeight)
{
    QPixmap* pix = new QPixmap(picName);

    int pixWidth = pix->width();
    int pixHeight = pix->height();

    QPixmap pix_1 = pix->copy(0, 0, iHorzSplit, iVertSplit);
    QPixmap pix_2 = pix->copy(iHorzSplit, 0, pixWidth - iHorzSplit * 2, iVertSplit);
    QPixmap pix_3 = pix->copy(pixWidth - iHorzSplit, 0, iHorzSplit, iVertSplit);

    QPixmap pix_4 = pix->copy(0, iVertSplit, iHorzSplit, pixHeight - iVertSplit * 2);
    QPixmap pix_5 = pix->copy(iHorzSplit, iVertSplit, pixWidth - iHorzSplit * 2, pixHeight - iVertSplit * 2);
    QPixmap pix_6 = pix->copy(pixWidth - iHorzSplit, iVertSplit, iHorzSplit, pixHeight - iVertSplit * 2);

    QPixmap pix_7 = pix->copy(0, pixHeight - iVertSplit, iHorzSplit, iVertSplit);
    QPixmap pix_8 = pix->copy(iHorzSplit, pixHeight - iVertSplit, pixWidth - iHorzSplit * 2, pixWidth - iHorzSplit * 2);
    QPixmap pix_9 = pix->copy(pixWidth - iHorzSplit, pixHeight - iVertSplit, iHorzSplit, iVertSplit);

    pix_2 = pix_2.scaled(DstWidth - iHorzSplit * 2, iVertSplit, Qt::IgnoreAspectRatio);//保持高度拉宽;
    pix_4 = pix_4.scaled(iHorzSplit, DstHeight - iVertSplit * 2, Qt::IgnoreAspectRatio);//保持宽度拉高;
    pix_5 = pix_5.scaled(DstWidth - iHorzSplit * 2, DstHeight - iVertSplit * 2, Qt::IgnoreAspectRatio);//宽高都缩放;
    pix_6 = pix_6.scaled(iHorzSplit, DstHeight - iVertSplit * 2, Qt::IgnoreAspectRatio);//保持宽度拉高;
    pix_8 = pix_8.scaled(DstWidth - iHorzSplit * 2, iVertSplit);//保持高度拉宽;

    QPixmap resultImg(DstWidth, DstHeight);
    // 需设置背景透明;
    resultImg.fill(Qt::transparent);
    QPainter* painter = new QPainter(&resultImg);
    if (!resultImg.isNull()) {
        painter->drawPixmap(0, 0, pix_1);
        painter->drawPixmap(iHorzSplit, 0, pix_2);
        painter->drawPixmap(DstWidth - iHorzSplit, 0, pix_3);

        painter->drawPixmap(0, iVertSplit, pix_4);
        painter->drawPixmap(iHorzSplit, iVertSplit, pix_5);
        painter->drawPixmap(DstWidth - iHorzSplit, iVertSplit, pix_6);

        painter->drawPixmap(0, DstHeight - iVertSplit, pix_7);
        painter->drawPixmap(iHorzSplit, DstHeight - iVertSplit, pix_8);
        painter->drawPixmap(DstWidth - iHorzSplit, DstHeight - iVertSplit, pix_9);
        painter->end();
    }
    return resultImg;
}

其中ninePatchScalePixmap函数来自Qt之使用QPainter自绘实现窗口阴影边框的博客,其中还有其他的阴影实现方式,大家也可以参考一下。

使用的阴影图片如下,它的阴影宽度为10px,对于其他宽度的阴影就不太适用了,需要再制作一张

实现效果

需要注意的是,因为给菜单添加了一定的margin用来显示阴影,所以菜单显示时会向右下角偏移,要记得设置回来。

更多菜单样式的优化

QMenu 样式优化 圆角实现

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值