Qt动画类实例一
来源:互联网 发布:mac用vmware 编辑:程序博客网 时间:2024/06/14 10:22
一、简述
前段时间群里小伙伴想写个自定义的控件,二话不说,我就答应帮他写了,结果一拖就拖到了今天。实现起来很简单,简单应用了动画类的效果就OK了。主要是对窗口的pos及新增了一个cornerOpacity属性做了动画处理,实现了窗口在鼠标进出时左右滑动,以及四个边框角的忽隐忽现效果。
图一为Qt动画实现效果:
图二为小伙伴提供要实现的效果:
二、代码之路
#include "AnimationTest.h"#include <QLabel>#include <QPushButton>#include <QHBoxLayout>#include <QVBoxLayout>#include <QPainter>#include <QDebug>#define CORNER_WIDTH 20 // 拐角边框宽度;#define CORNER_HEIGHT 6 // 拐角边框高度;AnimationTest::AnimationTest(QWidget *parent) : QWidget(parent){ initTopWidget(); this->setWindowIcon(QIcon(":/AnimationTest/Resources/icon.jpg")); this->setProperty("cornerOpacity", 0.0); this->setWindowFlags(Qt::FramelessWindowHint); this->setStyleSheet("QWidget{background:white;} \ QPushButton{background:rgb(14, 150, 254);border:none;color:white;font-size:18px;font-weight:bold;}\ QPushButton:hover{background:rgb(44, 137, 255);}\ QPushButton:pressed{background:rgb(14, 135, 228);padding-top:3px;padding-left:3px;}\ "); this->setFixedSize(QSize(370, 370));}// 初始化顶层Widget;void AnimationTest::initTopWidget(){ m_backWidget = new QLabel(this); m_backWidget->setObjectName("BackWidget"); m_backWidget->setFixedSize(QSize(350, 350)); m_backWidget->setPixmap(QPixmap(":/AnimationTest/Resources/backImage.jpg").scaled(m_backWidget->width(), m_backWidget->height())); m_topWidget = new QWidget(m_backWidget); m_topWidget->setFixedSize(QSize(350, 350)); m_topWidget->move(QPoint(-m_topWidget->width(), 0)); m_moveAnimation = new QPropertyAnimation(m_topWidget, "pos"); m_moveAnimation->setDuration(300); m_moveAnimation->setStartValue(QPoint(-m_topWidget->width(), 0)); m_moveAnimation->setEndValue(QPoint(0, 0)); m_opcityAnimation = new QPropertyAnimation(this, "cornerOpacity"); m_opcityAnimation->setDuration(300); m_opcityAnimation->setStartValue(0); m_opcityAnimation->setEndValue(1.0); connect(m_opcityAnimation, SIGNAL(valueChanged(const QVariant&)), this, SLOT(update())); QLabel* topWidgetInfo = new QLabel; topWidgetInfo->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding); topWidgetInfo->setPixmap(QPixmap(":/AnimationTest/Resources/labelInfo.png")); QPushButton* pButtonPreview = new QPushButton(QStringLiteral("预览")); pButtonPreview->setFixedSize(QSize(100, 50)); QPushButton* pButtonDownloadJPG = new QPushButton(QStringLiteral("下载JPG")); pButtonDownloadJPG->setFixedSize(QSize(100, 50)); QPushButton* pButtonDownloadPNG = new QPushButton(QStringLiteral("下载PNG")); pButtonDownloadPNG->setFixedSize(QSize(100, 50)); QHBoxLayout* hLayoutLabel = new QHBoxLayout; hLayoutLabel->addStretch(); hLayoutLabel->addWidget(topWidgetInfo); hLayoutLabel->addStretch(); hLayoutLabel->setMargin(0); QHBoxLayout* hLayoutButton = new QHBoxLayout; hLayoutButton->addStretch(); hLayoutButton->addWidget(pButtonPreview); hLayoutButton->addWidget(pButtonDownloadJPG); hLayoutButton->addWidget(pButtonDownloadPNG); hLayoutButton->addStretch(); hLayoutButton->setSpacing(6); hLayoutButton->setMargin(0); QVBoxLayout* vLayout = new QVBoxLayout(m_topWidget); vLayout->addLayout(hLayoutLabel); vLayout->addLayout(hLayoutButton); vLayout->setMargin(0); vLayout->setSpacing(0); QHBoxLayout* mainLayout = new QHBoxLayout(this); mainLayout->addWidget(m_backWidget); mainLayout->setMargin(10);}// 进入离开事件;// 主要进行动画的操作;void AnimationTest::leaveEvent(QEvent *event){ m_moveAnimation->setStartValue(QPoint(0, 0)); m_moveAnimation->setEndValue(QPoint(m_topWidget->width(), 0)); // 注掉以上两行代码使用下面代码则收缩往相反方向; // 使用以上两行代码则窗口收缩往相同方向;// m_moveAnimation->setDirection(QAbstractAnimation::Backward); m_moveAnimation->start(); m_opcityAnimation->setDirection(QAbstractAnimation::Backward); m_opcityAnimation->start();}void AnimationTest::enterEvent(QEvent *event){ m_moveAnimation->setStartValue(QPoint(-m_topWidget->width(), 0)); m_moveAnimation->setEndValue(QPoint(0, 0)); // 注掉以上两行代码使用下面代码则收缩往相反方向; // 使用以上两行代码则窗口收缩往相同方向;// m_moveAnimation->setDirection(QAbstractAnimation::Forward); m_moveAnimation->start(); m_opcityAnimation->setDirection(QAbstractAnimation::Forward); m_opcityAnimation->start();}// 绘制事件,主要绘制四角的边框;void AnimationTest::paintEvent(QPaintEvent *event){ Q_UNUSED(event); QPainter painter(this); // 左上角; drawCorner(&painter, QPoint(0, 0), 0); // 右上角; drawCorner(&painter, QPoint(this->width(), 0), 90); // 右下角; drawCorner(&painter, QPoint(this->width(), this->height()), 180); // 左下角; drawCorner(&painter, QPoint(0, this->height()), -90);}// 绘制单个角的边框;void AnimationTest::drawCorner(QPainter* painter, QPoint pos, int translateAngle){ painter->save(); // 通过角度,位置转换进行绘制四个角的边框; int transparentValue = 255 * this->property("cornerOpacity").toFloat(); QBrush rectBrush(QColor(30, 150, 230, transparentValue)); painter->translate(pos); painter->rotate(translateAngle); painter->fillRect(QRect(0, 0, CORNER_WIDTH, CORNER_HEIGHT), rectBrush); painter->fillRect(QRect(0, 0 + CORNER_HEIGHT, CORNER_HEIGHT, CORNER_WIDTH - CORNER_HEIGHT), rectBrush); painter->restore();}
代码很简单,创建了两个动画类对象实现了以上效果,通过QPropertyAnimation 动画类我们可以实现更多好玩的效果,关键还是在于尝试。
下面简单介绍一下几个常用的动画类方法。
// 设置动画持续效果;
void setDuration(int msecs)
// 控制动画的变化曲线;
void setEasingCurve(const QEasingCurve & easing)
下面可以看到几个枚举值代表着变化的不同趋势。
// 设置动画的起始值;
void setStartValue(const QVariant & value)// 设置动画的结束值;
void setEndValue(const QVariant & value)
上面两个是对应起来的,就拿上面移动位置举例,把widget从位置1移动到位置2,那么位置1就是起始值,位置2就是结束值(解释的挺2的)。
当然单纯这样的话我们可以通过时钟来把widget从位置1移动到位置2,效果也是一样的,不过简单的时钟的效果可能只能实现下面这种曲线效果。更复杂的可能相对麻烦,所以直接用动画类方便、快捷。
// 开始/结束 动画效果
void start(QAbstractAnimation::DeletionPolicy policy = KeepWhenStopped)void stop()
下面为start()方法的参数,也就是动画结束之后是否删除该对象。
尾
以上写了一个简单的小例子以及简单地介绍了一下动画类,更多的在于大家的尝试。
晚安哈 O(∩_∩)O!
代码下载
Qt动画类实例一
- Qt动画类实例一
- 一个qt 动画 实例
- Qt 动画详解一
- Qt 动画详解一
- Qt 动画详解一
- Android动画实例 (一)
- 详解Qt的动画框架(一)
- shader实例(一)UV动画
- 浅析Android动画(一) View动画高级实例探究
- 【实例】Qt之文本编辑(一)
- QT动画特效类使用
- qt 利用多张图片做成动画实例
- Qt动画
- QT动画
- Qt动画
- QT动画
- Qt中MainWindow类实例
- QT 滑动效果之 Qt动画组的简单使用(一)
- Android四大组件之Activity总结
- jquery取值,赋值,以及下拉框获取选中value值
- NanoPi K2 (Amlogic 905) 底层硬件分析
- matplotlib命令与格式:设置栅格,axes脊柱(坐标轴),背景颜色
- JVM原理浅谈分析
- Qt动画类实例一
- mybatis之大于、小于等写法
- HDU2054
- 关于xib的加载
- vue实战中遇到的`坑`
- 回环网卡驱动
- 《高性能MySQL》 第一章(并发控制、事务、存储引擎)
- JVM原理浅谈(2)
- 网页直播、微信直播技术解决方案:EasyNVR与EasyDSS流媒体服务器组合之区分不同场景下的easynvr