Qt Forum

    • Login
    • Search
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Groups
    • Search
    • Unsolved

    Unsolved Qt mismatch of coordinates

    General and Desktop
    2
    2
    82
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • A
      angeleyes last edited by angeleyes

      Hello.
      I added a itemgroup (inherited from QObject and QGraphicsItemGroup) to the coordinates (25,0), then I added an ellipse to the coordinates (25, 0) and added a picture. (CanvasScene inherited from QGraphicsScene). I also drew the position of the group.

      Screenshot from 2021-04-24 10-49-51.png

      Why the coordinates of itemgroup and ellipse don't match? And why x-position of image equal to x-positon of itemgroup?

      main.cpp:

      #include "mainwindow.h"
      
      #include <QApplication>
      
      int main(int argc, char *argv[])
      {
          QApplication a(argc, argv);
          MainWindow w;
          w.show();
          return a.exec();
      }
      

      mainwindow.h

      #ifndef MAINWINDOW_H
      #define MAINWINDOW_H
      
      #include <QMainWindow>
      #include <QGraphicsView>
      #include <QGraphicsItem>
      #include <QMouseEvent>
      //-----------------------------------------
      class MoveItem : public QObject, public QGraphicsRectItem
      {
          Q_OBJECT
          Q_INTERFACES(QGraphicsItem)
      public:
          MoveItem(const QString& path, uint64_t& zc, QGraphicsRectItem *parent = nullptr);
          ~MoveItem();
          QRectF boundingRect() const override;
      signals:
      protected:
          void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
      
      private:
          QImage qimage_;
          QPixmap pixmap_;
          QRectF rect_;
          uint64_t& zCounter_;
      };
      
      
      //-----------------------------------------
      class ItemGroup : public QObject, public QGraphicsItemGroup
      {
          Q_OBJECT
          Q_INTERFACES(QGraphicsItem)
      public:
          ItemGroup(uint64_t& zc, QGraphicsItemGroup *parent = nullptr);
          ~ItemGroup() = default;
      
      protected:
          void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget) override;
      private:
          uint64_t& zCounter_;
      };
      
      
      
      //-----------------------------------------
      class CanvasScene : public QGraphicsScene
      {
      public:
          CanvasScene(uint64_t& zc, QGraphicsScene *scene = 0);
          ~CanvasScene() = default;
      
      private:
          uint64_t& zCounter_;
          ItemGroup* itemGroup_ = nullptr;
      };
      
      
      //-----------------------------------------
      #define ZOOM_FACTOR 1.15
      class CanvasView : public QGraphicsView
      {
          Q_OBJECT
      public:
          CanvasView(QWidget* parent = 0);
          ~CanvasView();
      
          void addImage(const QString& path, QPointF point);
          void setZoomFactor(double factor) { zoomFactor_ = factor; }
      protected:
          void mouseMoveEvent(QMouseEvent* event) override;
          void mousePressEvent(QMouseEvent* event) override;
          void mouseReleaseEvent(QMouseEvent* event) override;
          void wheelEvent(QWheelEvent* event) override;
          void resizeEvent(QResizeEvent *event) override;
          virtual QString setToolTipText(QPoint imageCoordinates);
          void drawBackground(QPainter *painter, const QRectF &rect) override;
      private:
          CanvasScene* scene_;
          double zoomFactor_;
          bool pan_;
          bool panStartX_;
          bool panStartY_;
          uint64_t zCounter_ = 0;
      };
      
      
      
      QT_BEGIN_NAMESPACE
      namespace Ui { class MainWindow; }
      QT_END_NAMESPACE
      
      class MainWindow : public QMainWindow
      {
          Q_OBJECT
      
      public:
          MainWindow(QWidget *parent = nullptr);
          ~MainWindow();
      
      private:
          Ui::MainWindow *ui;
          CanvasView* canvasWidget;
      };
      #endif // MAINWINDOW_H
      

      mainwindow.cpp

      #include "mainwindow.h"
      #include "./ui_mainwindow.h"
      
      MoveItem::MoveItem(const QString& path, uint64_t& zc, QGraphicsRectItem *parent) :
          QGraphicsRectItem(parent), zCounter_(zc)
      {
          qimage_ = QImage(path);
          rect_ = qimage_.rect();
          setAcceptHoverEvents(true);
          setFlag(QGraphicsItem::ItemIsMovable, true);
      }
      
      MoveItem::~MoveItem() {}
      
      QRectF MoveItem::boundingRect() const
      {
          return QRectF (0, 0, rect_.width(), rect_.height());
      }
      
      void MoveItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
      {
          painter->setPen(QPen(QColor(0, 160, 230),2));
          painter->drawImage(boundingRect(), qimage_);
      }
      
      //-----------------------------------------------
      ItemGroup::ItemGroup(uint64_t& zc, QGraphicsItemGroup *parent) :
          QGraphicsItemGroup(parent),
          zCounter_(zc)
      {
          setAcceptHoverEvents(true);
          setFlags(ItemIsSelectable|ItemSendsGeometryChanges);
      }
      
      
      void ItemGroup::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
      {
          painter->save();
          painter->setPen( QPen(Qt::green, 3) );
          painter->drawEllipse(this->pos(), 6,6);
          painter->setPen( QPen(Qt::darkMagenta, 3) );
          painter->drawEllipse(this->scenePos(), 3,3);
          painter->restore();
      }
      
      //-----------------------------------------------
      CanvasScene::CanvasScene(uint64_t& zc, QGraphicsScene *scene) : zCounter_(zc)
      {
          (void)scene;
          itemGroup_ = new ItemGroup(zc);
          itemGroup_->setHandlesChildEvents(true);
      
          QPointF p = {25,0};
          itemGroup_->setPos(p);
          addItem(itemGroup_);
      
          addEllipse(QRectF(25, 0, 3, 3), QPen(Qt::black), QBrush(Qt::green));
      
          ++zCounter_;
          MoveItem* item = new MoveItem("bender.png", zCounter_);
          item->setFlag(QGraphicsItem::ItemIsSelectable, true);
          item->setPos({50,50});
          addItem(item);
      }
      
      CanvasView::CanvasView(QWidget* parent) :
          QGraphicsView(parent)
      {
          zoomFactor_ = ZOOM_FACTOR;
          scene_ = new CanvasScene(zCounter_);
          setMouseTracking(true);
          setScene(scene_);
          setViewportUpdateMode(QGraphicsView::FullViewportUpdate);
          setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
          setDragMode(QGraphicsView::RubberBandDrag);
          setResizeAnchor(QGraphicsView::AnchorViewCenter);
      }
      
      
      CanvasView::~CanvasView()
      {
          delete scene_;
      }
      
      
      void CanvasView::addImage(const QString& path, QPointF point)
      {
          ++zCounter_;
          MoveItem* item = new MoveItem(path, zCounter_);
          item->setFlag(QGraphicsItem::ItemIsSelectable, true);
          item->setPos(point);
          scene_->addItem(item);
      }
      
      
      void CanvasView::mouseMoveEvent(QMouseEvent *event)
      {
          if (pan_) {
              panStartX_ = event->position().x();
              panStartY_ = event->position().y();
              event->accept();
          }
          QGraphicsView::mouseMoveEvent(event);
      }
      
      
      void CanvasView::mousePressEvent(QMouseEvent *event)
      {
          if (event->button() == Qt::LeftButton) {
               pan_ = true;
               panStartX_ = event->position().x();
               panStartY_ = event->position().y();
               event->accept();
      
           }
          QGraphicsView::mousePressEvent(event);
      }
      
      
      void CanvasView::mouseReleaseEvent(QMouseEvent *event)
      {
          QGraphicsView::mouseReleaseEvent(event);
          if (event->button() == Qt::LeftButton) {
              pan_ = false;
              event->accept();
            }
      }
      
      void CanvasView::wheelEvent(QWheelEvent *event)
      {
          // When zooming, the view stay centered over the mouse
          this->setTransformationAnchor(QGraphicsView::AnchorUnderMouse);
      
          auto numPixels = event->angleDelta();
      //    qInfo()<<"CanvasView::wheelEvent: "<<numPixels.x()<<' '<<numPixels.y();
          double factor = zoomFactor_;//(event->modifiers() & Qt::ControlModifier) ? zoomCtrlFactor : zoomFactor;
          if (numPixels.y() > 0) {
              scale(factor, factor);
          } else {
              scale(1/factor, 1/factor);
          }
      
          // The event is processed
          event->accept();
      }
      
      
      void CanvasView::resizeEvent(QResizeEvent *event)
      {
          // First call, the scene is created
          if(event->oldSize().width() == -1 || event->oldSize().height() == -1) return;
      
          // Get the previous rectangle of the scene in the viewport
          QPointF P1=mapToScene(QPoint(0,0));
          QPointF P2=mapToScene(QPoint(event->oldSize().width(),event->oldSize().height()));
      
          // Stretch the rectangle around the scene
          if (P1.x()<0) P1.setX(0);
          if (P1.y()<0) P1.setY(0);
          if (P2.x()>scene_->width()) P2.setX(scene_->width());
          if (P2.y()>scene_->height()) P2.setY(scene_->height());
      }
      
      
      QString CanvasView::setToolTipText(QPoint imageCoordinates)
      {
          (void)imageCoordinates;
          return QString("");
      
      }
      
      void CanvasView::drawBackground(QPainter *painter, const QRectF &rect)
      {
          setCacheMode(CacheNone);
          painter->save();
          setBackgroundBrush(QBrush(QColor(77, 77, 77)));
          painter->fillRect(rect, backgroundBrush());
          scene_->setBackgroundBrush(QBrush(QColor(158, 158, 158)));
          painter->fillRect(scene_->sceneRect(), scene_->backgroundBrush());
          painter->setPen( QPen(QColor(247, 0, 255),2) );
          painter->drawRect(scene_->sceneRect());
          painter->restore();
      }
      
      //-----------------------------------------------
      MainWindow::MainWindow(QWidget *parent)
          : QMainWindow(parent)
          , ui(new Ui::MainWindow)
      {
          ui->setupUi(this);
          canvasWidget = new CanvasView();
          canvasWidget->addImage("bender.png", {-1000, -1000});
          canvasWidget->addImage("bender.png", {1300,1300});
          setCentralWidget(canvasWidget);
      }
      
      MainWindow::~MainWindow()
      {
          delete ui;
          delete canvasWidget;
      }
      

      regads, max

      1 Reply Last reply Reply Quote 0
      • Kent-Dorfman
        Kent-Dorfman last edited by

        It is late-oclock and I'm lazy so not reading your code, but the general reason people have problems with coordinates is because they forget that coordinates are relative to the parent widget, not global screen coordinates.

        1 Reply Last reply Reply Quote 4
        • First post
          Last post