我查看了文档以及我在互联网上找到的任何内容,但似乎无法从C ++访问QML图像。
有办法解决这个问题吗?
答案 0 :(得分:8)
可以在QtQuick1中执行,但在QtQuick2中删除了该功能。
我提出的解决方案允许在QML和C ++中使用QQuickImageProvider
来生成相同的图像,该QPixmap *
基本上与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
data
元素的实现非常简单,虽然初始有点受限,因为新的pixmap恰好分配在完全相同的内存地址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();
}
}
};
字符串是相同的不同的图像,导致QML图像组件不更新,但解决方案就像在分配新的pixmap之后删除旧的pixmap一样简单。这是实际的图像提供者:
//in main()
engine.addImageProvider("pixmap", new PixmapProvider);
qmlRegisterType<Pixmap>("Test", 1, 0, "Pixmap");
注册:
Pixmap {
id: pix
}
Image {
source: pix.data
}
// and then pix.load(path)
这就是你在QML中使用它的方式:
update()
另请注意,在我的情况下,没有实际修改需要在QML中更新的像素图。如果在C ++中更改了图像,则此解决方案不会自动更新QML中的图像,因为内存中的地址将保持不变。但是对此的解决方案同样简单 - 实现一个分配new QPixmap(oldPixmap)
的{{1}}方法 - 它将使用相同的内部数据,但会为您提供一个带有新内存地址的新访问器,触发QML图像以更新更新。这意味着访问pixmap的提供方法将通过Pixmap
类,而不是直接来自QPixmap *
,因为您需要Pixmap
类来触发data
更改,所以只需为pix
添加一个访问器,以防你做复杂或线程化的东西,你可能想要使用QImage
代替并添加一个互斥锁,这样底层数据就不会在QML中被改变了用C ++或其他方式改变了。