'QGraphicsItem partly disappeared under selection
Good afternoon, I have been working with graphics in Qt relatively recently, I ran into such a problem. For reasons that are unclear to me, PART of the QGraphicsItem is not drawn under the selection, and after releasing the selection appears only when calling update method, mousePressed does not work in these disappearing zones too (see screen 2), but if you select the same item in a bit other place, everything is OK, moreover, at some locations this error disappears (see screen 3) blue rectangles these are boundingRect, red outline shape, gray rectangles proxyWidget nested in bright green GraphicsItem. thank you in advanceinJust Build
Selection break Same Instance, Just Move widgets a bit, and no error
HPP
#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();
}
}
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
| Solution | Source |
|---|
