关于QAbstractGraphicsShapeItem的一个工程实践

目前项目中正在实现各类基本图形的绘制,在绘制完矩形和椭圆后,在碰撞过程中会发生干扰。这个问题苦恼了一天仍未解决,现已解决。



相关的类——————————————————————————————————————————————

矩形类:DSRectItem,关键方法如下:

QRectF DSRectItem::boundingRect() const
{
    qreal extra = qMax( qCeil(_penWidth),FOCUS_END_SIZE) / 2.0 ;
    QRectF rect = this->rect();
    return rect.normalized().adjusted(-extra, -extra, extra, extra);
}

QPainterPath DSRectItem::shape() const
{
    QPainterPath allPath;

    QPainterPath path;
    path.addRoundedRect( rect(),_radius,_radius );

    //include the outline ( half of pen width)
    QPainterPathStroker stroker;
    stroker.setWidth( _penWidth );
    stroker.setJoinStyle(Qt::MiterJoin);
    allPath = stroker.createStroke(path);

    for(const auto& item:_dragRects)
        allPath.addRect( item );

    if( _fillStyle==FS_SOLID ){
        allPath.setFillRule(Qt::WindingFill);
        allPath.addRoundedRect( rect(),_radius,_radius );
    }

    return allPath;
}


void DSRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
    painter->setRenderHint(QPainter::Antialiasing,true);

    QPen pen(_penColor,_penWidth,_penStyle,Qt::SquareCap,Qt::MiterJoin);
    painter->setPen( pen );
    if( _fillStyle==FS_SOLID ){
        painter->setBrush(_fillColor);

    }

    painter->drawRoundedRect( rect(),_radius,_radius);

    if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus)){
        QColor endColor(Qt::green);
        if( _isLocked ) endColor = Qt::gray;

        QPen pen(endColor,0.5,Qt::DashLine,Qt::SquareCap,Qt::MiterJoin);
        painter->setPen( pen );
        painter->drawLines( _foucsLines,sizeof(_foucsLines)/sizeof(_foucsLines[0]) );

        for(const auto &item:_dragRects)
            painter->fillRect(item,endColor);
    }

}

椭圆类:DSEllipseItem,实现如同DSRectItem


问题描述——————————————————————————————————————————————

先创建一个DSRectItem,该Item设置了填充色,也就是在其paint()中setbrush了。然后创建一个DSEllipseItem,该Item没有填充色。好了,问题来了,DSRectItemDSEllipseItem两个Item在发生碰撞的时候,DSEllipseItem也被填充颜色了!反之,如果DSRectItem也会被感染填充颜色。



问题解决——————————————————————————————————————————————

1,首先阅读文档,没有找到线索。

2,没办法了,开始注释代码,将一些方法采用默认实现,好了,锁定问题在paint()中

3,但还是找不到具体原因,最后在qt自带examples中的chip项目中找到了chip类的paint()方法找到了答案:在draw*()后,要恢复原有的brush

4,解决后的Paint()如下:

void DSRectItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *)
{
    painter->save();

    painter->setRenderHint(QPainter::Antialiasing,true);

    QPen pen(_penColor,_penWidth,_penStyle,Qt::SquareCap,Qt::MiterJoin);
    painter->setPen( pen );
    if( _fillStyle==FS_SOLID ){
        painter->setBrush(_fillColor);

    }

    painter->drawRoundedRect( rect(),_radius,_radius);

    if (option->state & (QStyle::State_Selected | QStyle::State_HasFocus)){
        QColor endColor(Qt::green);
        if( _isLocked ) endColor = Qt::gray;

        QPen pen(endColor,0.5,Qt::DashLine,Qt::SquareCap,Qt::MiterJoin);
        painter->setPen( pen );
        painter->drawLines( _foucsLines,sizeof(_foucsLines)/sizeof(_foucsLines[0]) );

        for(const auto &item:_dragRects)
            painter->fillRect(item,endColor);
    }
    painter->restore();
}





  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值