QGraphicsItem частично исчез при выборе

Добрый день, работаю с графикой в ​​Qt относительно недавно, столкнулся с такой проблемой. По непонятным мне причинам ЧАСТЬ QGraphicsItem не рисуется под выделением, а после отпускания выделение появляется только при вызове метода обновления, mousePressed не работает и в этих исчезающих зонах (см. скрин 2), но если выделить тот же элемент в другом месте, все в порядке, более того, в некоторых местах эта ошибка исчезает (см. скрин 3) синие прямоугольники это boundingRect, красная фигура контура, серые прямоугольники proxyWidget вложенные в ярко-зеленый GraphicsItem. заранее спасибов Just Build

Разрыв выделения Тот же экземпляр, просто немного переместите виджеты и нет ошибки

ГЭС

      #include <QGraphicsLineItem>
#include <QMoveEvent>
class pin;
class customGraphicsview;
class connector;
class Dot;
#include"dot.h"
#include"pin.h"
#include"connector.h"
#include<QGraphicsItem>
#include <QPainter>
#include<QPointF>
#include<QDebug>
#include<QColor>


class Whire : public QGraphicsItem
{
public:

    Whire(pin *nitem1, pin *nitem2,customGraphicsview*gv);
    void Update(bool OneMore=false);
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
    pin *pin1,*pin2;
    void collisions();
    void DotDot(Whire* w);
    void collisionfix(Whire* w);
    void collisionfix(connector* cn);
    void mousePressEvent(QGraphicsSceneMouseEvent *e) override;
    void colChange(QColor co);
    QColor color();
    QPointF NeartoPindot(pin* p,bool bl);
    QPointF NeartoPin(pin* p);
    ~Whire();


private:
    QColor col;
    bool selected=false;
    QVector<Dot*>points;
    void drawLine(Dot* p1, Dot* p2, Dot* p3, int& r, QPainter* p,bool last=false);
    void drawLine(Dot* p1, Dot* p2,QPainter* p);
    QRectF boundingRect() const override;
    QPainterPath shape() const override;
    customGraphicsview* gview;
    bool p2c=false,p3c=false;
};

CPP

      #include "whire.h"
#include"customviewmap.h"
#include<qgraphicsitem.h>
Whire::Whire(pin *nitem1, pin *nitem2,customGraphicsview* gv): QGraphicsItem()
{
    pin1=nitem1;
    pin2=nitem2;
    gview=gv;
    if(dynamic_cast<customviewMap*>(gview->view)!=nullptr)
    {
        dynamic_cast<customviewMap*>(gview->view)->Add(this);
    }
    gview->scene()->addItem(this);
    col=Qt::darkGray;
    points=QVector<Dot*>();
    pin1->addWhire(this);
    pin2->addWhire(this);
    points.clear();
    Dot* p = new Dot(pin1->whirepos(pin2), 0,gview->scene());
    points.append(p);
    p = new Dot(pin2->whirepos(pin1), 1, gview->scene());
    points.append(p);
    p = new Dot(((float)(points[0]->pos().x() + points.last()->pos().x()) / 2), points[0]->pos().y(), 1, gview->scene());
    points.insert(1, p);
    p = new Dot(((float)(points[0]->pos().x() + points.last()->pos().x()) / 2), points.last()->pos().y(), 0, gview->scene());
    points.insert(2, p);
    collisions();
}

void Whire::Update(bool colfix)
{
    prepareGeometryChange();
    Dot* p = new Dot(pin1->whirepos(pin2), 0,scene());
    delete points[0];
    points[0] = p;
    p = new Dot(pin2->whirepos(pin1), 1, scene());
    delete points.last();
    points.last() = p;
    p = new Dot(((float)(points[0]->pos().x() + points.last()->pos().x()) / 2), points[0]->pos().y(), 1, scene());
    delete points[1];
    points[1] = p;
    p = new Dot(((float)(points[0]->pos().x() + points.last()->pos().x()) / 2), points.last()->pos().y(), 0, scene());
    delete points[points.count() - 2];
    points[points.count() - 2] = p;
    for (int i = 2; i < points.count()-2; i++)
    {
        delete points[i];
        points.remove(i);
    }
    this->update();
    if(colfix)
    {
        collisions();
    }
}

void Whire::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    //qDebug()<<points.count();
    /*
    int radius=0;
    painter->setPen(QPen(col,8));
    for(int i=0;i<points.count()-3;i++)
    {
        drawLine(points[i],points[i+1],points[i+2],radius,painter);
    }
    if(points.count()>2)
        drawLine(points[points.count()-3],points[points.count()-2],points[points.count()-1],radius,painter,true);
        */
    for (int i = 0; i < points.count()-1; i++)
        drawLine(points[i], points[i + 1],painter);
    painter->setPen(QPen(Qt::red,Qt::DashDotDotLine));
    painter->setBrush(QBrush(Qt::transparent));
    painter->drawPath(shape());
    painter->setPen(QPen(Qt::darkBlue, Qt::DashLine));
    painter->drawRect(boundingRect());
}

void Whire::collisions()
{
    QList<Whire*>colWhires=QList<Whire*>();
    QList<connector*>colConn=QList<connector*>();
    Whire* wr;
    connector* cn;
    RefreshWGraphicsRectItem* RGI;

    QList<QGraphicsItem *> items = collidingItems();
    foreach (QGraphicsItem *item, items)
    {
        RGI=dynamic_cast<RefreshWGraphicsRectItem*>(item);
        if(RGI!=nullptr)
        {
            break;
        }

        wr = dynamic_cast<Whire*>(item);
        if(wr != nullptr)
        {
            colWhires.append(wr);
            break;
        }

        cn = dynamic_cast<connector*>((dynamic_cast<QGraphicsProxyWidget*>(item))->widget());
        if( cn != nullptr)
        {
            if(cn!=pin1->connectr()&&cn!=pin2->connectr())
            {
                colConn.append(cn);
            }
        }
    }

    foreach(Whire* wr, colWhires)
    {
        collisionfix(wr);
    }
    foreach(connector* cn,colConn)
    {
        //collisionfix(cn);
    }

    if(abs(pin1->whirepos().x()-pin2->whirepos().x())<pin1->connectr()->size().width())
    {
        if(pin1->connectr()->pos().x()<=pin2->connectr()->pos().x())
        {
            points[0]= new Dot(QPointF(pin1->whirepos(QPointF(pin1->connectr()->pos().x()-pin1->connectr()->size().width(),pin1->connectr()->pos().y()))),points[0]->inH, scene());
        }
        else
        {
            points[0]= new Dot(QPointF(pin1->whirepos(QPointF(pin1->connectr()->pos().x()+2*pin1->connectr()->size().width(),pin1->connectr()->pos().y()))),points[0]->inH, scene());
        }
    }

}

void Whire::DotDot(Whire* w)
{
    enum doupin
    {
        pin1_pin1,
        pin1_pin2,
        pin2_pin1,
        pin2_pin2

    };
    QPointF p2, wp2, doublepin;
    doupin dpin;
    if (pin1 == w->pin1)
    {
        dpin = pin1_pin1;
        p2 = this->pin2->whirepos(pin1);
        wp2 = w->pin2->whirepos(w->pin1);
        doublepin = pin1->whirepos(pin2);
        points.first()->setPos(pin1->whirepos(pin2));
        points[1]->setY(points.first()->y());
        w->points.first()->setPos(points.first()->pos());
        w->points[1]->setY(w->points.first()->y());
    }
    if (pin1 == w->pin2)
    {
        dpin = pin1_pin2;
        p2 = this->pin2->whirepos(pin1);
        wp2 = w->pin1->whirepos(w->pin2);
        doublepin = pin1->whirepos(pin2);
        points.first()->setPos(pin1->whirepos(pin2));
        points[1]->setY(points.first()->y());
        w->points.last()->setPos(points.first()->pos());
        w->points[w->points.size()-2]->setY(w->points.last()->y());

    }

    if (pin2 == w->pin1)
    {
        dpin = pin2_pin1;
        p2 = this->pin1->whirepos(pin2);
        wp2 = w->pin2->whirepos(w->pin1);
        doublepin = pin2->whirepos(pin1);;
        points.last()->setPos(pin2->whirepos(pin1));
        points[points.size()-2]->setY(points.last()->y());
        w->points.first()->setPos(points.first()->pos());
        w->points[1]->setY(w->points.first()->y());
    }
    if (pin2 == w->pin2)
    {
        dpin = pin2_pin2;
        p2 = this->pin1->whirepos(pin2);
        wp2 = w->pin1->whirepos(w->pin2);
        doublepin = pin2->whirepos(pin1);
        points.last()->setPos(pin2->whirepos(pin1));
        points[points.size() - 2]->setY(points.last()->y());
        w->points.last()->setPos(points.first()->pos());
        w->points[w->points.size() - 2]->setY(w->points.last()->y());
    }
    w->scene()->update();

    return;
}

void Whire::collisionfix(Whire *w)
{
    for (int j = 0; j < w->points.count() - 1; j++)
    {
        for (int i = 0; i < points.count() - 1; i++)
        {
            if (true);
            {
                if (points[i]->inH)
                {
                    if (w->points[j]->inH)
                    {
                        if (abs(points[i]->pos().x() - w->points[j]->pos().x()) <= 40)
                        {
                            if (points[i - 1]->pos().x() <= points[i]->pos().x())
                            {
                                if (w->points[j - 1]->pos().x() <= w->points[j]->pos().x())
                                {
                                    if (abs(points[i]->pos().y() - points[i + 1]->pos().y()) < abs(w->points[j]->pos().y() - w->points[j + 1]->pos().y()))
                                    {
                                        points[i]->setPos(points[i]->pos().x() - 35, points[i]->pos().y());
                                        w->points[j]->setPos(w->points[j]->pos().x() + 25, w->points[j]->pos().y());
                                        points[i + 1]->setPos(points[i + 1]->pos().x() - 35, points[i + 1]->pos().y());
                                        w->points[j + 1]->setPos(w->points[j + 1]->pos().x() + 25, w->points[j + 1]->pos().y());
                                        w->Update();
                                    }
                                    else
                                    {
                                        points[i]->setPos(points[i]->pos().x() + 35, points[i]->pos().y());
                                        w->points[j]->setPos(w->points[j]->pos().x() - 25, w->points[j]->pos().y());
                                        points[i + 1]->setPos(points[i + 1]->pos().x() + 35, points[i + 1]->pos().y());
                                        w->points[j + 1]->setPos(w->points[j + 1]->pos().x() - 25, w->points[j + 1]->pos().y());
                                        //w->Update();
                                    }
                                }
                                else
                                {
                                    points[i]->setPos(points[i]->pos().x() - 35, points[i]->pos().y());
                                    w->points[j]->setPos(w->points[j]->pos().x() + 25, w->points[j]->pos().y());
                                    points[i + 1]->setPos(points[i + 1]->pos().x() - 35, points[i + 1]->pos().y());
                                    w->points[j + 1]->setPos(w->points[j + 1]->pos().x() + 25, w->points[j + 1]->pos().y());
                                    w->Update();
                                }
                            }
                            else
                            {
                                if (w->points[j - 1]->pos().x() >= w->points[j]->pos().x())
                                {
                                    if (abs(points[i]->pos().y() - points[i + 1]->pos().y()) < abs(w->points[j]->pos().y() - w->points[j + 1]->pos().y()))
                                    {
                                        points[i]->setPos(points[i]->pos().x() - 35, points[i]->pos().y());
                                        w->points[j]->setPos(w->points[j]->pos().x() + 25, w->points[j]->pos().y());
                                        points[i + 1]->setPos(points[i + 1]->pos().x() - 35, points[i + 1]->pos().y());
                                        w->points[j + 1]->setPos(w->points[j + 1]->pos().x() + 25, w->points[j + 1]->pos().y());
                                        w->Update();
                                    }
                                    else
                                    {
                                        points[i]->setPos(points[i]->pos().x() + 35, points[i]->pos().y());
                                        w->points[j]->setPos(w->points[j]->pos().x() - 25, w->points[j]->pos().y());
                                        points[i + 1]->setPos(points[i + 1]->pos().x() + 35, points[i + 1]->pos().y());
                                        w->points[j + 1]->setPos(w->points[j + 1]->pos().x() - 25, w->points[j + 1]->pos().y());
                                        //w->Update();
                                    }
                                }
                                else
                                {
                                    points[i]->setPos(points[i]->pos().x() - 35, points[i]->pos().y());
                                    w->points[j]->setPos(w->points[j]->pos().x() + 25, w->points[j]->pos().y());
                                    points[i + 1]->setPos(points[i + 1]->pos().x() - 35, points[i + 1]->pos().y());
                                    w->points[j + 1]->setPos(w->points[j + 1]->pos().x() + 25, w->points[j + 1]->pos().y());
                                    w->Update();
                                }
                            }
                        }
                    }
                    else
                    {
                        //Bridge;
                    }
                }
                else
                {
                    if (!w->points[j]->inH)
                    {

                        if (abs(points[i]->pos().y() - w->points[j]->pos().y()) <= 40)
                        {
                            if (points[i]->pos().y() > w->points[j]->pos().y())
                            {
                                points[i]->setPos(points[i]->pos().x(), points[i]->pos().y() + 35);
                                w->points[j]->setPos(w->points[j]->pos().x(), w->points[j]->pos().y() - 25);
                                points[i + 1]->setPos(points[i + 1]->pos().x(), points[i + 1]->pos().y() + 35);
                                w->points[j + 1]->setPos(w->points[j + 1]->pos().x(), w->points[j + 1]->pos().y() - 25);
                            }
                            else
                            {
                                points[i]->setPos(points[i]->pos().x(), points[i]->pos().y() - 25);
                                w->points[j]->setPos(w->points[j]->pos().x(), w->points[j]->pos().y() + 35);
                                points[i + 1]->setPos(points[i + 1]->pos().x(), points[i + 1]->pos().y() - 25);
                                w->points[j + 1]->setPos(w->points[j + 1]->pos().x(), w->points[j + 1]->pos().y() + 35);
                            }
                        }
                    }
                    else
                    {
                        //Bridge;
                    }
                }
            }
        }
    }

    w->pin1->addDot(true);
    w->pin2->addDot(true);
}

void Whire::collisionfix(connector *cn)
{

}

void Whire::colChange(QColor co)
{
    col=co;
    pin1->ColorChange(col);
    pin2->ColorChange(col);
}

QColor Whire::color()
{
    return col;
}


QPointF Whire::NeartoPindot(pin *p,bool bl)
{
    if(pin1==p)
    {
        return points[1]->pos();
    }
    else if(pin2==p)
    {
        return points[points.count() - 2]->pos();
    }
}

QPointF Whire::NeartoPin(pin *p)
{
    if(pin1==p)
    {
        return points[1]->pos();
    }
    else if(pin2==p)
    {
        return points[points.count()-2]->pos();
    }
}

Whire::~Whire()
{
    pin1->removeW(this);
    pin2->removeW(this);
    if(dynamic_cast<customviewMap*>(gview->view)!=nullptr)
    {
        dynamic_cast<customviewMap*>(gview->view)->Remove(this);
    }
}


void Whire::drawLine(Dot* pos1, Dot* pos2, Dot* pos3, int &Radius2, QPainter* painter,bool last)
{
    painter->setPen(QPen(col,8));
    int Nrad;
    if(!pos2->isVisible())
    {
        if(pos2->inH)
        {
            Nrad=qMin((double)Radius2,abs(pos2->pos().y()-pos3->pos().y())/10);
            if (Nrad==0)
                Nrad=abs(pos2->pos().y()-pos3->pos().y())/10;
            if(pos1->pos().x()<=pos2->pos().x())
            {
                if(pos2->pos().y()<=pos3->pos().y())
                {
                    painter->drawLine(pos1->pos().x()+Radius2,pos1->pos().y(),pos2->pos().x()-Nrad,pos2->pos().y());
                    painter->drawArc(pos2->pos().x()-2*Nrad,pos2->pos().y(),2*Nrad,2*Nrad,0*16,90*16);

                }
                else
                {
                    painter->drawLine(pos1->pos().x()+Radius2,pos1->pos().y(),pos2->pos().x()-Nrad,pos2->pos().y());
                    painter->drawArc(pos2->pos().x()-2*Nrad,pos2->pos().y()-2*Nrad,2*Nrad,2*Nrad,270*16,90*16);

                }
            }
            else
            {
                if(pos2->pos().y()<=pos3->pos().y())
                {
                    painter->drawLine(pos1->pos().x()-Radius2,pos1->pos().y(),pos2->pos().x()+Nrad,pos2->pos().y());
                    painter->drawArc(pos2->pos().x(),pos2->pos().y(),2*Nrad,2*Nrad,90*16,90*16);

                }
                else
                {
                    painter->drawLine(pos1->pos().x()-Radius2,pos1->pos().y(),pos2->pos().x()+Nrad,pos2->pos().y());
                    painter->drawArc(pos2->pos().x(),pos2->pos().y()-2*Nrad,2*Nrad,2*Nrad,180*16,90*16);

                }
            }
        }
        else
        {
            Nrad=qMin((double)Radius2,abs(pos2->pos().x()-pos3->pos().x())/10);
            if(pos1->pos().y()<=pos2->pos().y())
            {
                if(pos2->pos().x()<=pos3->pos().x())
                {
                    painter->drawLine(pos1->pos().x(),pos1->pos().y()+Radius2,pos2->pos().x(),pos2->pos().y()-Nrad);
                    painter->drawArc(pos2->pos().x(),pos2->pos().y()-2*Nrad,2*Nrad,2*Nrad,180*16,90*16);
                    if(last)
                        painter->drawLine(pos2->pos().x()+Nrad,pos2->pos().y(),pos3->pos().x(),pos3->pos().y());
                }
                else
                {
                    painter->drawLine(pos1->pos().x(),pos1->pos().y()+Radius2,pos2->pos().x(),pos2->pos().y()-Nrad);
                    painter->drawArc(pos2->pos().x()-2*Nrad,pos2->pos().y()-2*Nrad,2*Nrad,2*Nrad,270*16,90*16);
                    if(last)
                        painter->drawLine(pos2->pos().x()-Nrad,pos2->pos().y(),pos3->pos().x(),pos3->pos().y());
                }
            }
            else
            {
                if(pos2->pos().x()<=pos3->pos().x())
                {
                    painter->drawLine(pos1->pos().x(),pos1->pos().y()-Radius2,pos2->pos().x(),pos2->pos().y()+Nrad);
                    painter->drawArc(pos2->pos().x(),pos2->pos().y(),2*Nrad,2*Nrad,90*16,90*16);
                    if(last)
                        painter->drawLine(pos2->pos().x()+Nrad,pos2->pos().y(),pos3->pos().x(),pos3->pos().y());
                }
                else
                {
                    painter->drawLine(pos1->pos().x(),pos1->pos().y()-Radius2,pos2->pos().x(),pos2->pos().y()+Nrad);
                    painter->drawArc(pos2->pos().x()-2*Nrad,pos2->pos().y(),2*Nrad,2*Nrad,0*16,90*16);
                    if(last)
                        painter->drawLine(pos2->pos().x()-Nrad,pos2->pos().y(),pos3->pos().x(),pos3->pos().y());
                }
            }

        }
        Radius2=Nrad;
    }
    else
    {
        painter->drawLine(pos1->pos(),pos2->pos());
        painter->drawLine(pos1->pos(),pos2->pos());
        painter->drawEllipse(pos2->pos(),5,5);
    }
}

void Whire::drawLine(Dot* p1, Dot* p2, QPainter* p)
{
    p->setPen(QPen(col, 8));
    p->drawLine(p1->pos(), p2->pos());
}

QRectF Whire::boundingRect() const
{
    QRectF rect= shape().boundingRect();
    rect.setRect(rect.x() - 10, rect.y() - 10, rect.width() + 10, rect.height() + 10);
    return rect;
}

QPainterPath Whire::shape() const
{
    QPainterPath p=QPainterPath();
    int x,y,w,h;
    for(int i=0;i<points.count()-1;i++)
    {
        x=qMin(points[i]->pos().x(),points[i+1]->pos().x());
        x-=5;
        y=qMin(points[i]->pos().y(),points[i+1]->pos().y());
        y-=5;
        w=abs(points[i]->pos().x()-points[i+1]->pos().x());
        w+=10;
        h=abs(points[i]->pos().y()-points[i+1]->pos().y());
        h+=10;
        p.addRect(x,y,w,h);
    }
    return p;
}

void Whire::mousePressEvent(QGraphicsSceneMouseEvent *e)
{
    if(e->modifiers()&Qt::SHIFT)
    {
       delete this;
    }
    else
    {
        if(col!=Qt::red)
            col=Qt::red;
        else
            col=Qt::darkGray;
        Update();
    }
}

0 ответов

Другие вопросы по тегам