使用更新功能扩展QML图像类型

Extend QML Image type with an update function

本文关键字:QML 图像 类型 扩展 新功能 更新      更新时间:2023-10-16

正如大多数熟悉QML知道的人,QML Image中没有内置的"刷新"功能。

我想创建一种新的QML类型,例如RefreshableImage来减轻此问题而不诉诸于更改源头,我觉得这是一个丑陋的骇客,因为它将其渗入了模型视图的所有层次,并且这种切换行为是不自然的。此外,在Image上设置不同的source会破坏可能已设置的任何绑定(这实际上是问题的核心:我想要一个可更新的图像来维护其绑定,并将其隔离到QML)。我知道我需要调用一些信号以实际刷新图像,这很好。

我在扩展QT自己的Image的方法上很难找到文档,以便我可以强迫它重新加载其源。我想避免编写一个完整的组件,该组件大多重复Image添加一个功能。是否有一种方法可以像我想到的那样扩展内置组件?

小笔记:

  • 由于外部情况,我仅限于QT 5.5。
  • 我们用作基础图像对象的 source a uuid,该对象被 QQuickImageProvider用于获取实际的 QImage。因此,我不想在更新图像时更改此内容。

您可以创建一个 RefreshableImage类型,该类型隐藏了丑陋的源。

通过为源引入新属性:

有一种简单的方法
import QtQuick 2.0
Image {
    id: root
    property string refreshableSource
    source: refreshableSource
    function refresh() {
        source = "";
        source = Qt.binding(function() { return refreshableSource });
    }
}

您必须这样使用:RefreshableImage { refreshableSource: "image.jpg" }

如果您仍然想将source用作属性,则可以使用一些别名Shenanigans进行。由于仅在完全初始化组件后才激活别名,因此您可以覆盖sourceImage属性,但仍然可以访问基础。

import QtQuick 2.0
Image {
    id: root
    property alias actualUnderlyingSource: root.source //this refers to Image.source and not the newly created source alias
    property alias source: root.refreshableSource
    property string refreshableSource
    actualUnderlyingSource: refreshableSource
    function refresh() {
        actualUnderlyingSource = "";
        actualUnderlyingSource = Qt.binding(function() { return refreshableSource });
    }
}

然后您可以像RefreshableImage { source: "image.jpg" }一样使用它,这实际上将修改refreshableSource属性

一个粗糙的骨架,用于直接使用自定义项目的模型中的qimage

class DirectImage : public QQuickPaintedItem
{
    Q_OBJECT
    Q_PROPERTY(QImage image READ image WRITE setImage NOTIFY imageChanged)
public:
    void paint(QPainter *painer);
    void setImage(const QImage &image);
};
void DirectImage::paint(QPainter *painter)
{
    painter->drawImage(m_image.scaled(width(), height()):
}
void DirectImage::setImage(const QImage &image)
{
    m_image = image;
    emit imageChanged();
    setImplicitWidth(image.width());
    setImplicitHeight(image.height());
    update();
}

通过

注册
qmlRegisterType<DirectImage>("MyElements", 1, 0, "RefreshableImage");

通过

使用
import MyElements 1.0
// ...
RefreshableImage {
    image: model.image
}

当询问图像角色时,模型只会返回QImage,每当图像变化时,都会发出带有图像角色的dataChanged()信号。

如果需要根据需要生成图像,则该模型可以首先返回空图像或占位符图像并在可用的实际内容时发射dataChanged()信号。