Qt-MVC图形视图框架初识

  使用QPushButtonQLabelQCheckBox等构成GUI的控件或自定义图形时,开发应用程序会变得很简单。
但是如果想在GUI中使用数十个或者数百个图形对象,向用户完美展示控制场景,则会受到很多的限制。
   使用Qt图形视图框架用来管理2D图形项,支持绘制、缩放、事件响应等等。
    1、快速提供并管理大量对象
    

    2、将事件传递到每一个对象

    3、管理焦点处理或对象选择等状态

  在需要大量图元绘制时为什么要使用Qt的图形试图框架呢?因为效率高!那为什么效率高,效率又有多高呢?

    答案就是QGraphicsView框架通过二元空间划分树(Binary Space Partitioning,BSP)提供快速的图元查找,这样就能够实时地显示包含上百万个图元的大场景了。

  在Qt图形视图中起主要作用的3个类:,分别是QGraphicsView(视图),QGraphicsSence(场景),QGraphicsItem(图元);

    QGraphicsView   :  间接继承于QWidget,既然是继承于Ui类。

    QGraphicsSence:一个用来容纳图元的容器。

    QGraphicsItem   :  所有图元的基类。

    三者关系:QGraphicsItem是图形的抽象;QGraphicsSence用来容纳QGraphicsItem对象的容器,但是无法显示图元,只有依赖QGraphicsView才能显示图元。

  下面代码以一个最简单的例子来演示三者之间的关系:

蝴蝶飞舞 
#include <QApplication>
#include "butterfly.h"
#include <QGraphicsScene>

#if 0
结构总结:
①继承QGraphicsItem生成了一个可自我维护的图元。
②生成场景,设置场景大小。
③生成QGraphicsView用于对场景进行显示。
#endif


int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    QGraphicsScene *scene = new QGraphicsScene;
    //确定scene的大小 四个参数依次是:x起点,y起点 长度 宽度
    scene->setSceneRect(QRectF(-200,-200,400,400));
    
    //继承于QGraphicsItem
    Butterfly *butterfly = new Butterfly;
    butterfly->setPos(-100,0);

    scene->addItem(butterfly);

    QGraphicsView *view = new QGraphicsView;
    view->setScene(scene);
    view->resize(1920,1080);
    view->show();

    return a.exec();
}

 

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);
    //一个被重写的虚函数,可以使用startTimer(100)启动
    void timerEvent(QTimerEvent *);
    QRectF boundingRect() const;  
    
signals:
    
public slots:
protected:
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget);

private:
    bool up;
    QPixmap pix_up;            //用于表示两幅蝴蝶的图片
    QPixmap pix_down;

    qreal angle;
};

#endif // BUTTERFLY_H

 

butterfly.cpp
#include "butterfly.h"
#include <math.h>

const static double PI=3.1416;

Butterfly::Butterfly(QObject *parent) :
    QObject(parent)
{
    up = true;
    pix_up.load(":/up.png");
    pix_down.load(":/down.png");

    startTimer(100);
}

QRectF Butterfly::boundingRect() const
{
    qreal adjust =2;
    return QRectF(-pix_up.width()/2-adjust,-pix_up.height()/2-adjust,pix_up.width()+adjust*2,pix_up.height()+adjust*2);
}

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

void Butterfly::timerEvent(QTimerEvent *)
{
    //边界控制
    qreal edgex=scene()->sceneRect().right()+boundingRect().width()/2;
    qreal edgetop=scene()->sceneRect().top()+boundingRect().height()/2;
    qreal edgebottom=scene()->sceneRect().bottom()+boundingRect(). height()/2;

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

 

 

    



posted @ 2018-05-29 20:44  小念之歌  阅读(782)  评论(0编辑  收藏  举报