我创建了一个基于Qt 5.2的QML应用程序,我在Mac OS X和Windows(从XP到8)上部署它。我的应用程序有一个主要动画,它无限旋转一个图像,同时用户正在直播。这个动画是应用程序的核心部分,我不能将其删除。
旋转图像需要太多的CPU功率,我正在寻找解决方法。原因是许多用户不支持OpenGL 2(在Windows上),我将不得不依靠MESA的DLL在软件中进行渲染,使应用程序在这些机器上无法使用,而动画正在运行。
以下是我的当前QML动画实现方式:
我尝试的第一个解决方案是创建一个包含所有动画帧的大精灵,然后用AnimatedSprite加载它。这减少了CPU使用率,但显然还不够,并且将RAM消耗增加了三倍以上,高达300MB。对于旧的Windows XP机器来说,这不是一个好的解决方案。
我还尝试了子类化QQuickPaintedItem,并手动每30ms调用
有没有办法改善这个问题并减少旋转动画的 CPU 使用率?
编辑: 当然,我可以更改动画或者不使用动画,但这并不是长期解决方案。最终,这张图片将需要动态绘制/更新以反映音量计并表示声音级别。因此,我需要找到一个适当的解决方案,允许我实时更新 QML 视图的一部分,而无需重新绘制整个 UI 并占用大量 CPU。
编辑2: 我发现主要的 CPU 使用率不是旋转本身,而是每次必须重新绘制整个 UI。您可以通过在 paint() 函数中调用 return 而不是旋转任何内容来确保这一点。这样做与对图像本身进行动画处理时的 CPU 使用率相同,这表明问题来自于每次更新场景中的一个 QML 组件时更新整个 UI。
旋转图像需要太多的CPU功率,我正在寻找解决方法。原因是许多用户不支持OpenGL 2(在Windows上),我将不得不依靠MESA的DLL在软件中进行渲染,使应用程序在这些机器上无法使用,而动画正在运行。
以下是我的当前QML动画实现方式:
Image {
id: imgBroadcastState
source: "images/broadcast_button.png"
anchors.horizontalCenter: parent.horizontalCenter
NumberAnimation on rotation {
from: 0
to: 360
running: rootWindow.isBroadcasting
loops: Animation.Infinite
duration: 7000
onRunningChanged:{
if(!running) {
imgBroadcastState.rotation = 0;
}
}
}
}
我尝试的第一个解决方案是创建一个包含所有动画帧的大精灵,然后用AnimatedSprite加载它。这减少了CPU使用率,但显然还不够,并且将RAM消耗增加了三倍以上,高达300MB。对于旧的Windows XP机器来说,这不是一个好的解决方案。
我还尝试了子类化QQuickPaintedItem,并手动每30ms调用
paint()
(使用QTimer
)来旋转图像。这也减少了CPU使用率,但仍然不够。以下是我使用的代码:void MXPaintedItem::paint(QPainter *painter)
{
QTransform rot;
rot.rotate(m_angle);
painter->setRenderHint(QPainter::Antialiasing);
painter->setRenderHint(QPainter::SmoothPixmapTransform);
painter->translate(width() / 2, height() / 2);
painter->rotate(m_angle);
// Use preloaded QImage
painter->drawImage(QPoint(-width() / 2, -height() / 2), m_image);
m_angle += 2.5;
}
有没有办法改善这个问题并减少旋转动画的 CPU 使用率?
编辑: 当然,我可以更改动画或者不使用动画,但这并不是长期解决方案。最终,这张图片将需要动态绘制/更新以反映音量计并表示声音级别。因此,我需要找到一个适当的解决方案,允许我实时更新 QML 视图的一部分,而无需重新绘制整个 UI 并占用大量 CPU。
编辑2: 我发现主要的 CPU 使用率不是旋转本身,而是每次必须重新绘制整个 UI。您可以通过在 paint() 函数中调用 return 而不是旋转任何内容来确保这一点。这样做与对图像本身进行动画处理时的 CPU 使用率相同,这表明问题来自于每次更新场景中的一个 QML 组件时更新整个 UI。