我仔细阅读了文档以及可以在Internet上找到的所有内容,但是似乎无法从C ++访问QML图像。
有办法解决这个问题吗?
在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
因此不同图像的字符串是相同的,从而导致QML Image组件无法更新,但是该解决方案就像在分配新像素图之后删除旧像素图一样简单。这是实际的图像提供程序:
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中使用它的方式:
Pixmap {
id: pix
}
Image {
source: pix.data
}
// and then pix.load(path)
还请注意,在我的情况下,没有在QML中需要更新的像素图的实际修改。如果在C ++中更改了图像,此解决方案将不会自动更新QML中的图像,因为内存中的地址将保持不变。但是,解决方案非常简单-实现update()
分配方法的方法new QPixmap(oldPixmap)
-它将使用相同的内部数据,但是会为您提供带有新内存地址的新访问器,这将触发QML映像进行更改更新。这意味着提供访问pixmap的方法将通过Pixmap
该类,而不是直接通过,QPixmap *
因为您将需要Pixmap
该类来触发data
更改,因此只需为添加一个访问器pix
,以防万一您执行复杂或线程化的操作,想要使用QImage
而是添加一个互斥锁,以便在C ++或其他方式下更改基础数据时,在QML中不会更改基础数据。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句