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

Qt中QGraphicsPathItem绘制的圆弧重绘后颜色消失如何解决?

问题描述

我有一个由Line、Arc和Circle组成的QGraphicsItem,用直线、圆弧、圆形绘制了数字门XNOR并设置为蓝色,初始加载显示效果如下:
初始加载效果图
点击其他区域后,圆弧的蓝色会消失,显示效果如下:
颜色消失后效果图

着色相关实现代码

myPoly.h

class myPoly: public QGraphicsPathItem 
{
    public:
    explicit myPoly(BGType *boostGraph);
    explicit myPoly();
    myPoly(QPainterPath p) : QGraphicsPathItem(p) {}
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);
    void DrawPolyline(QPolygonF);
};

myPoly.cpp

void myPoly::DrawPolyline(QPolygonF polygon)
{
    this->_polygon = polygon;
    QPainterPath pPath;
    pPath.addPolygon(polygon);
    this->setPen(QPen(QColor("gray"), 1));
    this->setPath(pPath);
}         
   
void myPoly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                        QWidget *widget)
{
    auto copied_option = *option;
    copied_option.state &= ~QStyle::State_Selected;
    std::cout<<"Paint called "<<std::endl;
    QGraphicsPathItem::paint(painter, &copied_option, widget);
}   

myArc.h

class myArc: public QGraphicsPathItem
{
    public:
        myArc(QPainterPath p) : QGraphicsPathItem(p) {}
        explicit myArc();
        void DrawArc();
};

myArc.cpp

myArc::myArc()
{}
void myArc::DrawArc()
{
    QPen mPen;
    mPen.setWidth(1);
    mPen.setBrush(Qt::blue);
    this->setPen(mPen);
}

mySymbol.cpp

void mySymbol :: DrawSymbol() 
{
    //绘制圆弧
    for (unsigned int i = 0; i < iter->second._allArcs.size(); i++) 
    {       
        // 获取圆弧所需的6个坐标值
        QPointF from(first, second);
        QPointF to(third, fourth);
        QPointF center(fifth, sixth);
        
        QLineF lineFrom{center, from};
        QLineF lineTo{center, to};
        qreal radius = lineFrom.length();
        QRectF bounding{center - QPointF{radius, radius},
                        center + QPointF{radius, radius}};
        
        QRectF bounding1(bounding.x() + x, bounding.y() + y, bounding.width(),bounding.height());
        
        // 使用QLineF计算相对于水平轴的角度
        qreal startAngle = lineFrom.angle();
        qreal sweep = lineFrom.angleTo(lineTo);
        
        QPainterPath path;
        path.moveTo(from.x(), from.y());
        
        path.arcTo(bounding1, startAngle, sweep);
        myArc* arc = new myArc(path);
        
        arc->DrawArc();
        scene->addItem(static_cast<QGraphicsPathItem*>(arc));
    }   
                

    class myLine: public QGraphicsLineItem
    {
    public:
        myLine();
        myLine(int x1,int y1,int x2 ,int y2,QGraphicsItem *parent = nullptr)
            : QGraphicsLineItem(x1,y1,x2,y2,parent)
        {}
        void DrawLine();
    };         

    // 绘制直线 
    for (unsigned int i = 0; i < iter->second._allLines.size(); i++) 
    {
        // 获取直线所需的4个坐标值
        myLine* line = new myLine(first,second,third,fourth);
        line->DrawLine();
        scene->addItem(static_cast<QGraphicsLineItem*>(line));
    }
}
  
void myLine::DrawLine()
{
    this->setPen(QPen(QColor("blue"), 1));
}
问题原因

核心错误是圆弧的画笔设置方式不对:

  • QPen的setBrush()接口仅用于宽度大于1像素的笔迹内部填充,1像素宽度的线条描边完全依赖QPen的color属性。
  • 你在myArc::DrawArc()里只调用了mPen.setBrush(Qt::blue),从未给画笔设置颜色属性,画笔默认颜色是黑色。初始加载时显示蓝色是Qt图形视图首次渲染的偶然现象,点击其他区域触发场景重绘后,绘制状态重置,圆弧会用默认的低对比度灰色绘制,看起来就像颜色消失了。
  • 对比myLine的实现,直线是直接在QPen构造函数中传入蓝色作为笔颜色,所以始终能正常显示。
修复方法

修改myArc::DrawArc()的画笔设置逻辑,直接给画笔指定蓝色即可,不需要调用setBrush:

void myArc::DrawArc()
{
    QPen mPen(Qt::blue);
    mPen.setWidth(1);
    this->setPen(mPen);
}

如果后续需要绘制宽度大于1的带填充效果的粗笔迹,再按需设置QPen的brush属性即可。另外建议给myArc类也加上和myPoly一致的paint重写逻辑,屏蔽默认的选中虚线样式,避免选中时出现显示异常。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.28 16:51:25