我创建了一个类Publisher
,它定期发出QImage
个对象。
但是我很难将QImage
绘制到QML元素上。看来Image
和Canvas
QML组件需要QUrl
而不是QImage
,但我不确定如何将QImage
转换为QUrl
QQuickImageProvider
。编辑4:当我说QUrl时,我并不是说我正在尝试将图像转换为URL。那是胡说八道。我的意思是我要生成对此映像的引用,该映像不在磁盘上,而QML组件要求的数据类型是URL。
我做了一些研究,发现QImage
提供了一个解决方案,但我没有找到任何解释如何将QUrl
信号转换为class Publisher
{
Q_OBJECT
public:
Publisher(QObject* parent = 0);
virtual ~Publisher(void);
Q_SIGNALS:
void newImage(const QImage& newImage);
};
的文档用于绘图。任何示例代码或参考文档将不胜感激。
感谢您的帮助!
EDIT1:
我在这里看了一下:http://qt-project.org/doc/qt-5.0/qtquick/qquickimageprovider.html我没看到如何将QImage传递给快速图像提供程序,并从中创建一个QUrl。
EDIT2。这是标题。实施应该不重要。
int main(int argc, char *argv[])
{
QGuiApplication app(argc, argv);
qmlRegisterType<Publisher>("Components", 1, 0, "Publisher");
QtQuick2ApplicationViewer viewer;
viewer.setMainQmlFile(QStringLiteral("qml/QQuickViewExample/main.qml"));
viewer.showExpanded();
return app.exec();
}
编辑3.这是我的QML代码,但我不知道如何绘制我的QImage,所以这段代码毫无意义。
我的main.cpp文件:
import QtQuick 2.0
import Components 1.0
Rectangle {
id : testRect
width: 360
height: 360
Image{
anchors.fill: parent
id: myImage
Publisher {
id: myPub
onNewImage: {
myImage.source = newImage; #I know this doesnt work, it needs a QUrl and not a QImage
}
}
}
}
我的main.qml文件:
{{1}}
答案 0 :(得分:36)
换句话说,你有一个类发出一个携带QImage的信号,并希望用该图像更新QML中的项目?有各种解决方案,其中没有一个涉及“将QImage转换为QUrl”(无论这意味着,当然您不需要获取带有图像数据的data
URL ...)
这意味着您可以在QML文件中使用普通的Image
项。
QQuickImageProvider
子类;给它一个QImage
成员(提供者的图像),覆盖requestImage
以提供该图像(请求的实际id
并不重要,见下文),以及接收一个QImage
并更新该成员。Publisher
信号连接到提供商的广告位QQmlEngine::addImageProvider
将提供者安装到QML引擎中(参见QQuickView::engine
);再次id
并不重要,只需使用合理的在QML中,只需使用带有此类
的源的普通Image
元素
Image {
id: myImage
source: "image://providerIdPassedToAddImageProvider/foobar"
}
foobar
将传递给您的提供商,但同样,这并不重要。
我们几乎就在那里,我们现在只需要一种方法推送图像更新到QML世界(否则Image永远不知道何时更新自己)。有关如何使用Connections
元素和一些JS执行此操作,请参阅my answer here。
请注意,通常您不需要使Publisher
成为QML类型,您只需要在C ++中创建一个实例并通过{{1将其公开给QML世界}}
QQmlContext::setContextProperty
可能是最方便的工作,因为它提供了采用QQuickPaintedItem
的{{1}}方法。因此,重大计划是
paint
:子类存储要绘制的QPainter
,并且有一个设置新QImage的插槽。此外,其QQuickPaintedItem
实现仅使用QImage
绘制图像。paint
将子类暴露给QML世界(以便您可以在QML中使用它)找出将携带新图像的信号连接到项目插槽的方法。
这可能是棘手的部分。
要在C ++中执行连接,您需要一种方法来确定项目是否已创建(并获取指向它的指针);通常通过将QPainter::drawImage
属性赋值给某个值,然后在根对象上使用qmlRegisterType
(由objectName
返回)来获取指向项本身的指针。然后你可以像往常一样使用findChild
。
或,可以通过QML世界中发布者C ++对象上的QQuickView::rootObject()
元素在QML中执行连接,如上所述:
connect
无论何时创建MyItem实例,这都具有工作优势;但我不能100%确定它会起作用,因为我不确定你能否在QML中处理Connections
类型。
答案 1 :(得分:3)
当我有想要嵌入QML的图像生成C ++类时,我总是通过使C ++类成为QDeclarativeItem
的子类来实现它(将会有一个新的QtQuick 2.0)相当于当然),用适当的绘图代码覆盖paint方法,这可能就像
void MyItem::paint(QPainter* painter,const QStyleOptionGraphicsItem*,QWidget*) {
painter->drawImage(QPointF(0.0f,0.0f),_image);
}
如果你已经有一个正确尺寸的QImage ......和Job Done。对于动画,只要在绘制新内容时ping update()。
答案 2 :(得分:0)
使用QQuickItem。有一个Qt示例可以做到这一点。
C:\ Qt \ Examples \ Qt-5.14.1 \ quick \ scenegraph \ threadedanimation
您创建一个派生自QQuickItem的类,并使用qmlRegisterType注册它。 在您的类中提供覆盖函数'updatePaintNode'。在示例中,类为“ Spinner”
在updatePaintNode中:
创建从QObject和QSGTransformNode派生的节点类
在节点类构造函数中:
使用createTextureFromImage将Qimage转换为QSGTexture。
创建QSGSimpleTextureNode,使用setTexture设置QSGTexture
appendChildNode与QSGSimpleTextureNode
在QML中添加
import Spinner 1.0
和
Spinner {
anchors.centerIn: parent
anchors.horizontalCenterOffset: 80
spinning: true
}
答案 3 :(得分:0)
QString getImage()
{
QByteArray byteArray;
QBuffer buffer(&byteArray);
buffer.open(QIODevice::WriteOnly);
img.save(&buffer,"JPEG");
//save image data in string
QString image("data:image/jpg;base64,");
image.append(QString::fromLatin1(byteArray.toBase64().data()));
return image;
}
将图像字符串直接发送到qml源