当前位置:   article > 正文

Qt图形视图框架三--坐标系统简介_qgraphicsscene 坐标系

qgraphicsscene 坐标系
一、视图(QGraphicsView)的坐标

视图将窗口中的左上角作为原点(0,0),不弄窗口大小,原点总是在左上角。向右为X轴正方向,向下为Y轴正方向。如下图所示:
  这里写图片描述

二、场景(QGraphicsScene)的坐标

通常情况下场景的坐标原点(0,0)在场景的的中心位置。向右为X轴的正方向,向下为Y轴的正方向,如下图所示:
  这里写图片描述
  场景通过void setSceneRect(qreal x, qreal y, qreal w, qreal h)来设置场景的坐标以及大小。其中x和y用于设定场景左上角的坐标,w和h来设定场景的大小。先分析下面代码:

main.cpp

#include <QApplication>
#include "butterfly.h"
#include <QGraphicsScene>
#include <QPointF>
#include <QMainWindow>

#include <QDebug>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QGraphicsScene *scene = new QGraphicsScene;
    scene->setSceneRect(0, 0, 400, 400);
    
    Butterfly *butterfly = new Butterfly();
    butterfly->setPos(scene->sceneRect().left(), scene->sceneRect().top());

    scene->addItem(butterfly);
    QGraphicsView *view = new QGraphicsView;
    view->setScene(scene);

    view->show();

    // 视图坐标原点(0,0)对应场景坐标(场景坐标)
    qDebug() << "view->mapToScene(0, 0):" << view->mapToScene(0, 0);

    // 场景坐标原点(0,0)对应视图坐标(视图坐标)
    qDebug() << "view->mapFromScene(0, 0):" << view->mapFromScene(0, 0);

    // 场景左上角坐标(场景坐标)
    QPointF p1 = QPointF(scene->sceneRect().topLeft());
    qDebug() << "p1:" << p1;

    // 场景左上角对应视图坐标(视图坐标)
    qDebug() << "view->mapFromScene(p1.x(), p1.y())" << view->mapFromScene(p1.x(), p1.y());

    return a.exec();
}

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40

输出结果如下图所示:
这里写图片描述
  
  由上图可知,视图原点和场景原点重合了,若对代码做如下修改:

scene->setSceneRect(-200, -200, 400, 400);  
// -200是相对于场景中心位置的偏移,由于是在X轴和Y轴的反方向,故为负数
  • 1
  • 2

输出结果如下图所示:
这里写图片描述
  
  由上图可知,场景的原点在视图的中心位置。若对代码做如下修改:

scene->setSceneRect(-400, -400, 400, 400);  
  • 1

输出结果如下图所示:
这里写图片描述
  
  由上图可知,场景的原点在视图的右下角位置。

从这三次的实验结果来看,最后一条打印的结果是一样的,也就是说场景的左上角一直和视图的左上角重合,当然也有可能出现不重合的情况。

三、图元(QGraphicsItem)坐标

图元使用自己的本地坐标,这个坐标系统通常以图元中心为原点,这也是所有变换的原点。图元坐标X轴正方向向右,Y轴正方向向下。图元创建后,只需注意图元坐标就可以了,QGraphicsScene和QGraphicsView会完成所有的变换。图元坐标如下图所示:
  这里写图片描述
  当然在自定义图元时,也可以指定图元的原点为其他位置,分析下面代码:
  
butterfly.h

#ifndef BUTTERFLY_H
#define BUTTERFLY_H

#include <QObject>
#include <QGraphicsItem>
#include <QPainter>
#include <QGraphicsScene>
#include <QGraphicsView>

class Butterfly : public QObject, public QGraphicsItem
{
    Q_OBJECT
public:
    explicit Butterfly(QObject *parent = 0);
    QRectF boundingRect() const;

protected:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *);

private:
    QPixmap pix_up;            //用于表示两幅蝴蝶的图片
    QPixmap pix_down;
};

#endif // BUTTERFLY_H
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

butterfly.cpp

#include "butterfly.h"
#include <math.h>
#include <QDebug>

Butterfly::Butterfly(QObject *parent) : QObject(parent)
{
    pix_up.load(":/img/up.png");
    pix_down.load(":/img/down.png");
}

QRectF Butterfly::boundingRect() const
{
    return QRectF(-pix_up.width()/2, -pix_up.height()/2, pix_up.width(), pix_up.height());
}

void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *, QWidget *)
{
    painter->drawPixmap(boundingRect().topLeft(), pix_up);
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

上述代码中,函数QRectF Butterfly::boundingRect() const为图元限定了区域范围(图元左上角坐标以及宽和高),上述实现中图元的原点便在图元的中心,若改为如下实现:

QRectF Butterfly::boundingRect() const
{
    return QRectF(0, 0, pix_up.width(), pix_up.height());
}
  • 1
  • 2
  • 3
  • 4

则,原点是图元的左上角,如下图所示:
  这里写图片描述

下面代码是添加图元到场景中:

	Butterfly *butterfly = new Butterfly();
    butterfly->setPos(scene->sceneRect().left(), scene->sceneRect().top());
  • 1
  • 2

其中butterfly->setPos(scene->sceneRect().left(), scene->sceneRect().top());指定***图元的原点在场景中的坐标***,若图元的原点在左上角,那么根据这段代码,可知图元在场景中的坐标如下图所示:
  这里写图片描述

若setPos函数如下调用:

butterfly->setPos(scene->sceneRect().left()+100, scene->sceneRect().top()+100);
  • 1

则坐标图便如下所示:
  这里写图片描述

四、运行结果

下图为本次实验最终运行结果:
这里写图片描述

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/91720
推荐阅读
相关标签
  

闽ICP备14008679号