Qt mismatch of coordinates
Unsolved
General and Desktop
-
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.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
-
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.