I have a Qt/QML project that works fine on Windows. Recently, I added an option to display some images in QML. Since I need to set those from C++, I used ImageProvider for that. It works fine on Windows, but when I compile the project on Raspberry Pi (Buster, Qt 5.12.4), it doesn't display anything.
I tried to insert some logging at some places and figured out the requestImage
doesn't ever get called.
Here's how the provider looks like:
class ImageProvider : public QQuickImageProvider {
QImage image;
public:
ImageProvider()
: QQuickImageProvider(QQuickImageProvider::Image) {}
void setImage(QImage img) {
image = img;
}
QImage requestImage(const QString& id, QSize* /*size*/, const QSize& /*requestedSize*/) override {
qInfo() << "Getting image from ImageProvider: " << id;
return image;
}
};
In QML, this is how it gets used:
Image {
id: customImage
source: ""
anchors.fill : parent
fillMode: Image.PreserveAspectFit
Timer {
id: refreshTimer
interval: 20
running: false
repeat: false
onTriggered: parent.source = "image://images/imageContent"
}
function refresh() {
source = "";
/* If an image is already displayed, it won't refresh
if I set source to empty string and then right away
to an image provider again, it won't notice. It has to
tick in the meantime... This is a workaround, maybe there's
a better solution*/
refreshTimer.start();
}
Connections {
target: rootItem
function onImageRefresh() {
customImage.refresh();
}
}
}
I do register the image provider, but that should be clear from the fact it works on Windows:
engine.addImageProvider(QLatin1String("images"), new ImageProvider());
As you can see, I'm using a kind of workaround to be able to refresh the image when it changes, but that is most likely not the problem because again, it works on Windows. The problem is that the function simply does not ever get called on Raspberry Pi.
rootItem
is the context so that I can emit a signal from the C++ backend class. It's setup like this:
engine.rootContext()->setContextProperty("rootItem", (QObject*)this);
Where this
is an instance of a class having this signal:
signals:
void imageRefresh();
I emit the signal from C++ like this:
emit view.imageRefresh();
But obviously the signal is never received on the QML side.
The reason it works on your Windows build but not your rPi is that you're using Qt 5.15 on Windows but 5.12 on your rPi. The code in your Connections block only works in 5.15. For some reason, Qt made a syntax change in 5.15 that broke backward compatibility. The older syntax should work on both, but I believe 5.15 will still nag you with warnings about it.
So to fix the code using the older 5.12 syntax, change your Connections object to look like this:
Connections {
target: rootItem
onImageRefresh: {
customImage.refresh();
}
}