2016-12-13 1 views
1

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!

Répondre

1

Veillez à appeler l'événement de classe de base après votre implémentation pour vous assurer que la fonctionnalité normale reste.

virtual void hoverEnterEvent(QGraphicsSceneHoverEvent *event) { 
    this->setCursor(Qt::SizeAllCursor); 
    // 
    QGraphicsRectItem::hoverEnterEvent(event); 
} 
virtual void hoverLeaveEvent(QGraphicsSceneHoverEvent *event) { 
    this->unsetCursor(); 
    // 
    QGraphicsRectItem::hoverLeaveEvent(event); 

} 
virtual void mousePressEvent(QGraphicsSceneMouseEvent *event) { 
    this->setCursor(Qt::BlankCursor); 
    // 
    QGraphicsRectItem::mousePressEvent(event); 
} 
virtual void mouseReleaseEvent(QGraphicsSceneMouseEvent *event) { 
    this->unsetCursor(); 
    this->data(0).toString(); 
    if (this->isUnderMouse()) { 
      this->setCursor(Qt::SizeAllCursor); 
    } 
    // 
    QGraphicsRectItem::mouseReleaseEvent(event); 
} 
0

Vous devez appeler la mise en œuvre de la classe de base pour vos méthodes mousePressEvent et mouseReleaseEvent:

QGraphicsRectItem::mousePressEvent (event); 

et

QGraphicsRectItem::mouseReleaseEvent (event); 

Selon les documents, les implémentations de base poignée accaparement de la souris, le déplacement et la sélection , vous devez donc les appeler dans ce cas. Je suis un peu surpris que les poignées bougent du tout, et elles le sont clairement, mais la position de l'objet n'est pas traitée correctement en interne.