QT 定时器与动画实现

前言
Qt提供图形视图框架(Graphics View Framework)、动画框架(The Animation Framework)和状态机框架(The State Machine Framework)来实现更加高级的图形和动画应用。使用这些框架可以快速设计出动态GUI应用程序和各种动画、游戏程序。

问题

怎样运用定时器和图形框架来做一个简单的动画呢?

探索
Qt 是基于C++的gui类库的开发平台工具,当然制作动画和游戏是完全可以实现的。但对初学者来说掌握这些框架需要一定的学习周期。不过编程软件的学习,本质上是一个不断练习,实践的过程。创意+编程=动画或者游戏,应该是一件十分有趣的事情。

图形视图框架重在理解。场景,视图,图形项还有坐标体系和事件机制。只有搞清楚这些对象,才能运用自如。

下面来看下实现的过程。
主函数main()中通过创设场景,放置图形项,然后通过视图来显示。


#include"myitem.h"
#include"myview.h"


#include <QApplication>
#include<QGraphicsScene>
#include<QGraphicsRectItem>
#include<QDebug>
#include<QTransform>
#include<QGraphicsView>
#include <QTime>

int main(int argc, char *argv[])
{

    QApplication a(argc, argv);
    
    //引用随机数
    qsrand(QTime(0, 0, 0).secsTo(QTime::currentTime()));
    //创建场景对象
    QGraphicsScene scene;
    //设置场景大小
    scene.setSceneRect(-200, -150, 400, 300);
    for(int i = 0; i < 5; ++i) {
        MyItem *item = new MyItem;
        item->setColor(QColor(qrand() % 256, qrand() % 256, qrand() % 256));
        item->setPos(i * 50 - 90, -50);
        scene.addItem(item);
    }

    //创建视图
    QGraphicsView view;
    view.setScene(&scene);
    //设置场景的前景色
    view.setForegroundBrush(QColor(255,255,0,100));
    //设置场景的背景图片
    view.setBackgroundBrush(QPixmap("../graph_03/background.png"));
    //穿件视图大小并显示
    view.resize(500,400);
    view.show();
    
    return a.exec();
}

添加一个myItem类来实现图形项。最重要的是添加定时器事件。

#include "myitem.h"
#include<QPainter>
#include<QTimerEvent>

#include <QCursor>
#include <QKeyEvent>
#include <QGraphicsSceneHoverEvent>
#include <QGraphicsSceneContextMenuEvent>
#include <QMenu>
#include<QtMath>


#include<QDebug>

MyItem::MyItem()
{
    brushColor = Qt::red;
    //初始化定时器功能
     startTimer(1000);

    setFlag(QGraphicsItem::ItemIsFocusable);
    setFlag(QGraphicsItem::ItemIsMovable);
    setAcceptHoverEvents(true);
}



//重载boundingRect()函数来绘制矩形
QRectF MyItem::boundingRect() const
{
    qreal adjust = 0.5;
    return QRectF(-10 - adjust, -10 - adjust,
                  20 + adjust, 20 + adjust);
}

//重载paint()函数实现填充
void MyItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option,
                   QWidget *widget)
{
    if(hasFocus()) {
        painter->setPen(QPen(QColor(255,255,255,200)));
    } else {
        painter->setPen(QPen(QColor(100,100,100,100)));
    }
    painter->setBrush(brushColor);
    painter->drawRect(-10, -10, 20, 20);
}


// 鼠标按下事件处理函数,设置被点击的图形项获得焦点,并改变光标外观
void MyItem::mousePressEvent(QGraphicsSceneMouseEvent *event)
{
    setFocus();
    setCursor(Qt::ClosedHandCursor);
}

// 键盘按下事件处理函数,判断是否是向下方向键,如果是,则向下移动图形项
void MyItem::keyPressEvent(QKeyEvent *event)
{
    if(event->key() == Qt::Key_Down)
        moveBy(0, 10);
}

// 悬停事件处理函数,设置光标外观和提示
void MyItem::hoverEnterEvent(QGraphicsSceneHoverEvent *event)
{
    setCursor(Qt::OpenHandCursor);
    setToolTip("I am item");
}

// 右键菜单事件处理函数,为图形项添加一个右键菜单
void MyItem::contextMenuEvent(QGraphicsSceneContextMenuEvent *event)
{
    QMenu menu;
    QAction *moveAction = menu.addAction("move back");
    QAction *selectedAction = menu.exec(event->screenPos());
    if(selectedAction == moveAction) {
        setPos(0, 0);
    }
}


void MyItem:: timerEvent(QTimerEvent *timeevent)
{
    qDebug()<<"timer1";
    angle +=(qrand()%10)/20.0;
    qreal dx = sin(angle)*50.0 + (qrand()%10)*(qrand()%10)*10;
    qreal dy = cos(angle)*50.0 + (qrand()%10)*10;

    qDebug()<<"dx :"<<dx <<endl;

    setPos(dx,dy);

}

#ifndef MYITEM_H
#define MYITEM_H

#include <QGraphicsItem>
#include <QObject>

class MyItem : public QObject,public QGraphicsItem
{
      Q_OBJECT
public:
    MyItem();
    QRectF boundingRect() const;
    void paint(QPainter *painter,const QStyleOptionGraphicsItem *option,
               QWidget *QWidget);

    void setColor(const QColor &color) { brushColor = color; }

protected:
    void keyPressEvent(QKeyEvent *event);
    void mousePressEvent(QGraphicsSceneMouseEvent *event);
    void hoverEnterEvent(QGraphicsSceneHoverEvent *event);
    void contextMenuEvent(QGraphicsSceneContextMenuEvent *event);

     void timerEvent(QTimerEvent *timeevent);

private:
  int id1;
  QColor brushColor;

  bool up;
      QPixmap pix_up;
      QPixmap pix_down;

      qreal angle;


};

#endif // MYITEM_H

ok!效果马上出来了。小方块就会在图中随机运动了。就是这么简单。

在这里插入图片描述
资源链接:
https://download.csdn.net/download/qq_21291397/12197372

原创文章 41 获赞 0 访问量 2048

猜你喜欢

转载自blog.csdn.net/qq_21291397/article/details/104544941