You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为QPainter绘制的图形添加QGraphicsDropShadowEffect阴影效果

报错原因

QGraphicsDropShadowEffect::draw()是Qt框架定义的受保护成员函数,仅允许内部渲染逻辑调用,开发者手动调用会触发访问权限错误。QGraphicsDropShadowEffect的设计用途是挂载到QWidget或QGraphicsItem实例上,由Qt自动在绘制流程中为整个目标对象应用阴影效果,不需要手动触发绘制。

正确实现方案

根据你的使用场景选择对应方案即可:

场景1:箭头是自定义QGraphicsItem子类

直接将阴影效果挂载到当前Item上即可,无需修改原有绘制逻辑:

  1. 删掉你原代码中创建QGraphicsDropShadowEffect、调用draw的相关代码
  2. 在Item的初始化逻辑(比如构造函数)中添加以下代码:
QGraphicsDropShadowEffect *m_DSEffect = new QGraphicsDropShadowEffect(this);
m_DSEffect->setBlurRadius(5);
m_DSEffect->setOffset(0);
m_DSEffect->setColor(QColor(Qt::black));
setGraphicsEffect(m_DSEffect);

Qt会自动将阴影效果应用到你在paint方法中绘制的所有箭头内容。

场景2:箭头在QWidget的paintEvent中手动绘制,不使用QGraphics框架

可以手动实现阴影绘制逻辑,Qt 5.15及以上版本可以直接用内置的阴影绘制接口,更低版本可以手动分层绘制:

void YourWidget::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.setRenderHint(QPainter::Antialiasing);
    QLineF coreLine = getShorterLine(points().first, points().second, thickness());
    QPainterPath arrowHead = getArrowHead(points().first, points().second, thickness());

    // 组装完整箭头路径用于阴影绘制
    QPainterPath fullArrow;
    fullArrow.moveTo(coreLine.p1());
    fullArrow.lineTo(coreLine.p2());
    fullArrow.addPath(arrowHead);

    // 绘制阴影(Qt 5.15及以上可用drawShadowedPath直接实现模糊阴影)
    painter.drawShadowedPath(fullArrow, QPointF(0, 0), 5, QColor(Qt::black));

    // 绘制原始箭头
    painter.setPen(QPen(color(), thickness()));
    painter.drawLine(coreLine);
    painter.fillPath(arrowHead, QBrush(color()));
}

如果是Qt 5.15以下版本,可以先将箭头绘制到临时透明Pixmap,再对Pixmap应用QGraphicsBlurEffect得到模糊阴影,最后分层绘制阴影和原箭头即可。

内容的提问来源于stack exchange,提问作者icicleking

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.25 23:45:08