J'ai commencé un petit projet en utilisant ce code source:effet étrange sur QGraphicsView sur Réimplementation Mouse Event
#include <QApplication>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QGraphicsRectItem>
#include <QGraphicsLineItem>
class CustomRectItem : public QGraphicsRectItem
{
public:
CustomRectItem (const QRectF& rect) : QGraphicsRectItem(rect) {
setFlag(QGraphicsItem::ItemIsMovable);
setFlag(QGraphicsItem::ItemSendsScenePositionChanges);
setAcceptHoverEvents(true);
}
void addLine(QGraphicsLineItem *line1, QGraphicsLineItem *line2) {
if (this->data(0).toString() == "_p1") {
this->leftLine = line1;
this->topLine = line2;
}
if (this->data(0).toString() == "_p2") {
this->topLine = line1;
this->rightLine = line2;
}
if (this->data(0).toString() == "_p3") {
this->rightLine = line1;
this->bottomLine = line2;
}
if (this->data(0).toString() == "_p4") {
this->bottomLine = line1;
this->leftLine = line2;
}
}
QPointF center(void) {
return QPointF((rect().x() + rect().width()/2),
(rect().y() + rect().height()/2));
}
QVariant itemChange(GraphicsItemChange change, const QVariant &value)
{
if (change == ItemPositionChange && scene()) {
// value is the new position.
QPointF newPos = value.toPointF();
moveLineToCenter(newPos, this->data(0).toString());
}
return QGraphicsItem::itemChange(change, value);
}
void moveLineToCenter(QPointF newPos, QString pointString) {
// Converts the polygon upper left position
// to the upper left "handle"-rect center position
qreal xOffset = rect().x() + rect().width()/2;
qreal yOffset = rect().y() + rect().height()/2;
QPointF newCenterPos = QPointF(newPos.x() + xOffset, newPos.y() + yOffset);
QPointF p1;
QPointF p2;
// upper-left point
if (pointString == "_p1") {
p1 = leftLine->line().p1();
p2 = newCenterPos;
leftLine->setLine(QLineF(p1, p2));
p1 = newCenterPos;
p2 = topLine->line().p2();
topLine->setLine(QLineF(p1, p2));
// upper-right point
} else if (pointString == "_p2") {
p1 = topLine->line().p1();
p2 = newCenterPos;
topLine->setLine(QLineF(p1, p2));
p1 = newCenterPos;
p2 = rightLine->line().p2();
rightLine->setLine(QLineF(p1, p2));
// lower-right point
} else if (pointString == "_p3") {
p1 = rightLine->line().p1();
p2 = newCenterPos;
rightLine->setLine(QLineF(p1, p2));
p1 = newCenterPos;
p2 = bottomLine->line().p2();
bottomLine->setLine(QLineF(p1, p2));
// lower-left point
} else if (pointString == "_p4") {
p1 = bottomLine->line().p1();
p2 = newCenterPos;
bottomLine->setLine(QLineF(p1, p2));
p1 = newCenterPos;
p2 = leftLine->line().p2();
leftLine->setLine(QLineF(p1, p2));
} else {
return;
}
}
/////////////////////////////////////////////////////
/* -- comment-in this block to observe problem -- //
/////////////////////////////////////////////////////
protected:
virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) {
Q_UNUSED(event);
this->setCursor(Qt::SizeAllCursor);
}
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) {
Q_UNUSED(event);
this->unsetCursor();
}
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) {
Q_UNUSED(event);
this->setCursor(Qt::BlankCursor);
}
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) {
Q_UNUSED(event);
this->unsetCursor();
this->data(0).toString();
if (this->isUnderMouse()) {
this->setCursor(Qt::SizeAllCursor);
}
}
/////////////////////////////////////////////////////
// -- end of problem-causing block -- //
///////////////////////////////////////////////////// */
private:
QGraphicsLineItem *topLine;
QGraphicsLineItem *rightLine;
QGraphicsLineItem *bottomLine;
QGraphicsLineItem *leftLine;
};
int main(int argc, char *argv[]) {
QApplication a(argc, argv);
QGraphicsScene scene;
CustomRectItem *custRect1 = new CustomRectItem(QRectF(30, 30, 10, 10));
scene.addItem(custRect1);
custRect1->setData(0, "_p1");
CustomRectItem *custRect2 = new CustomRectItem(QRectF(70, 30, 10, 10));
scene.addItem(custRect2);
custRect2->setData(0, "_p2");
CustomRectItem *custRect3 = new CustomRectItem(QRectF(70, 70, 10, 10));
scene.addItem(custRect3);
custRect3->setData(0, "_p3");
CustomRectItem *custRect4 = new CustomRectItem(QRectF(30, 70, 10, 10));
scene.addItem(custRect4);
custRect4->setData(0, "_p4");
QGraphicsLineItem *topLine = scene.addLine(QLineF(custRect1->center(), custRect2->center()));
QGraphicsLineItem *rightLine = scene.addLine(QLineF(custRect2->center(), custRect3->center()));
QGraphicsLineItem *bottomLine = scene.addLine(QLineF(custRect3->center(), custRect4->center()));
QGraphicsLineItem *leftLine = scene.addLine(QLineF(custRect4->center(), custRect1->center()));
custRect1->addLine(leftLine, topLine);
custRect2->addLine(topLine, rightLine);
custRect3->addLine(rightLine, bottomLine);
custRect4->addLine(bottomLine, leftLine);
QGraphicsView view(&scene);
view.show();
return a.exec();
}
la compilation du code ci-dessus, vous devriez finir avec une petite fenêtre contenant juste le QGraphivsView, un Polygon et quatre poignées attachées aux sommets des polygones. Maintenant, déplacez une poignée en utilisant votre souris. Déplacez-le à nouveau. Tout devrait se comporter comme vous l'attendez de n'importe quel éditeur graphique. Ensuite, commentez-dans le bloc de code qui réimplémente certains événements de la souris pour changer simplement le curseur en survolant et en faisant glisser les poignées. Recompilez et recommencez pour déplacer une poignée. Déplacer la même poignée encore et ... voir ce qui se passe! WTF? il revient à sa position initiale. Est-ce que quelqu'un sait comment expliquer ce comportement et comment le contourner?
Merci!