Qt文档阅读笔记-Transformations解析及例子
目錄
官方解析
博主小栗子
官方解析
QGraphicsItem除了基于他的坐標pos()外,還支持投影變化。下面提供了幾種變化item的方式。下面來說明下簡單的轉(zhuǎn)換,可以通過調(diào)用setRotation()或setScale(),或者調(diào)用setTransform(),這個方式是通過變化矩陣實現(xiàn)的。下面來說明下高級點的操作,可以通過調(diào)用setTransformations()選擇幾個被寫好的transformations進行圖像變化。
item的轉(zhuǎn)變是從parent到child逐步累計的(這一點和OpenGL感覺有點差別,OpenGL是只對當前矩陣上的物體有影響),舉個栗子,如果一個parentItem和childItem同時被設(shè)置旋轉(zhuǎn)90度,那么childItem最后將旋轉(zhuǎn)180讀。同樣的道理,如果一個parent item在他的原始尺寸上放大了2倍,那么他所有的child item都會被放大2倍。當一個item被轉(zhuǎn)化成其他形態(tài)后他自己的坐標系將不受影響(這個功能牛逼,贊一下);所有的關(guān)于幾何的函數(shù)(比如contains(),update(),所有的mapping函數(shù))都將可以在他原坐標系進行操作。為了方便,QGraphicsItem提供了一個叫sceneTransform()的函數(shù),這個函數(shù)返回這個Item的總變化矩陣(包括他的位置,和所有parent的坐標以及transformations)以及他在場景中的位置。調(diào)用resetTransform()可以重設(shè)他的變化矩陣。
在線性代數(shù)里面,矩陣是不具有交換率的,所以不同順序的操作,會有不同的轉(zhuǎn)變。舉個栗子,放大后旋轉(zhuǎn)和旋轉(zhuǎn)后放大將造成不同的結(jié)果。但是在QgraphicsItem中卻可以進行這樣的騷操作,也就是有交換律;QGraphicsItem有著他固定的操作,順序如下:
1.調(diào)用transform實現(xiàn)最基本的轉(zhuǎn)換(transform);
2.item是按照transformatins列表進行的(transformations());
3.item的旋轉(zhuǎn)依賴于他轉(zhuǎn)換的源坐標(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_Hmygraphicsview.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_Hwidget.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_Hmain.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; }?
總結(jié)
以上是生活随笔為你收集整理的Qt文档阅读笔记-Transformations解析及例子的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Linux工作笔记-解决spawn: n
- 下一篇: Qt的信号槽机制介绍(含Qt5与Qt4的