-1

i have been working on a QT application using the QGraphicsPolygonItem. First i created a class called DiagramScene who inherites the QGraphicsScene. First i create the item and put red corners in every point of the Polygon:

        item = new DiagramItem(myItemType, myItemMenu);
        item->setBrush(myItemColor);
        addItem(item);
        item->setPen(QPen(myLineColor, 2));
        item->setPolygon(mouseEvent->scenePos());
        item->setSelected(true);
        emit itemInserted(item);
        this->putPointsOnItem(item);

The the putPointsOnItem function:

void DiagramScene::putPointsOnItem(DiagramItem *item) {
    qDebug() << "putPointsOnItem";
    removeControlPoints();
    QPolygonF p = item->polygon();
    poly_points.clear();
    poly_points = p;
    qDebug() << p;
    for (int i = 0; i < p.size(); i++) {
        QPointF point = item->mapToScene(p[i]);
        QGraphicsEllipseItem *ellipse = addEllipse(QRectF(point.x() -5, point.y() -5, 8, 8), QPen(Qt::red, 3), QBrush(QColor("red")));
        ellipse->setFlag(QGraphicsItem::ItemIsMovable);
        ellipse->setZValue(100000000);
        corner_points.append(ellipse);
        real_corners.append(item);
    }
}

Then i check if the corner is selected:

void DiagramScene::mousePressEvent(QGraphicsSceneMouseEvent *mouseEvent) {

    if (mouseEvent->button() != Qt::LeftButton) {
        return;
    }

    this->finded = false;
    for (int i = 0; i < this->corner_points.length(); i++) {
        QGraphicsEllipseItem *item = this->corner_points[i];
        qDebug() << item;
        if (item->contains(mouseEvent->scenePos())) {
            item->setSelected(true);
            const QList<QGraphicsItem *> items = selectedItems();
            if (items.length()>0) {
                DiagramItem *startItem = qgraphicsitem_cast<DiagramItem *>(items.first());
                startItem->setFlag(QGraphicsItem::ItemIsMovable, false);
                selectedItem = startItem;
            }
            this->selected_corner = item;
            this->selected_corner_point = this->poly_points[i];
            selected_corner_number = i;
            finded = true;
            break;
        }
    }
    if (this->finded == true) {
        QGraphicsScene::mousePressEvent(mouseEvent);
        qDebug() << "POLY POINTS FINDED:";
        qDebug() << poly_points;
        return;
    }

And when the user move the mouse i check the selected corner and put the mouse position into one of the points:

void DiagramScene::mouseMoveEvent(QGraphicsSceneMouseEvent *mouseEvent) {

    
    QGraphicsScene::mouseMoveEvent(mouseEvent);

    QString coord = QString("%1, %2").arg(mouseEvent->scenePos().x()).arg(mouseEvent->scenePos().y());
    parentMain->setCoordinates(coord);

    if ((mouseEvent->buttons() & Qt::LeftButton)) {

        const QList<QGraphicsItem *> items = selectedItems();
        
        if (finded == true) {
        
            finded = false;

            for (int i = 0; i < corner_points.size(); ++i) {
                if (corner_points.at(i) == selected_corner) {
                    poly_points[selected_corner_number] = mouseEvent->scenePos();
                    finded = true;
                    break;
                }
            }
            if (finded) {
                qDebug() << poly_points;
                selectedItem->setPolygonItem(poly_points);
                return;
            }

Until that everithing works fine, but when the user move the item, the position dont work as i expected. For now i'm going crazy for many days and need help with this. Thanks a lot!

I think the problem is here:

poly_points[selected_corner_number] = mouseEvent->scenePos();

problem image described

  • What exactly is the problem? You show an animated GIF that depicts polygon vertices being moved around just fine. [Edit your question](https://stackoverflow.com/posts/73616617/edit) and update it to describe in detail exactly what you expect and what you actually observe. – paddy Sep 06 '22 at 04:16
  • Hi @paddy i already change the image problem. You can see when i move the item the item mantains their initial coordinates and differs of the mouse position. Thanks for your help! – Andrés Flórez Sep 06 '22 at 14:49
  • The issue is likely because you're using `scenePos` everywhere instead of `pos`. Read the Qt docs to understand how co-ordinate systems are handled in the Qt Graphics Framework. You might be misusing co-ordinate spaces in multiple places in your program. It's hard to tell from just the snippets you provided. Sometimes a misuse in one place is "fixed" by a misuse in another place. Work backwards from your mouse event handlers to iteratively fix and verify correct coordinates are used, all the way back to any auxiliary items, paint methods etc. – paddy Sep 06 '22 at 19:59
  • The important thing to note is that you should be correctly translating a point in the scene to a point in the local space of each item, when modifying an item. So, at the scene level then sure, use `scenePos`, but you must map that onto your polygon item correctly. Same goes when generating vertex points from that item -- remember when you pull the points out of the item, they are in the item's space, not scene space. – paddy Sep 06 '22 at 20:03

1 Answers1

0

Your comments pointed me in the right direction and I found the solution:

poly_points[selected_corner_number] = selectedItem->mapFromScene(mouseEvent->scenePos());

Thanks a lot!

Luis Gouveia
  • 8,334
  • 9
  • 46
  • 68