IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> 游戏开发 -> QT属性动画--设置样式属性(其他属性) -> 正文阅读

[游戏开发]QT属性动画--设置样式属性(其他属性)

故事背景

??最近在制作一个按钮切换的动画特效中接触了属性动画这部分内容,并由此产生了一些思考。
切换按钮动画
??开始也是不会使用 QPropertyAnimation 这个类,然后就在网上查资料总算是完成自己想要的效果了,但是发现了一个问题,网上我查到的资料在介绍使用QPropertyAnimation类时都是只使用 geometry 这一个属性。

          porpAnim->setPropertyName("geometry");

??这就令我很奇怪了,按理说这个QPropertyAnimation(属性动画)应该可以控制很多属性的,为什么大家都知识介绍这一个属性,以这个为契机,我开始研究如何进行样式动画属性.

遇到的问题

??既然是设置样式动画属性,那属性肯定不是geometry了,我们需要到头文件里面看看。我这里要设置的控件是QPushButton,我们可以直接去它的基类QWidget里面看样式属性。可以看到属性名称是styleSheet,是一个QString类型变量。

             Q_PROPERTY(QString styleSheet READ styleSheet WRITE setStyleSheet)

??接着仿照设置geometry来设置styleSheet。我是想着设置btn_A按钮的背景颜色进行一个由黑变白的动画效果。但是很遗憾,这样的操作并不奏效。于是我去网上找相关的资料,希望可以找到一点线索。

    QPropertyAnimation *animation = new QPropertyAnimation(ui->btn_A, "styleSheet");
    animation->setDuration(100);
    animation->setStartValue(QString("background-color:#000000"));
    animation->setEndValue(QString("background-color:#ffffff"));
    animation->start();

解决过程

??在网上转了一圈,还是没有找到什么好的方法,于是我决定自己来看看到底怎么解决这个问题。首先我想到的是可能是我传入setStartValue的值不对,既然是样式属性,那么传入的参数应该是样式表这样的字符串吧,于是我进行了如下修改。为了能看到明显变化,我在界面的构造函数中还设置btn_A按钮的样式表为红色。但还是生效。

#include "mainwindow.h"
#include "ui_mainwindow.h"

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setStyleSheet("#btn_A{ background-color:red} ");  //首先设置样式表
}

MainWindow::~MainWindow()
{
    delete ui;
}



void MainWindow::on_btn_B_clicked()
{
    QPropertyAnimation *animation = new QPropertyAnimation(ui->btn_A, "styleSheet");
    animation->setDuration(100);
    animation->setStartValue(QString("QPushButton{ background-color:#000000} "));     //这里是我的改动
    animation->setEndValue(QString("QPushButton{ background-color:#ffffff} "));
    animation->start();

}

失败1

??接着我又试了几种其他传入的参数,都不行,这让我一度陷入绝望。难道属性动画只能是修改geometry这一个属性吗?实在没有想法了我就去Qt Helper看看。
??看完了QPropertyAnimation这个类之后,没什么收获,接着我就又去它的父类QVariantAnimation去看看。果然皇天不负有心人,我还是找到了一些东西

Not all QVariant types are supported. Below is a list of currently supported QVariant types:
Int
UInt
Double
Float
QLine
QLineF
QPoint
QPointF
QSize
QSizeF
QRect
QRectF
QColor
If you need to interpolate other variant types, including custom types, you have to implement interpolation for these yourself. To do this, you can register an interpolator function for a given type. This function takes 3 parameters: the start value, the end value, and the current progress.
Example:

      QVariant myColorInterpolator(const QColor &start, const QColor &end, qreal progress)
      {
          ...
          return QColor(...);
      }
      ...
      qRegisterAnimationInterpolator<QColor>(myColorInterpolator);

Another option is to reimplement interpolated(), which returns interpolation values for the value being interpolated.

??上面这段话的意思是,目前支持的属性变量的类型是Int UInt Double Float QLine QLineF QPoint QPointF QSize QSizeF QRect QRectF QColor。没有QString,这也解释了为什么我上面传入的参数是无效的。不过Qt也为我们提供了设置其他类型的方法。类如注册动画属性qRegisterAnimationInterpolator(myColorInterpolator);(这个函数是可以自定义的),还有一个是重新实现 interpolated(),我决定试一下第一种方法。

最终方法

??下面说一下我是怎么用的,mySheetStyle函数是要注册使用的,这里我先没有使用传入的参数,是自己在函数中造了一些值,progress这个值就是一个进度从0到1,所以我设置的rgb颜色会随着进度改变。然后返回一个QString样式,效果如下。由于对颜色渐变值设置的原因,颜色变化不是很明显,但是绝对变化了。mySheetStyle函数中的逻辑可以依照自己的需要来改变。

QVariant mySheetStyle(const QString & start, const QString & end, qreal progress)
{
    int red   = (int)(40 * progress) + 50;
    int green = (int)(50 * progress) + 50;
    int blue  = (int)(200 * progress) + 50;

    QString style = QString("background-color: rgb(%1,%2,%3)").arg(red).arg(green).arg(blue);
    qDebug()<<"style = "<<style;
    return style;
}

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    this->setStyleSheet("#btn_A{ background-color:red} ");
    qRegisterAnimationInterpolator<QString>(mySheetStyle);   //这里进行了注册
}

void MainWindow::on_btn_B_clicked()
{
    QPropertyAnimation *animation = new QPropertyAnimation(ui->btn_A, "styleSheet");
    animation->setDuration(1000);
    animation->setStartValue(QString("QPushButton{ background-color:#000000} "));   //这里的值目前没有使用
    animation->setEndValue(QString("QPushButton{ background-color:#ffffff} "));
    animation->start();
}

成功1

总结

??大家需要注意的是,setStartValue传入的参数类型、qRegisterAnimationInterpolator(myColorInterpolator)最后设定类型、需要一致,并且类型需要和你设置的属性匹配。比如我设置的是styleSheet属性,它对应的变量类型是QString,所以上述的参数类型都是QString,换成其他类型是没有动画效果的。
??另外,关于上面我返回的样式字符串,为什么我没有指定选择器按钮也更改了,可能是因为创建属性动画对象时已经选择了控件

new QPropertyAnimation(ui->btn_A, "styleSheet");

??当然加上选择器也可以生效,但要注意前后设置的控件要保持一致性。

QString style = QString("background-color: rgb(%1,%2,%3)").arg(red).arg(green).arg(blue);

QString style = QString("#btn_A { background-color: rgb(%1,%2,%3)} ").arg(red).arg(green).arg(blue);
  游戏开发 最新文章
6、英飞凌-AURIX-TC3XX: PWM实验之使用 GT
泛型自动装箱
CubeMax添加Rtthread操作系统 组件STM32F10
python多线程编程:如何优雅地关闭线程
数据类型隐式转换导致的阻塞
WebAPi实现多文件上传,并附带参数
from origin ‘null‘ has been blocked by
UE4 蓝图调用C++函数(附带项目工程)
Unity学习笔记(一)结构体的简单理解与应用
【Memory As a Programming Concept in C a
上一篇文章      下一篇文章      查看所有文章
加:2022-03-06 13:29:43  更:2022-03-06 13:30:59 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/27 16:27:59-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码