使用 QML 播放动画 SVG

问题描述 投票:0回答:3

我想用 QML 播放动画 SVG 文件。我已经尝试过

AnimatedImage
,但 SVG 保持静态并且不是动画。

AnimatedImage {
      id: loader
      source: "qrc:/Assets/Images/loader"
      height: 30
      width: 30
}

如有任何建议,我们将不胜感激,谢谢。

qt svg qml
3个回答
2
投票

检查支持的动画格式列表:

http://doc.qt.io/qt-5/qml-qtquick-animatedimage.html#details

http://doc.qt.io/qt-5/qmovie.html#supportedFormats

因此,在您的

qDebug
中添加一行
main.cpp

#include <QDebug>
#include <QMovie>
// ...
qDebug() << "Supported animated file formats:" << QMovie::supportedFormats();

如果

QMovie
不支持,你可能需要依赖
QSvgRenderer
:

http://doc.qt.io/qt-5/qsvgrenderer.html#details

http://doc.qt.io/qt-5/qsvgrenderer.html#animated

希望有帮助。


1
投票

虽然我找不到纯粹在 QML 中执行此操作的方法,但我让它可以与 C++ 中定义的自定义 QML 类型一起使用,如此处所述。

import Svg 1.0

    Svg{
        width:50
        height:50
        file: ":/res/icons/spinning.svg"
    }

在 C++ 中

//svg.h
class Svg : public QQuickPaintedItem {
    Q_OBJECT
    Q_PROPERTY(QString file READ file WRITE setFile NOTIFY fileChanged)
    QML_ELEMENT

   public:
    explicit Svg(QQuickItem* parent = 0);
    void paint(QPainter* painter) override;
    const QString& file();

   public slots:
    void setFile(const QString& filepath);

   signals:
    void fileChanged(const QString& filepath);

   private:
    QSvgRenderer* m_renderer;
    QTimer* m_timer;
    QString m_path;
    int m_refreshRate;
};

// svg.cpp
#include <svg.h>

Svg::Svg(QQuickItem *parent) : QQuickPaintedItem(parent) {
    m_refreshRate = 1 / 60 * 1000;  // 60hz
    setAntialiasing(true);

    m_timer = new QTimer{this};
    connect(m_timer, &QTimer::timeout, [this] {
        if (m_renderer->isValid()) {
            update(boundingRect().toRect());
        }
    });        
}

void Svg::paint(QPainter *painter) { m_renderer->render(painter); }

const QString &Svg::file() { return m_path; }

void Svg::setFile(const QString &path) {
    m_path = path;
    m_renderer = new QSvgRenderer(path, this);
    emit fileChanged(path);
    m_timer->start(m_refreshRate);
}

在.pro文件中添加以下内容:

QT += svg
CONFIG += qmltypes
QML_IMPORT_NAME = Svg
QML_IMPORT_MAJOR_VERSION = 1

0
投票

我想使用 .svg 生成的动画而不是 .gif 来显示动画。我使用基于前面答案中显示的代码的代码,但图像看起来是静态的并且不会移动。有必要以某种方式设置它吗?

//svg.h
    class Svg : public QQuickPaintedItem {
    Q_OBJECT
    Q_PROPERTY(QString file READ file WRITE setFile NOTIFY fileChanged)
public:
    explicit Svg(QQuickItem* parent = nullptr);
    void paint(QPainter* painter) override;
    const QString& file();
public slots:
    void setFile(const QString& filepath);
signals:
    void fileChanged(const QString& filepath);
private:
    QSvgRenderer* m_renderer;
    QString m_file;
};

//svg.c
Svg::Svg(QQuickItem* parent) : QQuickPaintedItem(parent) {
    m_renderer = new QSvgRenderer(this);
}

void Svg::paint(QPainter* painter) {
    if (m_renderer->isValid()) {
        m_renderer->render(painter);
    }
}

const QString& Svg::file() {
    return m_file;
}

void Svg::setFile(const QString& filepath) {
    if (m_file != filepath) {
        m_file = filepath;
        m_renderer->load(filepath);
        emit fileChanged(filepath);
        update();
    }
}

// main.cpp

qmlRegisterType<Svg>("Svg", 1, 0, "Svg");

//myanimation.qml

import Svg 1.0

        Svg{
            height: 200
            width: 200
            file: "animation.svg"
        }
© www.soinside.com 2019 - 2024. All rights reserved.