qt-example之animated picture的学习

     今天一天就主要把这个实验敲了一遍,然后把他写成我们常写的格式吧,本来觉得挺简单的,不过自己敲了一遍之后,发现内容真的挺多的哈哈,初略估计了一下,里面包含了绘图,视图,状态机,时钟(当然这个可有可恶哈哈)等等,   当然重点还是qt的图形视图框架。
     废话就不多说了,哈哈,我们进入正题,首先在看之前我们需要了解下基本的知识---关于qt的图形视图框架(graphics view)

1.1首先是graphics view的特点,主要有以下3个方面:(也就摘抄那些大神的属于了哈哈哈)
  1. 在graphics view 中 ,系统可以利用qt系统的绘图系统的反锯齿,以及open gl工具来改善绘图性能(关于这一点,我们在这个例子中可以深刻的感受到)
  2. graphics view支持事件传播体系结构,可以使图元在scene中的交互 能力大大提高,图元能够处理键盘事件,和鼠标事件(包括鼠标按下、移动、释放双击等等,还可以跟随鼠标的移动),在animated tiles这个例子中,我们可以看到他的强大之处。
  3. graphics view框架中通过BSP(二元空间划分树)提供快速的图元查找,可以实时显示百万个图元的大场景---这个额待考证哈哈
1.2接着必须了解graphics view的三元素:QGraphicsScene、 QGraphicsView 、QGraphicsItem
我们对他们进行粗劣的了解一下吧
(1)QGraphicsScene 场景类,注意这是一个 容器(用于放置图元),不可见、必须通过与之相连的视图类来显示与外界进行交互操作。主要操作:
QGraphicsScene::addItem()---- 添加一个图元到场景中。图元可以通过多个函数进行检索
QGraphicsScene::items()以及一些重载函数可以 返回和点、矩形、多边形或向量路径相交的所有图元。
QGraphicsScene::itemAt()-----返回指定点的最顶层图元。

除了以上这些常用的函数外,场景类可以实现管理图元的状态(如选择和焦点处理)具体函数如下(这个例子当然没有用到哈哈,看到了先提一下,备着以后用到吧):
QGraphicsScene::setSelectionArea()----选择图元(选择区域可以是任意形状),使用QPainterPath表示。
setFocus()以及setFocusItem()-----设置图元焦点
focusItem()--获得具有焦点的图元

将场景内容绘制到特定的绘图设备,可以使用 QGraphicsScene::render()函数在绘图设备上绘制场景
(2)QGraphicsView,视图类,提供可视窗口,显示场景中的图元(是可以滚动的窗口部件哦)
视图类需要讲的话当然是OpenGL,要用它的话,可以使用 QGraphicsView::setViewPort()将视图设置为 QGLWidget,可是咱 这个例子好像没用到哈哈,先提一下吧(我们只用了基本的显示功能嘿嘿)
     视图接受键盘和鼠标的输入事件,也就是我们所说的场景事件(把坐标转换为场景坐标),使用变换矩阵函数 QGraphicsView::matrix()可以变换场景坐标,实现缩放和旋转,QGraphicsView提供了以下函数可以用于与场景的坐标进行转换:( 在我看来一般做地图那块用的多一点,这个回头也可以玩玩
  • QGraphicsView::mapToScene()
  • QGraphicsView::mapFromScene();

(3)QGraphicsItem,图元类,场景中各种图元的基类,在此基础上可以继承出各种图元类。
  • QGraphicsLineItem 直线
  • QGraphicsEllipseItem 椭圆
  • QGraphicsTextItem  文本
  • QGraphicsRectItem 矩形
  • 其他用户自定义图元



1.3 在分析他们之前(其实是很单纯的),咱们还得先别漏了一件事啊,就是QGraphicsView坐标系统

QGraphicsScene场景坐标是所有图元的基础坐标系统,原点在场景的中心。
视图坐标是窗口部件的坐标( QGraphicsView继承自QWidget类),与其他QWidget类是一样的。
图元使用自己的本地坐标,一般一自己的-图元中心为原点。(创建图元后,只需要注意图元坐标就可以了,QGraphicsScene,QGraphicsView会完成所有的变换)
根据需要,qt还提供了这3个坐标系之间的转换:mapToScene()

以上的简要小结如下
View是视图,负责显示;Scene是文档,负责存储数据;Item则是具体要显示的东西
最基本的Qt类就是QGraphicsItem,一般如果要显示自定义的形状通常的做法是继承自QGraphicsItem,然后去实现它的两个纯虚函数 boundingRectpaint,它们的形式化申明如下:
virtual QRectF boundingRect () const = 0
virtual void paint ( QPainter * painter, const QStyleOptionGraphicsItem * option, QWidget * widget = 0 ) = 0

boundingRect就是返回该Item的包围盒,用于Graphics内部的碰撞检测以及选取等计算。paint则是用于Item的重绘

QGraphicsView和QGraphicsScene以及QGraphicsItem都能够接受鼠标、键盘事件,那他们的关系又是如何呢? 首先从消息流来看,先是View,然后是Scene,最后是Item

Scene更新的时候,尽可能将更新范围限制在最小内,毕竟update全局的话需要消耗较多的资源,尤其是显示内容比较大的时候,会不流畅。
获取鼠标下面的item方法是itemAt。若在View中调用此函数,注意它的参数坐标是View中的坐标,即不需要再做任何的转化。
上面结语摘自博文,恩感觉经验很好哈哈;引用一下,可以借鉴

2、以上啰嗦了半天了,不过也讲的差不多啦,上代码:


首先创建animatepicture.h 以及源文件animatepicture.cpp:
接下来开始源码部分,在这个例子中我们创建了3个类:
class animatePicture(用于添加QGraphicsScene),class Button,class View()


/*animate Picture主要继承自*/
class animatePicture : public QObject,public QGraphicsPixmapItem
{
  
    Q_OBJECT
  
    Q_PROPERTY( QPointF  pos  READ  pos  WRITE  setPos)// 【1】
public:
    animatePicture(const QPixmap &pix):QObject(),QGraphicsPixmapItem(pix)
    {
  
        setCacheMode(QGraphicsItem::DeviceCoordinateCache);//设置项的缓存模式
    }
 
 
    ~animatePicture();
};

class Button: public QGraphicsWidget
{
  
    Q_OBJECT
public:
    Button(const QPixmap &pixmap,QGraphicsItem *parent = 0)
        :QGraphicsWidget(parent), _pix(pixmap) //parent = 0 的话没有父对象
    {
  
        setAcceptHoverEvents(true);
        setCacheMode(QGraphicsItem::DeviceCoordinateCache);
 
 
    }
 
 
    virtual QRectF boundingRect() const;
    QPainterPath shape() const;
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *opt
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值