QML和C ++映像互操作性 [英] QML and C++ image interoperability

查看:206
本文介绍了QML和C ++映像互操作性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经浏览过文档以及在互联网上找到的任何内容,但它似乎不可能从C ++访问QML图像。

I've looked through the documentation and also whatever I could find on the internet, but it doesn't seem like it is possible to access a QML Image from C++.

有办法解决这个问题吗?

Is there a way to work around that?

推荐答案

这是可能在QtQuick1, QtQuick2。

It was possible to do in QtQuick1 but that functionality was removed in QtQuick2.

我想出的解决方案允许在QML和C ++中实现相同的图像通过实现 QQuickImageProvider 基本上与 QPixmap * ,它被转换为字符串,然后回到一个指针类型(它听起来有点不安全,但已证明工作很好)。 / p>

The solution I've come up with allows to have the same image in QML and C++ by implementing a QQuickImageProvider that basically works with QPixmap * which is converted to string and then back to a pointer type(it does sound a little unsafe but has proven to work quite well).

class Pixmap : public QObject {
    Q_OBJECT
    Q_PROPERTY(QString data READ data NOTIFY dataChanged)
public:
    Pixmap(QObject * p = 0) : QObject(p), pix(0) {}
    ~Pixmap() { if (pix) delete pix; }

    QString data() {
        if (pix) return "image://pixmap/" + QString::number((qulonglong)pix);
        else return QString();
    }

public slots:
    void load(QString url) {
        QPixmap * old = 0;
        if (pix) old = pix;
        pix = new QPixmap(url);
        emit dataChanged();
        if (old) delete old;
    }

    void clear() {
        if (pix) delete pix;
        pix = 0;
        emit dataChanged();
    }

signals:
    void dataChanged();

private:
    QPixmap * pix;
};

Pixmap 元素的实现非常漂亮直接,虽然初始有点有限,由于新的pixmap偶然被分配在完全相同的存储器地址, data 字符串对于不同的图像是相同的,导致QML图像组件不更新,但解决方案就像删除旧的像素映射只有在新的一个已经分配后。这是实际的图像提供程序:

The implementation of the Pixmap element is pretty straightforward, although the initial was a bit limited, since the new pixmap happened to be allocated at the exactly same memory address the data string was the same for different images, causing the QML Image component to not update, but the solution was as simple as deleting the old pixmap only after the new one has been allocated. Here is the actual image provider:

class PixmapProvider : public QQuickImageProvider {
public:
    PixmapProvider() : QQuickImageProvider(QQuickImageProvider::Pixmap) {}
    QPixmap requestPixmap(const QString &id, QSize *size, const QSize &requestedSize) {
        qulonglong d = id.toULongLong();
        if (d) {
            QPixmap * p = reinterpret_cast<QPixmap *>(d);
            return *p;
        } else {
            return QPixmap();
        }
    }
};

注册:

//in main()
engine.addImageProvider("pixmap", new PixmapProvider);
qmlRegisterType<Pixmap>("Test", 1, 0, "Pixmap");

这是你如何在QML中使用它:

And this is how you use it in QML:

Pixmap {
    id: pix
}

Image {
    source: pix.data
}

// and then pix.load(path)

在我的情况下,没有实际修改的像素图,需要在QML中更新。如果在C ++中更改,此解决方案不会自动更新QML中的图像,因为内存中的地址将保持不变。但是这个解决方案也很简单 - 实现一个更新()方法分配一个新的QPixmap(oldPixmap) - 它将使用相同的内部数据,但是给你一个新的访问器,它有一个新的内存地址,这将触发QML镜像更新更改。这意味着访问像素图的提示方法将通过 Pixmap 类,而不是直接从 QPixmap * 将需要 Pixmap 类来触发数据更改,因此只需添加 pix ,并且为了防止你做复杂的或线程的东西,你可能想使用 QImage ,并添加一个互斥体,使底层数据不是在CML中改变,或者以其他方式改变。

ALSO Note that in my case there was no actual modification of the pixmap that needed to be updated in QML. This solution will not auto-update the image in QML if it is changed in C++, because the address in memory will stay the same. But the solution for this is just as straightforward - implement an update() method that allocates a new QPixmap(oldPixmap) - it will use the same internal data but give you a new accessor to it with a new memory address, which will trigger the QML image to update on changes. This means the proffered method to access the pixmap will be through the Pixmap class, not directly from the QPixmap * since you will need the Pixmap class to trigger the data change, so just add an accessor for pix, and just in case you do complex or threaded stuff, you might want to use QImage instead and add a mutex so that the underlying data is not changed in QML while being changed in C++ or the other way around.

这篇关于QML和C ++映像互操作性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆