您的位置:首页 > 新闻 > 会展 > 百度关键词优化外包_绵阳高端网站建设_网络推广竞价是什么_seo网站推广实例

百度关键词优化外包_绵阳高端网站建设_网络推广竞价是什么_seo网站推广实例

2025/6/8 14:31:16 来源:https://blog.csdn.net/2401_86112944/article/details/148380183  浏览:    关键词:百度关键词优化外包_绵阳高端网站建设_网络推广竞价是什么_seo网站推广实例
百度关键词优化外包_绵阳高端网站建设_网络推广竞价是什么_seo网站推广实例

文章目录

  • 源码地址,环境:QT5.15,MinGW32
  • 实现思路
  • 先创建两个窗口
  • 把界面添加进QStackWidget
  • 翻转按钮被点击
    • 翻转效果实现类
    • 动画效果
    • 动画播放过程

源码地址,环境:QT5.15,MinGW32

实现思路

翻转动画持续时间
QPropertyAnimation::setDuration(700);
翻转动画起始值
QPropertyAnimation::setStartValue(m_startVal);
翻转动画结束值
QPropertyAnimation::setEndValue(m_endVal);

通过这三个值计算出动画执行过程的一个中间值 iRotateVal

按照这个中间值去播放相应的画面
比如

  • 当旋转角度在0到90度之间时,绘制当前页面(即当前显示的页面),并绕Y轴旋转iRotateVal角度的画面
  • 当旋转角度在90到180度之间时,绘制下一个页面(m_nextPageIndex),并绕Y轴旋转iRotateVal+180度的画面
  • 当旋转角度在-180度到-90度之间时,同样绘制下一个页面,并绕Y轴旋转iRotateVal+180度的画面
  • 当旋转角度在-90度到0度之间时,绘制当前页面,并绕Y轴旋转iRotateVal度的画面

连续的不同角度的图像的绘制就形成了动画

然后翻转的两个画面作为两个窗口放到QStackedWidget里,当动画播放结束以后直接重绘窗口界面

先创建两个窗口

一样的方法
在这里插入图片描述

Page01::Page01(QWidget *parent) :QWidget(parent),ui(new Ui::Page01)
{ui->setupUi(this);
}Page01::~Page01()
{delete ui;
}void Page01::paintEvent(QPaintEvent *event)
{QPainter p(this);QPixmap pix(":/images/1.png");p.drawPixmap(QRect(0,0,500,500),pix);}void Page01::on_pushButton_clicked()
{//点击然后翻转到页面2//发送信号出去emit page01Clicked();
}
class Page01 : public QWidget
{Q_OBJECTpublic:explicit Page01(QWidget *parent = 0);~Page01();signals:void page01Clicked();protected:void paintEvent(QPaintEvent *event);private slots:void on_pushButton_clicked();private:Ui::Page01 *ui;
};

把界面添加进QStackWidget

	AnimationStackedWidget* m_asw;QHBoxLayout *layout = new QHBoxLayout();layout->setContentsMargins(0,0,0,0);m_asw = new AnimationStackedWidget(this);m_page01 = new Page01(this); // AnimationStackedWidget中的第一页m_page02 = new Page02(this); // AnimationStackedWidget中的第二页m_asw->addWidget(m_page01);m_asw->addWidget(m_page02);QObject::connect(m_page01, &Page01::page01Clicked, this, &AnimationDialog::onPage01Clicked);QObject::connect(m_page02, &Page02::page02Clicked, this, &AnimationDialog::onPage02Clicked);layout->addWidget(m_asw);this->setLayout(layout);

翻转按钮被点击

翻转效果实现类

没有这一句无法实现动画播放效果
Q_PROPERTY(float rotateVal READ rotateVal WRITE setRotateVal)

class AnimationStackedWidget : public QStackedWidget
{Q_OBJECT//Qt提供的属性系统,独立于编译器和平台的库//Qt属性是基于元数据对象系统 信号和槽//需要用moc进行编译,需要继承QObjectQ_PROPERTY(float rotateVal READ rotateVal WRITE setRotateVal)//Q_PROPERTY 是 Qt 框架中用于声明类属性的宏,它允许对象属性在 Qt 的元对象系统中被暴露,//从而支持诸如属性动画、属性绑定、信号与槽机制等功能public:AnimationStackedWidget(QWidget *parent = 0);~AnimationStackedWidget();//动画效果void animation(int pageIndex);//动画更新过程中​​,rotateVal() ​​不会被自动调用​​,因为动画通过 setRotateVal() 直接写入值。
//读取属性值由​​开发者手动调用​​或​​框架初始阶段自动调用​​(如确认起始状态)。
//若未显式设置起始值(setStartValue()),动画会调用 rotateVal() 获取当前值作为起始点float rotateVal() {return iRotateVal;}void setRotateVal(float val) {iRotateVal = val;} //设置旋转值float startVal() {return m_startVal;}void setStartVal(float val) {m_startVal = val;}float endVal() {return m_endVal;}void setEndVal(float val) {m_endVal = val;}protected:void paintEvent(QPaintEvent *event);private slots:void onValueChanged(const QVariant &value);void onFinished();private:float iRotateVal;   //旋转值int m_startVal;     //动画起始值int m_endVal;       //动画结束值int m_nextPageIndex;    //下一页
};
void AnimationDialog::onPage01Clicked()
{m_asw->setStartVal(0);   //翻转的起始值m_asw->setEndVal(180);     //翻转的结束值//m_asw实现动画效果m_asw->animation(1);
}

动画效果

注意currentWidget()->hide();这一步很重要

void AnimationStackedWidget::animation(int pageIndex)
{m_nextPageIndex = pageIndex;//propertyNameQPropertyAnimation *animation = new QPropertyAnimation(this, "rotateVal");//设置动画持续时间animation->setDuration(700);//设置动画的缓动曲线为线性模式。缓动曲线控制着动画在执行过程中的速度变化,线性模式意味着动画会以恒定的速度进行animation->setEasingCurve(QEasingCurve::Linear);/*QEasingCurve::InQuad:加速运动QEasingCurve::OutQuad:减速运动QEasingCurve::InOutQuad:先加速后减速*///设置动画起始值//把 AnimationStackedWidget 里的setStartValue到 QPropertyAnimation 里animation->setStartValue(m_startVal);//设置动画结束值animation->setEndValue(m_endVal);//QPropertyAnimation::valueChanged 当属性动画在运行期间属性值"rotateVal"发生变化时QObject::connect(animation, &QPropertyAnimation::valueChanged, this, &AnimationStackedWidget::onValueChanged);QObject::connect(animation, &QPropertyAnimation::finished, this, &AnimationStackedWidget::onFinished);//堆叠窗口(QStackedWidget)默认情况下会显示当前部件//但是,在动画过程中,我们希望由我们自己来控制绘制,而不是让窗口系统自动绘制当前部件。currentWidget()->hide();//!!!/*
动画启动后​​:QPropertyAnimation 会根据预设的 ​​起始值​​、​​结束值​​、​​持续时间​​ 和 ​​缓动曲线​​(默认未设置时使用线性变化),生成中间值序列
*/animation->start();//非阻塞调用​​:这个调用会立即返回,不会等待动画完成//​​异步执行​​:实际的动画是在Qt事件循环中逐步执行的
}

动画播放过程

  1. 启动动画​​(animation->start()):
    未设置起始值则调用 rotateVal() 获取初始值。
  2. ​​每帧动画​​:
    QPropertyAnimation 每帧自动计算(基于时间、缓动曲线等)并通过 setRotateVal() 更新
  3. ​​调用 setRotateVal(val)​​ 更新 iRotateVal。
    ​​触发 valueChanged 信号​​ → 执行 onValueChanged 槽函数。
  4. ​​动画结束​​:
    触发 finished 信号 → 执行 onFinished 槽函数。

所以根据上面槽函数绑定情况可得

当计算出中间值iRotateVal以后就会自动调用 setRotateVal(),然后会触发onValueChanged,rapaint()会触发paintEvent()实现重绘

void AnimationStackedWidget::onValueChanged(const QVariant &value)
{//值改变了以后//立即强制重绘窗口部件。它会直接调用paintEvent()函数,不进行任何优化//如果在短时间内多次调用repaint(),会导致多次重绘,可能影响性能。repaint();//update();//标记窗口部件为 “需要重绘”,但不会立即执行。//Qt 会将重绘请求放入事件队列中,等到下一次事件循环时合并所有的重绘请求,然后只进行一次实际的重绘操作。//这样可以避免不必要的重复绘制,提高性能。
}

按照计算出的中间值绘制图像旋转各角度的画面

void AnimationStackedWidget::paintEvent(QPaintEvent *event)
{QPainter p(this);if (iRotateVal > 0 && iRotateVal <= 90) {
//当旋转角度在0到90度之间(不包括0,包括90)时,绘制当前页面(即当前显示的页面),并绕Y轴旋转iRotateVal角度QPixmap pix(currentWidget()->size());currentWidget()->render(&pix);//旋转QTransform transform;transform.translate(width()/2,0);transform.rotate(iRotateVal, Qt::YAxis);p.setTransform(transform);p.drawPixmap(-1*width()/2, 0,pix);} else if (iRotateVal > 90 && iRotateVal <= 180) {
//当旋转角度在90到180度之间(不包括90,包括180)时,绘制下一个页面(m_nextPageIndex),并绕Y轴旋转iRotateVal+180度QPixmap pix(widget(m_nextPageIndex)->size());widget(m_nextPageIndex)->render(&pix);//旋转QTransform transform;transform.translate(width()/2,0);transform.rotate(iRotateVal+180, Qt::YAxis);p.setTransform(transform);p.drawPixmap(-1*width()/2, 0,pix);}else if (iRotateVal > -180 && iRotateVal <= -90) {
//当旋转角度在-180度到-90度之间(不包括-180,包括-90)时,同样绘制下一个页面,并绕Y轴旋转iRotateVal+180度QPixmap pix(widget(m_nextPageIndex)->size());widget(m_nextPageIndex)->render(&pix);//旋转QTransform transform;transform.translate(width()/2,0);transform.rotate(iRotateVal+180, Qt::YAxis);p.setTransform(transform);p.drawPixmap(-1*width()/2, 0,pix);} else if (iRotateVal > -90 && iRotateVal < 0) {
//当旋转角度在-90度到0度之间(不包括0,包括-90)时,绘制当前页面,并绕Y轴旋转iRotateVal度QPixmap pix(currentWidget()->size());currentWidget()->render(&pix);//旋转QTransform transform;transform.translate(width()/2,0);transform.rotate(iRotateVal, Qt::YAxis);p.setTransform(transform);p.drawPixmap(-1*width()/2, 0,pix);}}

动画播放结束后直接设置QStackWidget的另一个界面

void AnimationStackedWidget::onFinished()
{//动画结束widget(m_nextPageIndex)->show();//用于将指定的 QWidget 控件提升到其父窗口控件的最前面显示widget(m_nextPageIndex)->raise();setCurrentWidget(widget(m_nextPageIndex));
}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com