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 <QObject>
#include <QGraphicsItem>
#include <QPainter>
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 <QObject>
#include <QGraphicsItem>
#include <QPainter>
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 <QMainWindow>
#include <QGraphicsScene>
#include <QGraphicsView>
#include <QMenuBar>
#include <QGraphicsEllipseItem>

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 <QGraphicsItemAnimation>
#include <QTimeLine>
#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<QGraphicsItem*>  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<QPoint> v;
     v<< QPoint(30,-15) <<QPoint(0,-30)<<QPoint(-30,-15)
     <<QPoint(-30,15)<<QPoint(0,30)<<QPoint(30,15);

    QGraphicsPolygonItem *item=new QGraphicsPolygonItem(QPolygonF(v));
    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::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);

}





效果:

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
QGraphicsView是一个用于显示和编辑大型和复杂的二维图形的类,它是Qt的一个重要组件。它提供了一个可视化的视图窗口,其可以放置QGraphicsItem,并允许用户对这些物品进行操作。 QGraphicsView类提供了许多功能,使得在图形场景进行交互变得更加容易。通过使用QGraphicsScene类作为场景的模型,可以将各种QGraphicsItem对象添加到场景。场景然后可以通过QGraphicsView显示出来。 使用QGraphicsView的好处包括: 1. 支持平移和缩放:QGraphicsView支持对场景进行平移和缩放操作,可以通过鼠标或触摸手势来轻松地在场景导航和缩放。 2. 支持图形项选择:QGraphicsView提供了一些方法来选择场景的图形项,可以将选项高亮显示,并可以对其进行移动、删除等操作。 3. 支持渲染和交互:QGraphicsView可以根据需要重新绘制场景,并捕获用户的交互行为,例如鼠标点击、拖动等。 4. 支持多种视图模式:QGraphicsView提供了几种视图模式,可以进行不同方式的显示,例如普通视图模式、缓存视图模式和OpenGL视图模式等。 5. 提供了自定义功能:QGraphicsView允许用户通过继承和重写其方法来实现自定义的行为和外观,以满足特定的需求。 QGraphicsView是一个功能丰富而强大的类,它为开发者提供了许多工具和方法来处理和显示二维图形。无论是创建绘图应用程序还是设计交互式界面,QGraphicsView都是一个非常有用的类。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值