Ответ 1
Другими словами, у вас есть класс, излучающий сигнал, несущий QImage, и хотите обновить элемент в QML с этим изображением? Существуют различные решения, ни одна из которых не включает в себя "преобразование QImage в QUrl" (независимо от того, что это означает, конечно, вам не нужно получать URL data
, несущий ваши данные изображения...)
Использование поставщика изображений
Это означает, что вы можете использовать простой Image
элемент в ваших файлах QML.
- Создайте подкласс
QQuickImageProvider
; дать ему элементQImage
(изображение для провайдера), переопределитьrequestImage
, чтобы обеспечить это изображение (фактическийid
запрос не имеет значения, см. ниже) и слот, который получаетQImage
, и обновляет член. - Подключите свой
Publisher
сигнал к слоту вашего провайдера. - Установите поставщика в механизм QML с помощью
QQmlEngine::addImageProvider
(см.QQuickView::engine
); сноваid
не имеет большого значения, просто используйте разумный -
В QML просто используйте простой элемент
Image
с источником вроде этогоImage { id: myImage source: "image://providerIdPassedToAddImageProvider/foobar" }
foobar
будет передан вашему провайдеру, но опять же, это не имеет большого значения. -
Мы почти там, теперь нам нужен способ нажимать обновления изображений в мир QML (иначе изображение никогда не узнает, когда нужно обновить себя). См. мой ответ здесь о том, как это сделать с помощью элемента
Connections
и немного JS.Обратите внимание, что в общем случае вам не нужно делать
Publisher
тип QML, вам просто нужно создать один экземпляр на С++ и выставить его в мир QML черезQQmlContext::setContextProperty
.
Использовать пользовательский Qt Quick 2 Item
QQuickPaintedItem
, вероятно, наиболее удобен для работы, поскольку он предлагает метод paint
, принимающий QPainter
. Следовательно, большой план
- Подкласс
QQuickPaintedItem
: подкласс хранитQImage
для окрашивания и имеет слот, который устанавливает новый QImage. Также реализацияpaint
просто рисует изображение с помощьюQPainter::drawImage
. - Предоставьте подкласс миру QML через
qmlRegisterType
(чтобы вы могли использовать его в QML) -
Выясните способ подключения сигнала, несущего новое изображение, к слоту.
Это может быть сложная часть.
Чтобы выполнить соединение на С++, вам нужно выяснить, что элемент был создан (и получить указатель на него); обычно это делается путем присвоения свойству
objectName
некоторому значению, а затем с помощьюfindChild
в корневом объекте (возвращаемомQQuickView::rootObject()
), чтобы получить указатель на сам элемент. Затем вы можете использоватьconnect
, как обычно.Или вместо этого можно выполнить соединение в QML, как и выше, с помощью элемента
Connections
объекта издателя С++, открытого в мире QML:MyItem { id: myItem } Connections { target: thePublisherObjectExposedFromC++ onNewImage: myItem.setImage(image) }
Это имеет то преимущество, что вы работаете независимо от того, когда вы создаете экземпляр MyItem; но я не уверен на 100%, что он будет работать, потому что я не уверен, что вы можете обрабатывать тип
QImage
в QML.