Welcome to the official BlackBerry Support Community Forums.

This is your resource to discuss support topics with your peers, and learn from each other.

inside custom component

Native Development

Posts: 19
Registered: ‎05-09-2013
My Device: Z10
My Carrier: None
Accepted Solution

Expose abstract type as Q_PROPERTY to QML

[ Edited ]



I defined a base interface for classes to implement:


class AbstractImageProcessor : public QObject
    AbstractImageProcessor(QObject * parent) : QObject(parent) {}
    virtual QImage process(const QByteArray &data) = 0;
    virtual ~AbstractImageProcessor(){ }

 One such implementation that I want usable from QML looks like this:

class WebImageProcessor : public AbstractImageProcessor
    Q_PROPERTY(int maxHeight READ getMaxHeight WRITE setMaxHeight NOTIFY maxHeightChanged)
    Q_PROPERTY(int maxWidth READ getMaxWidth WRITE setMaxWidth NOTIFY maxWidthChanged)
    Q_PROPERTY(bool fit READ isFit NOTIFY fitChanged)
    public WebImageProcessor(QObject * parent = 0) : AbstractImageProcessor(parent) {}
    virtual ~WebImageProcessor() {}
    /* rest of code omitted */ 

 I want to expose this AbstractImageProcessor as a property on another QML type:

class WebImageView : public bb::cascades::ImageView {
    Q_PROPERTY(AbstractImageProcessor* processor READ getProcessor WRITE setProcessor NOTIFY processorChanged)
    WebImageView(bb::cascades::Container * parent) : bb::cascades::ImageView(parent)  {}
    virtual WebImageView() {}
    /* rest of code omitted */

 So I register my custom types with QML

qmlRegisterUncreatableType<AbstractImageProcessor>("foo.controls", 1, 0, "AbstractImageProcessor", ""); 
qmlRegisterType<WebImageProcessor>("foo.controls", 1, 0, "WebImageProcessor"); qmlRegisterType<WebImageView>("foo.controls", 1, 0, "WebImageView");

 How I want to use it in QML

import foo.controls 1.0
/* omitted containers */

WebImageView { 
  processor: WebImageProcessor {
     maxHeight: 500
     maxWidth: 300
  /* rest of properties omitted */


But once I launch my application it fails to parse the qml document.


bb::cascades::QmlDocument: error when loading QML from: QUrl( "asset:///main.qml" )
--- errors: (asset:///main.qml:138:57: Cannot assign object to property) bb::cascades::QmlDocument:createRootObject document is not loaded or has errors, can't create root


In fact if I hover over the WebImageProcessor class in the editor, it says:


The super type of the component WebImageProcessor is unknown, some of its properties are not validated.


Now the thing is that the for example the built in cascades ListView exposes an abstract type as a Q_PROPERTY:



Event inspecting the header files of bb::cascades::ListView and bb::cascades:Smiley Very HappyataModel gives me no other clues because it's done essentially the same way.


Could it be that I have to register the types in a different way? If so how?


If I use WebImageProcessor in the Q_PROPERTY instead of the AbstractImageProcessor then it works as expected, but I want to expose the abstract type, and given that cascades does it then it's definitely possible somehow

Posts: 19
Registered: ‎05-09-2013
My Device: Z10
My Carrier: None

Re: Expose abstract type as Q_PROPERTY to QML

[ Edited ]

Turns out I've been missing a Q_OBJECT macro inside AbstractImageProcessor.


I swear I had it before with no luck. Perhaps cleaning the project today fixed the issue.


Anyway it works as I wanted, with the only exception that Momentics complains about the assignment in qml, but it's just a minor inconvenience. Smiley Happy