当前位置 博文首页 > fearlazy:Qt实现图片翻转(开源)
?
一、思路
? ?????使用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();
????????}
????}
}
?
点击查看原文