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

版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/zhaoxd200808501/article/details/76177497

一、视图(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();
}

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

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

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

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

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

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

三、图元(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

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

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

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

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

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

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

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

 若setPos函数如下调用:

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

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

四、运行结果

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

展开阅读全文

没有更多推荐了,返回首页