当前位置 博文首页 > fearlazy:Qt实现图片翻转(开源)

    fearlazy:Qt实现图片翻转(开源)

    作者:[db:作者] 时间:2021-06-18 21:10

    flipimgf.gif

    ?

    一、思路

    ? ?????使用Qt的Graphics View Framework可以非常容易实现翻转的效果。该框架中的item可以通过设置QGraphicsRotation实现沿x轴、y轴和z轴(垂直于屏幕)方向上的旋转。再配合上动画便能达到上图的效果。

    ?

    二、关键代码

    ????1.既然是基于图形视图框架,那view是必不可少的。从基类中派生出我们的视图类FlipView:

    ??FlipView?:?public?QGraphicsView
    

    ???? 在这个demo中视图和场景都不是主角。场景无需做其他设置,视图也只是做了一些简单的设置即可。

    FlipView::FlipView(QWidget?*parent):QGraphicsView(parent)
    {
    ????//场景
    ????m_pScne?=?new?QGraphicsScene();
    ????this->setScene(m_pScne);
    
    ????//item
    ????m_picture?=?new?Picture();
    ????m_pScne->addItem(m_picture);
    
    ????//设置
    ????setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);
    ????setVerticalScrollBarPolicy(Qt::ScrollBarAlwaysOff);??
    ????setViewportUpdateMode(FullViewportUpdate);???//刷新方式
    ????setCacheMode(CacheBackground);
    ????setRenderHints(QPainter::Antialiasing
    ???????????????????|?QPainter::SmoothPixmapTransform
    ???????????????????|?QPainter::TextAntialiasing);
    }
    
    void?FlipView::drawBackground(QPainter?*painter,?const?QRectF?&rect)
    {
    ????//重写drawBackground函数绘制视图的背景
    ????painter->drawPixmap(rect,QPixmap(":/back.jpg"),QRectF());
    }
    
    void?FlipView::resizeEvent(QResizeEvent?*event)
    {
    ????//在视图大小变化时,让Item填充视图(缩放)
    ????fitInView(m_picture,?Qt::KeepAspectRatioByExpanding);
    }
    

    ????2.demo的主角,图片Item从QGraphicsObject中派生,其主要成员变量如下:

    class?Picture?:?public?QGraphicsObject
    
    ???//主要成员变量:
    ????QList<QPixmap>??????????????m_pixmaplist;?????//图片列表
    ????int?????????????????????????m_index;??????????//当前显示的图片的下标
    ????QPropertyAnimation*?????????m_roateAnimation;?//m_itemRotation的动画?
    ????QParallelAnimationGroup*????m_animationGroup;?//并行动画组,包括m_rotateAnimation和item的缩放动画
    ????QGraphicsRotation*??????????m_itemRotation;???//旋转
    

    ????在构造函数中做设置变换:

    Picture::Picture(QGraphicsItem?*parent):QGraphicsObject(parent)
    {
    ????//初始化
    ????m_pixmaplist.append(QPixmap(":/01.jpg"));
    ????m_pixmaplist.append(QPixmap(":/02.jpg"));
    ????m_index?=?0;
    ????m_bChanged?=?false;
    
    ????//设置该item的变换
    ????m_itemRotation?=?new?QGraphicsRotation(this);
    ????m_itemRotation->setAxis(Qt::YAxis);?//沿Y轴旋转
    ????m_itemRotation->setOrigin(QVector3D(boundingRect().width()/2,0,0));?//旋转基准位置为item的中心线
    ????this->setTransformations(QList<QGraphicsTransform?*>()<<m_itemRotation);//<--关键-->
    
    ????//动画效果
    ????m_roateAnimation?=?new?QPropertyAnimation(m_itemRotation,?"angle");?//动画与m_itemRotation绑定
    ????m_roateAnimation->setDuration(1500);
    ????connect(m_roateAnimation,SIGNAL(finished()),this,SLOT(animationFinished()));
    ????connect(m_roateAnimation,SIGNAL(valueChanged(QVariant)),this,SLOT(animationValueChanged(QVariant)));
    
    ????QPropertyAnimation*?scaleAnimation?=?new?QPropertyAnimation(this,"scale");?//辅助效果,让item翻转的时候先缩小再放大
    ????scaleAnimation->setDuration(1500);
    ????scaleAnimation->setStartValue(1);
    ????scaleAnimation->setKeyValueAt(0.5,0.3);
    ????scaleAnimation->setEndValue(1);
    ????setTransformOriginPoint(this->boundingRect().center());
    
    ????m_animationGroup?=?new?QParallelAnimationGroup(this);
    ????m_animationGroup->addAnimation(m_roateAnimation);
    ????m_animationGroup->addAnimation(scaleAnimation);
    }
    

    ????在构造函数中的设置已经能够实现图片的翻转效果,为了让翻转效果更逼真,我们在旋转到90度左右(图片与屏幕垂直)时换一张图片显示,好像两张图片刚好是正反两面。

    ????在旋转动画的槽函数中进行判断:

    void?Picture::animationValueChanged(const?QVariant?&value){
    ????if(!m_bChanged){
    ????????if(value.toDouble()?>=?90?-?2?&&?value.toDouble()?<=?90?+?2){?//旋转角度约在90度左右时切换当前图片下标
    ????????????if(++m_index?>=?m_pixmaplist.count()){
    ????????????????m_index?=?0;
    ????????????}
    ????????????m_bChanged?=?true;?//一次旋转动画只需要判断一次是否到90度即可。
    ????????????update();
    ????????}
    ????}
    }

    ?

    点击查看原文

    下一篇:没有了