前言
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