QGraphicsView QGraphicsItem 实例5

通过实现:一个在其中显示各种类型QGraphicsItem的窗口例子,介绍如何使用Qt预定义的各种标准的QGraphicsItem类型(如QGraphicsEllipseItem、QGraphicsRectItem等),以及自定义的QGraphicsItem类型(如本例中不停闪烁的圆及来回移动的星星等)来创建图元。

QTimeLine类提供用于控制动画的时间表,通常用于定期调用插槽来为GUI控件创建动画。简单来说,就是可以通过 QTimeLine 来快速的实现动画效果,其原理就是在指定的时间内发出固定帧率的信号,通过连接该信号去改变目标控件的值,由于时间断帧率高,所以整体看起来就是连续的动画效果。
以上说得可能有些抽象,下面结合实例和用法步骤来看看。

用法
将使用步骤总结为以下几点:1.创建 QTimeLine对象的时候传入时间值,单位是毫秒,该时间就是动画运行的时间;
2.设置帧率范围,通过setFrameRange()进行设置,该值表示在规定的时间内将要执行多少帧;
3.连接frameChanged()信号,并在槽中对需要实现动画的控件进行赋值,如QProgressBar的setValue().
4.调用 start()开始执行时间轴动作。

例如:

progressBar = new QProgressBar(this);
progressBar->setRange(0, 100);
progressBar->move(100,100);

// Construct a 1-second timeline with a frame range of 0 - 100
QTimeLine *timeLine = new QTimeLine(1000, this);
timeLine->setFrameRange(0, 100);
connect(timeLine, SIGNAL(frameChanged(int)), progressBar, SLOT(setValue(int)));

// Clicking the push button will start the progress bar animation
QPushButton * pushButton = new QPushButton(tr("Start animation"), this);
connect(pushButton, SIGNAL(clicked()), timeLine, SLOT(start()));

当 QTimeLine调用 start()后将进入运行状态,并会发出frameChanged()信号,而连接该信号的槽中将会不断的对目标控件进行相应的动作赋值,从而实现动画效果。

可以通过调用setUpdateInterval()来指定更新间隔。完成后,QTimeLine进入NotRunning状态,并发出finished().

默认情况下,时间轴从开始到结束运行一次,此时必须再次调用start()才能从头开始重新启动。要进行时间线循环,您可以调用setLoopCount(),并在完成之前传递时间轴应该运行的次数。

通过调用setDirection(),方向也可以改变,可以让时间线向后运行。

也可以通过调用setPaused()来暂停和取消暂停时间轴的运行。

对于交互式控件,提供了setCurrentTime()函数,该函数直接设置时间线的时间位置。

原文链接:https://blog.csdn.net/luoyayun361/article/details/80381984

图元的动画显示有江中两种方式可以实现:

1.利用 QGraphicsItemAnimation类和QTimLine类实现 。如本例中圆是闪烁功能的实现

2.在图元类中利用定时器QTimer和图元的重画函数paint()实现。如本例中星星不停的左右移动

flash.h

#ifndef FLASH_H
#define FLASH_H
#include 
#include 
#include 
class Flash : public QObject,public QGraphicsItem
{
    Q_OBJECT
public:
    explicit Flash(QObject *parent = nullptr);


    QRectF boundingRect() const;      //图元边界函数,完成以图元坐标系为基础,增加两个像素点的冗余工作
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) ;
    void timerEvent(QTimerEvent *);

private:
    bool flash;
    QTimer *timer;

signals:

};

#endif // FLASH_H

flash.cpp

#include "flash.h"

Flash::Flash(QObject *parent) : QObject(parent)
{
   flash=true;
   setFlag(ItemIsMovable);
   startTimer(1000);

}

QRectF Flash::boundingRect() const   //图元边界函数,完成以图元坐标系为基础,增加两个像素点的冗余工作
{
    qreal adjuct=2;
    return QRectF(-10-adjuct,-10-adjuct,43+adjuct,43+adjuct);
}

void Flash::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->setPen(Qt::NoPen);          //闪烁图元的阴影区不绘制边线
    painter->setBrush(Qt::darkGray);     //闪烁图元的阴影区的阴影画刷颜色为深灰
    painter->drawEllipse(-7,-7,40,40);    //绘制阴影区
    painter->setPen(QPen(Qt::black,0));         //闪烁区的椭圆边线颜色为黑色,线宽为0

    painter->setBrush(flash?(Qt::red):(Qt::yellow));
    //设置闪烁区的椭圆画刷颜色根据颜色切换标识flash决定填充哪一种颜色,颜色在红色和黄色之间选择
    painter->drawEllipse(-10,-10,40,40);     //绘制与阴影区同样大小的椭圆,并错开一定的距离实现立体效果

}

void Flash::timerEvent(QTimerEvent *)  //定时器响应闪烁效果
{
    flash=!flash;
    update();
}

startItem.h

#ifndef STARTITEM_H
#define STARTITEM_H

#include 
#include 
#include 
class StartItem : public QObject
{
    Q_OBJECT
public:
    explicit StartItem(QObject *parent = nullptr);


    QRectF boundingRect() const;      //图元边界函数
    void paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget = nullptr) ;
    StartItem();

private:
    QPixmap pix;


signals:

};

#endif // STARTITEM_H

startItem.cpp

#include "startitem.h"

StartItem::StartItem(QObject *parent) : QObject(parent)
{
}

StartItem::StartItem()
{
    pix.load(":/new/images/star.png");

}

QRectF StartItem::boundingRect() const
{
    return QRectF (-pix.width()/2,-pix.height()/2,pix.width(),pix.width());
}

void StartItem::paint(QPainter *painter, const QStyleOptionGraphicsItem *option, QWidget *widget)
{
    painter->drawPixmap(boundingRect().topLeft(),pix);
}

mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include 
#include 
#include 
#include 
#include 

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

    void  initScene();      //初始化场景
    void  createAction();   //创建主窗体的所有动作
    void  createMenus();    //创建主窗体的菜单栏

private:
    QGraphicsScene *scene;
    QAction *act_New;
    QAction *act_Clear;
    QAction *act_exit;
    QAction *act_addEllipseItem;
    QAction *act_addPolygonItem;
    QAction *act_addTextItem;
    QAction *act_addRectItem;
    QAction *act_addAlphaItem;
    QAction *act_addflashItem;
    QAction *act_addAnimItem;


public slots:
      void   slotNew();                //新建一个显示窗体
      void   slotClear();               //清除场景中所有的图元
      void   slotAddEllipseItem();      //在场景中加入一个椭圆形图元
      void   slotAddPolygonItem();      //在场景中加入一个多边形形图元
      void   slotAddTextItem();         //在场景中加入一个文字图元
      void   slotAddRectItem();       //在场景中加入一个长方形形图元
      void   slotAddAlphaItem();      //在场景中加入一个透明蝴蝶图片
      void   slotAddFlashItem();      //在场景中加入一个闪烁图元
      void   slotAddAnimationItem();       //在场景中加入一个动画星星
};
#endif // MAINWINDOW_H

mainwindow.cpp

#include "mainwindow.h"
#include "flash.h"
#include 
#include 
#include "startitem.h"
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
{
    createAction();              //创建主窗体的所有动作
    createMenus();               //创建主窗体的菜单栏

    scene=new QGraphicsScene;
    scene->setSceneRect(-200,-200,400,400);
    initScene();

    QGraphicsView *view=new QGraphicsView;
    view->setScene(scene);
    view->setMinimumSize(400,400);
    view->show();
    setCentralWidget(view);

    setWindowTitle(QStringLiteral("Graphics Items"));
}

MainWindow::~MainWindow()
{
}


void MainWindow::createAction()    //创建主窗体的所有动作
{
    act_New=new QAction(QStringLiteral("新建"),this);
    act_Clear=new QAction(QStringLiteral("清除"),this);
    act_exit=new QAction(QStringLiteral("退出"),this);
    act_addEllipseItem=new QAction(QStringLiteral("加入 椭圆"),this);
    act_addPolygonItem=new QAction(QStringLiteral("加入 多边形"),this);
    act_addTextItem=new QAction(QStringLiteral("加入 文字"),this);
    act_addRectItem=new QAction(QStringLiteral("加入 长方形"),this);
    act_addAlphaItem=new QAction(QStringLiteral("加入 透明图片"),this);
    act_addflashItem=new QAction(QStringLiteral("加入 闪烁圆"),this);
    act_addAnimItem=new QAction(QStringLiteral("加入 星星"),this);

    connect(act_New,SIGNAL(triggered()),this,SLOT(slotNew()));
    connect(act_Clear,SIGNAL(triggered()),this,SLOT(slotClear()));
    connect(act_exit,SIGNAL(triggered()),this,SLOT(close()));
    connect(act_addEllipseItem,SIGNAL(triggered()),this,SLOT(slotAddEllipseItem()));
    connect(act_addPolygonItem,SIGNAL(triggered()),this,SLOT(slotAddPolygonItem()));
    connect(act_addTextItem,SIGNAL(triggered()),this,SLOT(slotAddTextItem()));
    connect(act_addRectItem,SIGNAL(triggered()),this,SLOT(slotAddRectItem()));
    connect(act_addAlphaItem,SIGNAL(triggered()),this,SLOT(slotAddAlphaItem()));
    connect(act_addflashItem,SIGNAL(triggered()),this,SLOT(slotAddFlashItem()));
    connect(act_addAnimItem,SIGNAL(triggered()),this,SLOT(slotAddAnimationItem()));
}

void MainWindow::createMenus()    //创建主窗体的菜单栏
{
    QMenu *fileMenu=menuBar()->addMenu(QStringLiteral("文件"));
    fileMenu->addAction(act_New);
    fileMenu->addAction(act_Clear);
    fileMenu->addSeparator();
    fileMenu->addAction(act_exit);

    QMenu *itemMenu=menuBar()->addMenu(QStringLiteral("元素"));
    itemMenu->addAction(act_addEllipseItem);
    itemMenu->addAction(act_addPolygonItem);
    itemMenu->addAction(act_addTextItem);
    itemMenu->addAction(act_addRectItem);
    itemMenu->addAction(act_addAlphaItem);
    itemMenu->addAction(act_addflashItem);
    itemMenu->addAction(act_addAnimItem);
}

void MainWindow::initScene()   //初始化场景
{
    int i;
    for(i=0;i<3;i++)
       slotAddEllipseItem();
    for(i=0;i<3;i++)
        slotAddPolygonItem();
    for(i=0;i<3;i++)
        slotAddTextItem();
    for(i=0;i<3;i++)
        slotAddRectItem();
    for(i=0;i<3;i++)
        slotAddAlphaItem();
    for(i=0;i<3;i++)
        slotAddFlashItem();
    for(i=0;i<3;i++)
        slotAddAnimationItem();
}


void MainWindow::slotClear()     //清除场景中所有的图元
{
    QList  listItem =scene->items();
    while(!listItem.empty())
    {
        scene->removeItem(listItem.at(0));
        listItem.removeAt(0);
    }
}


void MainWindow::slotNew()     //新建一个显示窗体
{
    slotClear();
    initScene();
    MainWindow *newWin=new MainWindow;
    newWin->show();

}

void MainWindow::slotAddEllipseItem()    //在场景中加入一个椭圆形图元
{
    QGraphicsEllipseItem *item=new QGraphicsEllipseItem(QRectF (0,0,80,60));
    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)
            );

}

void MainWindow::slotAddPolygonItem()  //在场景中加入一个多边形形图元
{
    QVector v;
     v<< QPoint(30,-15) <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)
            );
}

void MainWindow::slotAddTextItem()   //在场景中加入一个文字图元
{
   QFont font("Times",16);
   QGraphicsTextItem *item = new QGraphicsTextItem("Hello Qt");
   item->setFont(font);
   item->setDefaultTextColor(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)
           );


}

void MainWindow::slotAddRectItem()  //在场景中加入一个长方形形图元
{
    QGraphicsRectItem *item=new QGraphicsRectItem(QRectF(0,0,60,50));
    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)
            );

}

void MainWindow::slotAddAlphaItem()  //在场景中加入一个透明蝴蝶图片
{
    QGraphicsPixmapItem *item =scene->addPixmap(QPixmap(":/new/images/image.png"));
    item->setFlag(QGraphicsItem::ItemIsMovable);
    item->setPos((qrand()%int(scene->sceneRect().width())-200),
                   ((qrand()%int(scene->sceneRect().height()))-200)
            );

}

void MainWindow::slotAddFlashItem() //在场景中加入一个闪烁图元
{
    Flash *item=new Flash;
    scene->addItem(item);
    item->setPos((qrand()%int(scene->sceneRect().width())-200),
                   ((qrand()%int(scene->sceneRect().height()))-200)
            );

}

void MainWindow::slotAddAnimationItem()  //在场景中加入一个动画星星
{
    StartItem *item=new StartItem;


    QTimeLine *timeLine=new QTimeLine(4000);
    timeLine->setCurveShape(QTimeLine::SineCurve);
    timeLine->setLoopCount(0);


    QGraphicsItemAnimation *anim=new QGraphicsItemAnimation;
    anim->setItem(item);
    anim->setTimeLine(timeLine);

    int y=(qrand()%400)-200;
    for(int i=0;i<400;i++)
    {
        anim->setPosAt(i/400.0,QPointF(i-200,y));
       // void setPosAt(qreal step, const QPointF &pos);
    }
    timeLine->start();
    scene->addItem(item);

}





效果:

QGraphicsView QGraphicsItem 实例5_第1张图片

 

你可能感兴趣的:(qt)