3

大多数熟悉 QML 的人都知道,QML 中没有内置的“刷新”功能Image

我想创建一个新的 QML 类型,比如说RefreshableImage在不改变源代码的情况下缓解这个问题,我觉得这是一个丑陋的 hack,因为它渗透到模型 - 视图关系的所有层并且这种切换行为是不自然的。此外,source在 an 上设置不同的值Image会破坏任何可能已设置的绑定(这实际上是问题的核心:我想要一个可更新的图像来维护其绑定,并且与 QML 隔离)。我知道我需要调用一些信号来实际刷新图像,这很好。

我很难找到有关扩展 Qt 自己的方法的文档,Image以便我可以强制它重新加载其源代码。我想避免编写一个完整的组件,该组件大部分都很难复制Image以添加一个功能。有没有办法像我想的那样扩展内置组件?

小提示:

  • 由于外部情况,我仅限于 Qt 5.5。
  • 我们使用source底层图像对象的 UUIDQQuickImageProvider来获取实际的QImage. 因此,我不想在更新图像时更改它。
4

2 回答 2

3

您可以创建一种RefreshableImage类型来隐藏丑陋的来源。

有一种简单的方法是为 source 引入一个新属性:

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用作属性,则可以使用一些别名恶作剧来做到这一点。由于别名仅在组件完全初始化后才被激活,因此您可以覆盖的source属性,Image但仍然可以访问底层的属性。

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属性

于 2016-12-16T10:59:48.700 回答
0

一个粗略的骨架,用于直接使用带有自定义项目的模型中的 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()在实际内容可用时发出信号。

于 2016-12-19T10:56:37.253 回答