一、简介

GraphicsView框架结构主要包含三个主要的类QGraphicsScene(容器)、QGraphicsView(视图)、QGraphicsItem(图形项)。QGraphicsScene本身不可见必须通过与之相连的QGraphicsView视口类来显示及与外界进行互操作,主要提供项目的操作接口、传递事件和管理各个项目状态;QGraphicsView提供一个可视的窗口,用于显示场景中的项目,一个场景中可以有多个视口;QGraphicsItem是场景中各个项目的基础类。

二、关系图

(1)三者间的关系

(2)坐标系统

QGraphicsScene坐标系是以中心为原点(0,0),QGraphicsView继承自QWidget以窗口的左上角作为自己坐标系的原点,而QGraphicsItem则有自己的坐标系其paint()函数重画时以此坐标系为基准。

(3)坐标映射

三个坐标系之间的相互转换函数及图形项与图形项之间的转换函数。

三、详解

1、运行图

2、解析

(1)利用定时器实现QGraphicsItem不停上下飞舞的蝴蝶的动画效果

#include <QGraphicsItem>
#include <QObject>class Butterfly : public QObject, public QGraphicsItem
{Q_OBJECT
public:Butterfly();void timerEvent(QTimerEvent *);QRectF boundingRect() const;protected:void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);private:bool up;QPixmap pix_up;QPixmap pix_down; qreal angle;};
static const double PI = 3.14159265358979323846264338327950288419717;Butterfly::Butterfly()
{ setFlag(QGraphicsItem::ItemIsMovable);pix_up.load(":/images/butterfly1.PNG");pix_down.load(":/images/butterfly2.PNG");up = true;startTimer(100);
}QRectF Butterfly::boundingRect() const
{qreal adjust = 8;return QRectF(-pix_up.width()/2-adjust,-pix_up.height()/2-adjust,pix_up.width()+adjust*2,pix_up.height()+2*adjust);
}void Butterfly::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{if(up){painter->drawPixmap(boundingRect().topLeft(),pix_up);up = !up;}else{painter->drawPixmap(boundingRect().topLeft(),pix_down);up = !up;}
//    painter->setPen(Qt::NoPen);
//    painter->setBrush(Qt::darkGray);
//    painter->drawEllipse(-7,-7,40,40);//    painter->setPen(QPen(Qt::black,0));
//    painter->setBrush(flash ? (Qt::red):(Qt::yellow));
//    painter->drawEllipse(-10,-10,40,40);}void Butterfly::timerEvent(QTimerEvent *)
{// edge controllqreal edgex = scene()->sceneRect().right()+boundingRect().width()/2;qreal edgetop = scene()->sceneRect().top()+boundingRect().height()/2;qreal edgebottom = scene()->sceneRect().bottom()+boundingRect().height()/2;//qDebug() << scene()->itemsBoundingRect();if (pos().x() >= edgex)setPos(scene()->sceneRect().left(),pos().y());if (pos().y() <= edgetop)setPos(pos().x(),scene()->sceneRect().bottom());if (pos().y() >= edgebottom)setPos(pos().x(),scene()->sceneRect().top());angle += (qrand()%10)/20.0;qreal dx = fabs(sin(angle*PI)*10.0);qreal dy = (qrand()%20)-10.0;setPos(mapToParent(dx,dy));update();
}

分析:在定时器的timeEvent()中对QGraphicsItem进行重画,重画paint()函数中飞舞的蝴蝶是由两幅图片组成,蝴蝶的移动边界做一个限定,dx和dy是相对于蝴蝶的坐标系而言的,调用setPos函数时使用mapToParent()函数映射成场景的坐标。setFlag(QGraphicsItem::ItemIsMovable);使蝴蝶可以通过鼠标移动。

(2)来回移动的星星

class StarItem : public QGraphicsItem
{
public:StarItem();QRectF boundingRect() const;void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);private:QPixmap pix;
};
StarItem::StarItem()
{pix.load(":/images/star.png");
}QRectF StarItem::boundingRect() const
{return QRectF(-pix.width()/2,-pix.height()/2,pix.width(),pix.height());
}void
StarItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{painter->drawPixmap(boundingRect().topLeft(),pix);
}
{StarItem *star = new StarItem;QGraphicsItemAnimation *anim = new QGraphicsItemAnimation;anim->setItem(star);QTimeLine *timeLine = new QTimeLine(4000);timeLine->setCurveShape(QTimeLine::SineCurve);timeLine->setLoopCount(0);anim->setTimeLine(timeLine);int y = (qrand()%400) - 200;for (int i=0; i<400; i++){anim->setPosAt(i/400.0, QPointF(i-200,y));}timeLine->start();scene->addItem(star);
}

分析:利用QGraphicsItemAnimation类和QTimeLine实现项目的动画效果(也可使用定时器QTimer结合重绘函数来实现)。

(3)简单正方形

{QGraphicsRectItem *item = new QGraphicsRectItem(QRectF(0,0,60,60));QPen pen;pen.setWidth(3);pen.setColor(QColor(qrand()%256,qrand()%256,qrand()%256));item->setPen(pen);item->setBrush(QColor(qrand()%256,qrand()%256,qrand()%256));item->setFlag(QGraphicsItem::ItemIsMovable);scene->addItem(item);//item->setPos((qrand()%int(scene->sceneRect().width()))-200,(qrand()%int(scene->sceneRect().height()))-200);item->setPos(-200, -200);
}

分析:利用继承QGraphicsItem的类QGraphicsRectItem添加一个正方形的图形项。

四、总结

(1)GraphicsView框架相对与QWidget难于理解,且内容也比较多,以后会继续更新相应的内容。

(2)本文没有涉及GraphicsView的事件的处理和传播(事件首先由视图接收然后传递给场景再由场景给相应的图形项),读者可自行查阅相应的资料。

(3)源码已经打包上传到csdn上可登录下载(http://download.csdn.net/detail/taiyang1987912/7785071)。

(4)本人思路有限,若有更好的设计建议,也可发邮件沟通,在此先感谢!邮箱地址yang.ao@i-soft.com.cn。

Qt浅谈之十七:飞舞的蝴蝶(GraphicsView框架)相关推荐

  1. Qt图形视图实例:飞舞的蝴蝶

    1.运行效果 2.具体代码 ​​butterfly.h​​ #ifndef BUTTERFLY_H #define BUTTERFLY_H#include <QObject> #inclu ...

  2. 学习QT之图形视图实例#-飞舞的蝴蝶

    一.运行效果 二.具体代码 butterfly.h #ifndef BUTTERFLY_H #define BUTTERFLY_H#include <QObject> #include & ...

  3. Qt浅谈之一:内存泄露(总结)

    一.简介        Qt内存管理机制:Qt 在内部能够维护对象的层次结构.对于可视元素,这种层次结构就是子组件与父组件的关系:对于非可视元素,则是一个对象与另一个对象的从属关系.在 Qt 中,在 ...

  4. IDE / Qt / 浅谈 qmake 之 pro、pri、prf、prl文件

    一. *.pro qmake 的工程(project)文件,栗子: 这是一个典型的 Qt 示例程序的 .pro 文件(propriprfprl.pro): TEMPLATE = app CONFIG ...

  5. Qt浅谈之三十系统托盘(QSystemTrayIcon)

    一.简介 Qt自带的例子/usr/lib64/qt4/examples/desktop/systray中详尽介绍了系统托盘的功能,在其基础上进行拓展,定制适合自己的系统托盘.        托盘菜单实 ...

  6. Qt浅谈之二:钟表(时分秒针)

    一.简介 QT编写的模拟时钟,demo里的时钟只有时针和分针,在其基础上添加了秒针,构成了一个完整的时钟.能对2D绘图中坐标系统.平移变换(translate).比例变换(scale).旋转变换(ro ...

  7. Qt浅谈之八:富文本转换成pdf

    一.简介 Qt对富文本的处理,主要有几个感兴趣的知识点才写下这篇文章,将文本或图片转换成pdf格式.文件直接拖拽到文本框中.双击对程序全屏和缩小.滚动滑轮对文字放大缩小及安装事件过滤器通过键盘的上下按 ...

  8. Qt浅谈之三十九圆形进度条

    一.简介 Qt下进度条一般都是水平或垂直的,有时需要一个椭圆或圆来动态显示进度,或用此来显示存储百分比,都是比较适用的. 二.详解 1.代码 (1)widgetdisplay.h #ifndef WI ...

  9. Qt浅谈之三十六仿360设置中心

    一.简介 模仿360设置中心面板的功能:左侧导航使用QTreeWidget,右侧的显示区域使用QScrollArea控件:主要使用垂直滚动条的valueChanged事件和QTreeWidget的it ...

最新文章

  1. SAP HUM 如何把HU号码与Outbound Delivery 解除Assignment?
  2. 2.在某应用软件中需要记录业务方法的调用日志,在不修改现有业务类的基础上为每一个类提供一个日志记录代理类,在代理类中输出日志,例如在业务方法 method() 调用之前输出“方法 method() 被
  3. 人类如何感受到四维空间?
  4. ajax多选下拉,模拟select下拉框之多选(数据源采用模拟Ajax数据--原创)(示例代码)...
  5. 实战篇|风控策略效率的测试、调优与评估
  6. [C++] 构造函数 which is of non-class type
  7. 在asp.net web api 2 (ioc autofac) 使用 Serilog 记录日志
  8. 关于多线程编程您不知道的5 件事---有关高性能线程处理的微妙之处 (转)
  9. 微信公众号自定义消息模板(处理数据)
  10. python找色_利用python检测色情图片简易实例
  11. 火车售票系统(设计模式分析)
  12. Qt调节电脑屏幕亮度
  13. QT安装我i发下载存档问题解决
  14. 办公局域网内的打印机如何做共享?
  15. 用PHOTOSHOP 1寸照片制作方法
  16. 串口文件送 linux,Linux下secureCRT串口传送文件
  17. 如何在EDUIS中导出ETL字幕模板_Arctime教程——将字幕导出到剪辑/合成软件
  18. UNIAPP中H5微信登录
  19. type=submit表单提交理解
  20. 【目录】成为独立开发者

热门文章

  1. C6678程序中的_mfence()内联函数
  2. stylus在vue中的安装及使用
  3. 个人博客(威博)原创项目
  4. 2023年高新技术企业怎么申报认定
  5. 【微服务】Day17(酷鲨商城前台业务总结、布隆过滤器、Docker)
  6. 名画381 齐白石《人物画十七幅》
  7. 安卓自定义View进阶-事件分发机制原理
  8. jenkins:Build periodically和Poll SCM的区别
  9. c# SQLite下载和安装
  10. 日撸 Java 三百行(51-60天,kNN 与 NB)