Qt实现图片翻转(开源)

2018-05-02 21:45:21  阅读 289 次 评论 2 条

flipimgf.gif

 作者:fearlazy。 有需要该源码的加微信fearlazy_com发私信。


一、思路

       使用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();
        }
    }
}


本文地址:http://fearlazy.com/index.php/post/71.html
版权声明:本文为原创文章,版权归 fearlazy 所有,欢迎分享本文,转载请保留出处!

发表评论


表情

评论列表

  1. a
    a  @回复

    不错,不错啊,有点意思

  2. www.mjquan.com
    www.mjquan.com  @回复

    挺好的,用了代码测试了下 ,还不错的