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();
}
}