2016-12-13 3 views
1

begann ich ein kleines Projekt mit dieser Quelle-Code:merkwürdige Wirkung auf QGraphicsView auf Reimplementierung Mausereignis

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

Kompilieren des Codes über Ihnen mit einem kleinen Fenster am Ende sollte nur die QGraphivsView, ein Polygon enthält, und vier Griffe an den Polygonscheitelpunkten. Bewegen Sie nun einen Griff mit Ihrer Maus. Verschiebe es erneut. Alles sollte sich so verhalten, wie Sie es von jedem grafischen Editor erwarten würden. Als Nächstes kommentieren Sie den Code-Block, der einige Mausereignisse neu implementiert, um im Grunde nur den Cursor zu ändern, wenn Sie den Mauszeiger darüber bewegen und die Ziehpunkte ziehen. Erneut kompilieren und erneut starten, um einen Handle zu verschieben. Den gleichen Griff nochmal bewegen und ... sehen was passiert! WTF? es springt zurück zu seiner ursprünglichen Position. Weiß jemand, wie man dieses Verhalten erklärt und wie man es umgeht?

Danke!

Antwort

1

Stellen Sie sicher, dass das Basisklassenereignis nach Ihrer Implementierung aufgerufen wird, um sicherzustellen, dass die normale Funktionalität erhalten bleibt.

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

Sie müssen die Basisklassenimplementierung für Ihre mouse und mouse Methoden aufrufen:

QGraphicsRectItem::mousePressEvent (event); 

und

QGraphicsRectItem::mouseReleaseEvent (event); 

die Dokumentation nach, die Basis Implementierungen Maus Grabbing Griff, Verschieben und Auswahl , also musst du sie in diesem Fall anrufen. Ich bin ein wenig überrascht, dass sich die Griffe überhaupt bewegen, und sie sind eindeutig, aber die Position des Gegenstands wird intern nicht richtig gehandhabt.