Qt5之图形视图框架

一、简述

  1. 图形视图框架提供了一个基于图形项的模型视图编程方法
  2. 组成三元素:场景(QGraphicsScene类)、视图(QGraphicsView类)、图形项(QGraphicsItem类)。
  3. 多个视图可以看到同一个场景,场景包含各种各样的几何形状的图形项(图形项的行为:如移动、叠加、碰撞、拖动、缩放、旋转等)。
  4. QGraphicScene(场景)可以管理多个图形项QGraphicsItem(如:QGraphicsRectItem(矩形的图形项,即图元)),QGraphicsView(视图)关联场景可以让场景中的所有图形项可视化。

二、简单应用——发射爱心碰撞

在视图类中新建一个场景,以及相应的图元(小人物、爱心),将图元添加到场景中,将视图与场景关联,最后显示视图。场景是管理图元的,所有的图元必须添加到一个场景中,但是场景本身无法可视化,要看到场景上的内容,必须用上视图。

1、实现效果

 

2、源码:

2.1图元类:

class MyItem : public QObject,public QGraphicsItem//要加QObject
{
    Q_OBJECT
public:
    int type;
    bool isLife;
    QString fileName;
    QPixmap pix;
    //方法
    MyItem();
    MyItem(QString fileName,int type,bool isLife);
    QRectF boundingRect() const override;//boundingRect虚函数
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) override;

public slots:
    void advance(int phase) override;
signals:
    void itemCollding();//用来发送信号,不要定义方法
};
MyItem::MyItem(QString fileName, int type, bool isLife)//fileName加载图片
{
    pix.load(fileName);//pix存图片
    this->type = type;
    this->isLife = isLife;

}
//画边界
QRectF MyItem::boundingRect() const
{
    qreal penWidth = 1;
    return QRectF(0,0,pix.width(),pix.height());
}
//重绘
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    //标明该参数没有使用
    Q_UNUSED(option)
    Q_UNUSED(widget)
      painter->drawPixmap(0,0,pix.width(),pix.height(),pix);//不是pix.width()图片拖尾

}
//移动,用定时器,绑定advance
void MyItem::advance(int phase)
{
    qDebug()<<"advance";
    if(collidingItems().isEmpty())
    {
        if(this->type == 1)//左边爱心的发射
        {
            moveBy(20,0);
        }
        if(this->type == 2)
        {

            moveBy(-20,0);
        }
    }
    else
    {
        this->isLife = true;//要给为true,不然碰撞后弹不出界面
        emit itemCollding();//发送信号给视图类
    }

}

2.2视图类:

class animationView : public QGraphicsView
{
    Q_OBJECT
public:
    animationView();
    QGraphicsScene *pscene ;//场景指针
    MyItem *item1;//图元
    MyItem *item2;
    MyItem *item4;
    MyItem *item3;
    MyItem *item5;
    MyItem *item6;

    QTimer *time1;//定时器
    QTimer *time2;
public slots:
    void itemMoveStopSlot();//要使用Q_OBJECT
};
animationView::animationView()
{

    this->resize(900,800);
    /*1、创建场景、图元*/
    pscene = new QGraphicsScene;
    item1 = new MyItem(":/love-l.png",1,false);//左边爱心
    item2 = new MyItem(":/love-r.png",2,false);
    item5 = new MyItem(":/l1.png",5,false);//左边小人物
    item6 = new MyItem(":/r1.png",6,false);

    /*2、位置及数量关系*/
    item5->setPos(0,230);
    item6->setPos(680,230);
    item1->setPos(100,this->height()/3);
    item2->setPos(600,this->height()/3);
    pscene->addItem(item1);
    pscene->addItem(item2);
    pscene->addItem(item5);
    pscene->addItem(item6);
    this->setScene(pscene);

    /*3、移动——定时器*/
    time1 = new QTimer;
    connect(time1, SIGNAL(timeout()), pscene,SLOT(advance()));
    time1->start(1000);

    /*4、item1发送信号,不用两个定时器*/
    connect(item1, SIGNAL(itemCollding()), this,SLOT(itemMoveStopSlot()));
}
void animationView::itemMoveStopSlot()
{
/*方法一:用connect(item1, SIGNAL(itemCollding()), this,SLOT(itemMoveStopSlot()));*/
    time1->stop();
    delete this->item1;
    delete this->item2;
    item3 = new MyItem(":/love.png",3,false);
    pscene->addItem(item3);//中间显示出玫瑰花
    item3->setPos(180,120);
}

附方法二:利用两个定时器

 

 注:实现过程可能出现bug:

 解决步骤:

  1. 重新写图元类class(继承QObject、QGraphicsItem,包含Q_OBJECT宏)
  2. 构建中点击qmake
  3. 重新构建

 

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ze言

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值