PDA

View Full Version : QML image not refreshing when evoked in separate method



Miss_Mc
14th January 2019, 15:26
Im tring to update a qml Image URL via signal:

This is working perfectly fine when executed in this method:




void Sentinel::startQmlEngine()
{
QQmlApplicationEngine qmlEngine;

qmlRegisterType<ImageItem>("ImageItem",1,0,"ImageItem");
qmlEngine.rootContext()->setContextProperty("imageUrlClass", &image);

QQmlComponent component(&qmlEngine, "qrc:/main.qml");
object = component.create();
assert(object);

image.setUrl(getPathToImage());
}



As soon as I outsource setting the URL the signal is not emitted




void Sentinel::updateGui()
{
image.setUrl(getPathToImage());
}



How can this be?

Here my Qml




import QtQuick 2.12
import QtQuick.Window 2.12
import ImageItem 1.0


Rectangle {

width: 768
height: 576

Connections {
target: imageUrlClass
onUrlChanged: {
image.update();
console.log("image UURL-" + imageUrlClass.imageUrl);
}
}

Image {
id: image
objectName: "image"
x: 0
y: 0
width: 768
height: 576
source: imageUrlClass.imageUrl
opacity: 1
clip: true
fillMode: Image.PreserveAspectFit
cache: false
}

}



ImageItem class header:




#pragma once

#include <QQuickPaintedItem>

//---------------------------------------------------------------------------


class ImageItem: public QQuickPaintedItem
{
Q_OBJECT
Q_PROPERTY(QVariant imageUrl READ getUrl() WRITE setUrl NOTIFY urlChanged)

public:

explicit ImageItem(QQuickItem *parent = nullptr);

virtual void paint(QPainter* painter);

QVariant getUrl() const;
void setUrl(const QVariant &value);

signals:

void urlChanged();

private:
QVariant url;

};


And Cpp:




#include "ImageItem.h"

//---------------------------------------------------------------------------

ImageItem::ImageItem(QQuickItem *parent) :
QQuickPaintedItem(parent)
{
}

QVariant ImageItem::getUrl() const
{
return url;
}

void ImageItem::setUrl(const QVariant &value)
{
url = value;
emit urlChanged();
}

void ImageItem::paint(QPainter* painter)
{
paint(painter);
}



Thanks!

d_stranz
14th January 2019, 16:49
In startQmlEngine(), you declare an instance of QQmlApplicationEngine as a local variable inside the method. As soon as the method ends, this local variable goes out of scope and is destroyed. Any components created using that engine instance are also destroyed, and any signal / slot connections made are automatically disconnected.

Miss_Mc
15th January 2019, 07:31
In startQmlEngine(), you declare an instance of QQmlApplicationEngine as a local variable inside the method. As soon as the method ends, this local variable goes out of scope and is destroyed. Any components created using that engine instance are also destroyed, and any signal / slot connections made are automatically disconnected.

Thanks you are genius.

anda_skoa
16th January 2019, 21:02
Just some additional observation which might not be applicable depending on how your final code will look like:

* you don't need to derive from QQuickItem if you are only using the object for transporting data via properties
* if the property is a URL then the C++ type for this would be QUrl
* you only need qmlRegisterType() and the import if you are instantiating the type from within QML or if the type provides enums that you want to access by name

Cheers,
_