Welcome!

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

Reply
New Developer
Posts: 8
Registered: ‎07-23-2013
My Device: Blackberry Z10
My Carrier: Sosh (FR)

[QML/JS] Unregistered datatype 'bb::cascades::Image'

Hello,

 

To workaround the fact that ImageView cannot download remote images, I've created a QML invocable C++ object that download the image's bytes, transforms it in a bb::cascades::Image, and output it in a signal.


Then I wrote the following custom QML component :

 

import bb.cascades 1.0
import recatch.controls 1.0

Container {
    property alias image : imageLoader.imageUrl
    property alias scalingMethod : imageView.scalingMethod
    
    layout: DockLayout {}

    ActivityIndicator {
        id: hourglass
        running: true
        horizontalAlignment: HorizontalAlignment.Center
    }

	ImageView {
        id: imageView
        verticalAlignment: VerticalAlignment.Fill
        horizontalAlignment: HorizontalAlignment.Fill
    }
    
    attachedObjects: [
        ImageLoader {
            id: imageLoader
            onImageFailed: {
                hourglass.running = false;
                console.log("RemoteImage : image loading failed");
            }
            onImageReady: {
                hourglass.running = false;
                console.log("RemoteImage : image ready");
            	imageView.image =  image;
            }
        }
    ]
}

 The image loads fine, onImageReady is triggered and when I try to set the image property of my ImageView, I have the following error : 

 

Warning: QMetaProperty::read: Unable to handle unregistered datatype 'bb::cascades::Image' for property 'QDeclarativeBoundSignalParameters::image'

 What am I doing wrong ?

Developer
Posts: 1,159
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: [QML/JS] Unregistered datatype 'bb::cascades::Image'

Unfortunately I don't have an answer for you... yet, but I am working on pretty much the exact same thing... right down to calling it "ImageLoader". I get the exact same result as you when I try to apply the downloaded image to the ImageView, in fact I found your post by searching for "QDeclarativeBoundSignalParameters::image". I am guessing it has something to do with the Q_DECLARE_METATYPE macro, but I haven't figured it out yet. If I do I will post it here.

 


pleasereset wrote:

Hello,

 

To workaround the fact that ImageView cannot download remote images, I've created a QML invocable C++ object that download the image's bytes, transforms it in a bb::cascades::Image, and output it in a signal.


Then I wrote the following custom QML component :

 

import bb.cascades 1.0
import recatch.controls 1.0

Container {
    property alias image : imageLoader.imageUrl
    property alias scalingMethod : imageView.scalingMethod
    
    layout: DockLayout {}

    ActivityIndicator {
        id: hourglass
        running: true
        horizontalAlignment: HorizontalAlignment.Center
    }

	ImageView {
        id: imageView
        verticalAlignment: VerticalAlignment.Fill
        horizontalAlignment: HorizontalAlignment.Fill
    }
    
    attachedObjects: [
        ImageLoader {
            id: imageLoader
            onImageFailed: {
                hourglass.running = false;
                console.log("RemoteImage : image loading failed");
            }
            onImageReady: {
                hourglass.running = false;
                console.log("RemoteImage : image ready");
            	imageView.image =  image;
            }
        }
    ]
}

 The image loads fine, onImageReady is triggered and when I try to set the image property of my ImageView, I have the following error : 

 

Warning: QMetaProperty::read: Unable to handle unregistered datatype 'bb::cascades::Image' for property 'QDeclarativeBoundSignalParameters::image'

 What am I doing wrong ?






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.  multiFEED Icon

Play nice: Clicking Like Button on posts that helped you not only encourages others to continue sharing their experience, but also improves your own rating on this board. Also, don't forget to accept a post if it solves your problem or answers your question.
Highlighted
Developer
Posts: 1,524
Registered: ‎12-18-2012
My Device: Z30, Z10 LE, DevAlpha C, PlayBook

Re: [QML/JS] Unregistered datatype 'bb::cascades::Image'

I can't test this right now, could you try calling:

qmlRegisterType<Image>();

before creating the QML and see if it helps?

Andrey Fidrya, @zmeyc on twitter
Developer
Posts: 1,159
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: [QML/JS] Unregistered datatype 'bb::cascades::Image'

Ok, solved it. There are really two solutions.

 

  1. Don't pass the Image as a signal parameter (remove the parameter from your signal declaration). If your ImageLoader class has a property called "image" then your  imageView.image =  image; line will still work unchanged. It will, however, get the image from the property rather than the signal parameter.
  2. use qRegisterMetaType() to tell the signal/slot mechanism to recognize Image as a valid signal parameter. This choice is probably preferable to you since it only requires one line of code and allows you to pass Image to QML as a parameter in any signals you like.

When I looked closer at the error message we were both getting, I noticed QDeclarativeBoundSignalParameters::image suggested that it was trying to pass an Image as a signal parameter that was making QML choke. I remembered that you can register other classes as valid signal parameters as long as they fulfill two requirements:

 

  1. Must have a copy constructor.
  2. Must have an assigment operator defined (operator=()).

Unfortunately this means you can't pass any descendent of QObject as a signal parameter since QObject has neither (actually you can pass a pointer to a QObject descendent by wrapping it in a QVariant with QVariant::fromValue()). Lucky for us though, Image doesn't inherit from QObject and actually satifies both our requirements so just add this line in main.cpp or in the constructor of your main application class:

 

qRegisterMetaType<bb::cascades::Image>("Image");

Now QML will be able to receive the Image from the signal parameter and your original code will work as intended.

 

If this works for you remember to mark this thread as solved. 



Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.  multiFEED Icon

Play nice: Clicking Like Button on posts that helped you not only encourages others to continue sharing their experience, but also improves your own rating on this board. Also, don't forget to accept a post if it solves your problem or answers your question.
Developer
Posts: 1,159
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: [QML/JS] Unregistered datatype 'bb::cascades::Image'

I took too long writing up my solution and you beat me to the punch. LOL

 


Zmey wrote:
I can't test this right now, could you try calling:

qmlRegisterType<Image>();

before creating the QML and see if it helps?





Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.  multiFEED Icon

Play nice: Clicking Like Button on posts that helped you not only encourages others to continue sharing their experience, but also improves your own rating on this board. Also, don't forget to accept a post if it solves your problem or answers your question.
New Developer
Posts: 3
Registered: ‎01-24-2015
My Device: None
My Carrier: Virgin Mobile

Re: [QML/JS] Unregistered datatype 'bb::cascades::Image'

[ Edited ]

greenmr wrote:

Ok, solved it. There are really two solutions.

 

  1. Don't pass the Image as a signal parameter (remove the parameter from your signal declaration). If your ImageLoader class has a property called "image" then your  imageView.image =  image; line will still work unchanged. It will, however, get the image from the property rather than the signal parameter.
  2. use qRegisterMetaType() to tell the signal/slot mechanism to recognize Image as a valid signal parameter. This choice is probably preferable to you since it only requires one line of code and allows you to pass Image to QML as a parameter in any signals you like.

When I looked closer at the error message we were both getting, I noticed QDeclarativeBoundSignalParameters::image suggested that it was trying to pass an Image as a signal parameter that was making QML choke. I remembered that you can register other classes as valid signal parameters as long as they fulfill two requirements:

 

  1. Must have a copy constructor.
  2. Must have an assigment operator defined (operator=()).

Unfortunately this means you can't pass any descendent of QObject as a signal parameter since QObject has neither (actually you can pass a pointer to a QObject descendent by wrapping it in a QVariant with QVariant::fromValue()). Lucky for us though, Image doesn't inherit from QObject and actually satifies both our requirements so just add this line in main.cpp or in the constructor of your main application class:

 

qRegisterMetaType<bb::cascades::Image>("Image");

Now QML will be able to receive the Image from the signal parameter and your original code will work as intended.

 

If this works for you remember to mark this thread as solved. 


 

 

Thanks you Smiley Very Happy ! I used qRegisterMetaType method!