目录

官方解析

博主小栗子


官方解析

QGraphicsItem除了基于他的坐标pos()外,还支持投影变化。下面提供了几种变化item的方式。下面来说明下简单的转换,可以通过调用setRotation()或setScale(),或者调用setTransform(),这个方式是通过变化矩阵实现的。下面来说明下高级点的操作,可以通过调用setTransformations()选择几个被写好的transformations进行图像变化。

item的转变是从parent到child逐步累计的(这一点和OpenGL感觉有点差别,OpenGL是只对当前矩阵上的物体有影响),举个栗子,如果一个parentItem和childItem同时被设置旋转90度,那么childItem最后将旋转180读。同样的道理,如果一个parent item在他的原始尺寸上放大了2倍,那么他所有的child item都会被放大2倍。当一个item被转化成其他形态后他自己的坐标系将不受影响(这个功能牛逼,赞一下);所有的关于几何的函数(比如contains(),update(),所有的mapping函数)都将可以在他原坐标系进行操作。为了方便,QGraphicsItem提供了一个叫sceneTransform()的函数,这个函数返回这个Item的总变化矩阵(包括他的位置,和所有parent的坐标以及transformations)以及他在场景中的位置。调用resetTransform()可以重设他的变化矩阵。

在线性代数里面,矩阵是不具有交换率的,所以不同顺序的操作,会有不同的转变。举个栗子,放大后旋转和旋转后放大将造成不同的结果。但是在QgraphicsItem中却可以进行这样的骚操作,也就是有交换律;QGraphicsItem有着他固定的操作,顺序如下:
1.调用transform实现最基本的转换(transform);
2.item是按照transformatins列表进行的(transformations());
3.item的旋转依赖于他转换的源坐标(rotation(),transformOriginPoint());
4.item的放缩也依赖于他的源坐标(scale(),transformOriginPoint())。

博主小栗子

运行截图如下:

源码如下:

mygraphicsitem.h

#ifndef MYGRAPHICSITEM_H
#define MYGRAPHICSITEM_H#include <QGraphicsItem>class MyGraphicsItem:public QGraphicsItem
{
public:MyGraphicsItem();void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);QRectF boundingRect() const;};#endif // MYGRAPHICSITEM_H

mygraphicsview.h

#ifndef MYGRAPHICSVIEW_H
#define MYGRAPHICSVIEW_H#include <QGraphicsView>QT_BEGIN_NAMESPACE
class QGraphicsScene;
class QGraphicsItem;
class QTimeLine;
QT_END_NAMESPACEclass MyGraphicsItem;class MyGraphicsView : public QGraphicsView
{Q_OBJECT
public:explicit MyGraphicsView(QWidget *parent = 0);public slots:void updateStep(int value);void finished();signals:void mousePos();protected:void mouseMoveEvent(QMouseEvent *event)Q_DECL_OVERRIDE;private:QGraphicsScene *m_scene;QList<QGraphicsItem*> m_list;QTimeLine *m_timeLine;MyGraphicsItem *m_currentItem;bool timeLineIsRun;
};#endif // MYGRAPHICSVIEW_H

widget.h

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>namespace Ui {
class Widget;
}class Widget : public QWidget
{Q_OBJECTpublic:explicit Widget(QWidget *parent = 0);~Widget();void mouseMoveEvent();private:Ui::Widget *ui;
};#endif // WIDGET_H

main.cpp

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

mygraphicsitem.cpp

#include "mygraphicsitem.h"
#include <QPainter>MyGraphicsItem::MyGraphicsItem()
{}void MyGraphicsItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{painter->save();painter->setPen(QPen(Qt::red,4));painter->drawRect(0,0,50,50);painter->restore();
}QRectF MyGraphicsItem::boundingRect() const
{return QRectF(0,0,50,50);
}

mygraphicsview.cpp

#include "mygraphicsview.h"
#include "mygraphicsitem.h"
#include <QGraphicsScene>
#include <QTransform>
#include <QMouseEvent>
#include <QTimeLine>
#include <QDebug>MyGraphicsView::MyGraphicsView(QWidget *parent): QGraphicsView(parent)
{MyGraphicsItem *item=new MyGraphicsItem;m_scene=new QGraphicsScene;this->setScene(m_scene);m_scene->addItem(item);m_list.append(item);setMouseTracking(true);m_timeLine=new QTimeLine;m_timeLine->setFrameRange(0,500);connect(m_timeLine,SIGNAL(frameChanged(int)),this,SLOT(updateStep(int)));connect(m_timeLine,SIGNAL(finished()),this,SLOT(finished()));m_currentItem=NULL;timeLineIsRun=false;
}void MyGraphicsView::updateStep(int value)
{if(m_currentItem==NULL&&timeLineIsRun)return;//    QPointF pt=m_currentItem->boundingRect().center();
//    m_currentItem->setTransformOriginPoint(pt); //it only works for item. isn't QTransform
//    m_currentItem->setRotation(value);//    QPointF pt=m_currentItem->boundingRect().center();
//    qreal scaleX_Y=value/100.0;
//    QTransform tran;
//    tran.translate(pt.x(),pt.y());  //move to center
//    tran.scale(scaleX_Y,scaleX_Y);
//    m_currentItem->setTransform(tran);
//    QTransform t;
//    t.translate(-pt.x(), -pt.y());  //equal to reset
//    m_currentItem->setTransform(t, true);QPointF pt=m_currentItem->boundingRect().center();qreal angle=value/2.0;QTransform transform;transform.translate(pt.x(),pt.y());  //move to centertransform.rotate(angle,Qt::XAxis);m_currentItem->setTransform(transform);QTransform t;t.translate(-pt.x(), -pt.y());  //equal to resetm_currentItem->setTransform(t, true);update();
}void MyGraphicsView::finished()
{qDebug()<<"finished!";timeLineIsRun=!timeLineIsRun;m_currentItem->resetTransform();m_currentItem=NULL;
}void MyGraphicsView::mouseMoveEvent(QMouseEvent *event)
{QGraphicsView::mouseMoveEvent(event);QTransform transform;QGraphicsItem *item=m_scene->itemAt(mapToScene(event->pos()),transform);if(item&&!timeLineIsRun){//makes item's view big or smallm_currentItem=static_cast<MyGraphicsItem*>(item);m_timeLine->start();timeLineIsRun=!timeLineIsRun;}
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"
#include "mygraphicsitem.h"
#include <QGraphicsScene>
#include <QTransform>Widget::Widget(QWidget *parent) :QWidget(parent),ui(new Ui::Widget)
{ui->setupUi(this);
}Widget::~Widget()
{delete ui;
}

Qt文档阅读笔记-Transformations解析及例子相关推荐

  1. Qt文档阅读笔记-Q_PROPERTY解析及实例

    目录 官方解析 博主栗子 官方解析 这个宏用于继承于QObject的类声明属性.这样声明后的属性行为与类数据成员一样,但是他们可以通过元对象系统进行访问. Q_PROPERTY(type name(R ...

  2. Qt文档阅读笔记-QIODevice解析及Audio Example实例解析

    目录 QIODevice官方解释及个人分析 Audio Example官方实例解析 QIODevice官方解释及个人分析 QIODevice类是Qt中I/O设备的接口. 提供了读和写的接口,QIODe ...

  3. Qt文档阅读笔记-QQmlApplicationEngine解析与实例(qml与C++混合编程及QQuick与widgets混合)

    目录 官方解析 博主例子 官方解析 QQmlApplicationEngine提供了从一个QML文件里面加载应用程序的方式. 这类联合了QQmlEngine和QmlComponent去加载单独的QML ...

  4. Qt文档阅读笔记-QLatin1String解析及文本段跨行赋值

    QString的许多成员函数都被重载了,用于接收const char *.包括拷贝构造函数.分配符.操作符 insert().replace().indexOf().上述的函数都被优化避免const ...

  5. Qt文档阅读笔记-QScopedPointer解析及实例

    当指针超出范围后就会删除被引用的对象. 与QPointer不同,他可以在任意类型中使用(QPointer只能在identity type中使用) 4个不同的清除类         1. QScoped ...

  6. Qt文档阅读笔记-共享库的创建与调用

    使用共享库的符号 这个符号可以作用在变量.类.函数中,并且这些都可以被调用端使用. 在编译共享库中,需要使用export符号.在使用端调用的时候使用import符号. 这里是本人从文档中记录的笔记,大 ...

  7. Qt文档阅读笔记-加载HeightMap(高度图)构造3D地形图

    Qt文档阅读笔记-加载HeightMap(高度图)构造3D地形图 QHeightMapSurfaceDataProxy:是Q3DSurface的一个基本代理类. 他是专门加载高度图. 高度图是没有X, ...

  8. Qt文档阅读笔记-Rotations Example相关

    Rotations Example文档阅读笔记 使用这种方式,对y轴和z轴进行旋转. QQuaternion yRotation = QQuaternion::fromAxisAndAngle(0.0 ...

  9. Qt文档阅读笔记-Fortune Client Example实例解析

    目录 官方解析 实例代码 博主增加解析 官方解析 Fortune Client Example 以使用QTcpSocket为例子,服务端可以配合Fortune Server或Threaded Fort ...

最新文章

  1. java多线程-死锁的一些问题
  2. flink开发案例_为什么说 Flink + AI 值得期待?
  3. Java校招笔试题-Java基础部分(七)
  4. 2017.4.16 级数求和 思考记录
  5. 哦~最重要的产品链接忘了发了
  6. Django index_together设置
  7. 电商项目的app学习笔记(三)-嵌套路由组件的实现
  8. 用Java实现简单的学生管理系统
  9. case when 多条件 oracle,casewhen(casewhen同时满足多条件)
  10. 城市历年人均GDP API数据接口
  11. 深圳医保社保的使用方法
  12. 截止失真放大电路_模电必学基本放大电路
  13. 使用python绘制3维正态分布图
  14. 「Python」面向对象封装案例3——士兵突击(需求分析、代码演练)
  15. 绝了!一个妹子 rm -rf 把公司整个数据库删没了...
  16. 浅谈共线性的产生以及解决方法(上篇——前世)
  17. 2019互联网公司100强
  18. c语言实现灰度图转换
  19. 如何链接外部JavaScript文件
  20. 高防CDN相比普通CDN的优势有哪些?

热门文章

  1. [原创]性能测试之“Windows性能监视器”
  2. 轻松学习 Flex 布局的小游戏
  3. 腾讯:中小企业数字化转型路径报告|附PDF下载
  4. 苹果员工出逃现象严重:人才挽留成大难题
  5. WZ132源代码有的在运果子
  6. 美国科学家研制出由病毒构成的微型电池
  7. 利用C++Builder自定义Windows窗体“系统菜单”
  8. 一张图告诉你,自学编程和科班程序员的差别在哪
  9. Python 为了提升性能,竟运用了共享经济!赶紧看看!!
  10. 因为加班,错过77万年终大奖,你还加班?