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
Developer
Posts: 45
Registered: ‎01-18-2013
My Device: 9000
My Carrier: CMCC

How signals in custom components connect to slots in C++?

hi,everyone:

I create a QML custom components,and there is a custom signal in it ,but how the signal  connect to C++ slots?

QObject::connect(&theSignalOwner,      SIGNAL(customSigal(QString)), 
                 theApp, SLOT(theSlotFunction(QString)));

---------how to Create theSignalOwner object?
Developer
Posts: 45
Registered: ‎01-18-2013
My Device: 9000
My Carrier: CMCC

Re: How signals in custom components connect to slots in C++?

who knows?

Regular Contributor
Posts: 77
Registered: ‎01-27-2010
My Device: Dev Alpha
My Carrier: Verizon

Re: How signals in custom components connect to slots in C++?

Try to read an article "Create your own signals"  in this link below

 

http://developer.blackberry.com/cascades/documentation/dev/signals_slots/index.html

 

Maz

Developer
Posts: 45
Registered: ‎01-18-2013
My Device: 9000
My Carrier: CMCC

Re: How signals in custom components connect to slots in C++?

[ Edited ]

the custom component in a separate QML file...

 

 

QObject::connect(&theSignalOwner, SIGNAL(customSigalInQML(QString)),
theApp, SLOT(theSlotFunction(QString)));

---------how to Create theSignalOwner object?

Developer
Posts: 103
Registered: ‎12-31-2012
My Device: Blackberry 9810
My Carrier: Verizon

Re: How signals in custom components connect to slots in C++?

Can you please post the entire code... as that would help in diagnosing what your exact problem is.... 

Developer
Posts: 1,524
Registered: ‎12-18-2012
My Device: Z30, Z10 LE, DevAlpha C, PlayBook

Re: How signals in custom components connect to slots in C++?

[ Edited ]

Hi,

I've created a sample project to show how to implement this:

 

http://supportforums.blackberry.com/t5/Cascades-Development/Emit-signal-from-dynamic-component-and-h...

 

The sample is for components created dynamically.

 

If you aren't creating them dynamically then it's simpler:

1) when creating the components set their objectName properties:

 

CustomComponent {
  objectName: "componentName"
}

 

2) find the components by using root->findChild<QObject *>("componentName") function in constructor, then connect their signals to C++ handlers:

 

QObject *component = root->findChild<QObject *>("componentName");
QObject::connect(component, SIGNAL(...

 


Andrey Fidrya, @zmeyc on twitter
Developer
Posts: 541
Registered: ‎05-17-2009
My Device: Not Specified

Re: How signals in custom components connect to slots in C++?

For teaching purposes, I tell people only to use findChild as a last resort because it limits scalablity of the application. The problem is that findChild is not recursive - it only seeks for children of the object it is called on, not for children of children etc.. As soon as you make certain changes within your QML file, you have to also change your findChild call.

 

For example, if you are using findChild to locate a child of the root QML object and you change the QML document by nesting the custom component within another container, you then have to change format of your findChild call. The custom component will no longer be a child of the root, but rather a child of a child of the root. This means your have to call findChild on the result of another findChild call. This is messy and doubles the work required when you want to make basic changes to your QML. Also, you need to use ComponentDefinition at two spots in your QML which clutters your document.

 

It is better just to emit all of your signals from QML items from the root level of your QML document. This means any time you want to connect to an element in your QML file from C++, you really need to use your root QML object in connect() as the signal owner.

 

QObject::connect(&theSignalOwner, SIGNAL(customSigalInQML(QString)),
theApp, SLOT(theSlotFunction(QString)));

---------how to Create theSignalOwner object?

The QObject::connect line looks fine. Either, a) from your custom component, emit a signal that is defined at the root level of your QML, or b) connect a signal from your custom component to a slot in your root QML and emit a signal that is defined at the root level of your QML (there are other good ways to do it too). This would mean theSignalOwner would be your root QML object, which is already created because it is on your screen.

 

Scott

Developer
Posts: 1,524
Registered: ‎12-18-2012
My Device: Z30, Z10 LE, DevAlpha C, PlayBook

Re: How signals in custom components connect to slots in C++?

Superdirt,

 

 

According to Qt docs, findChild is recursive:

http://qt-project.org/doc/qt-4.8/qobject.html#findChild

Returns the child of this object [...] The search is performed recursively.

 

Signals can only be declared at the root level of QML as far as I know (and emitted from anywhere in hierarchy). But if you have a custom component, for example:

 

CustomComponent
{
  signal ...
}

 Which was created like this:

 

Page {
  Container {
    CustomComponent {
objectName: "myComponent"

Then findChild<> can be used to get the pointer to myComponent no matter how complex the hierarchy is.

This is convenient if C++ code is just an implementation of the interface described by qml file.

 

When developing a standalone component which should be treated as a black box by user, the approach you described is better in terms of encapsulation as it hides implementation details.

 

 

 


Andrey Fidrya, @zmeyc on twitter
Developer
Posts: 541
Registered: ‎05-17-2009
My Device: Not Specified

Re: How signals in custom components connect to slots in C++?

The API says findChild is recursive, but it actually is not or at least not in all cases. I am not sure if this is a bug in Cascades or because the definition of a child is not what I expect, but I have lots of code where findChild would not work recursively. I will try and show code to reproduce this.

 

Either way, recursive calls are time consuming and I would warn against them for that reason alone.

 

Scott

Developer
Posts: 45
Registered: ‎01-18-2013
My Device: 9000
My Carrier: CMCC

Re: How signals in custom components connect to slots in C++?

Thanks a lot for reply,but I didn't solve my problem! 

 

(1) myCustomCom.qml  file

 

import bb.cascades 1.0

// This is another Stamp Container used by the list to present a small thumbnail image of the stamps.
Container {
   
    property string phoneNumber

Container { layout: StackLayout { orientation: LayoutOrientation.LeftToRight } Button { onClicked: { //-------invoke functions from C++ file------ } } Button { } } }

 (2) mail.qml  file

            Container
             {
                // define tab content here

                    // Main List
                    ListView {
                        id: stampList
                        objectName: "stampList"
                        
                        layout: GridListLayout {
                            columnCount: 1
                        headerMode: ListHeaderMode.Standard
                            cellAspectRatio: 6.5
                            spacingAfterHeader: 40
                            verticalCellSpacing:5
                        orientation: LayoutOrientation.TopToBottom
                    }

                    listItemComponents: [

                            // The stamp Item
                            ListItemComponent {
                                type: "item"
                                myCustomCom{
          
                                    phoneNumber:ListItemData.phone

                            }
                        }
                    ] // listItemComponents
                }

            }

 (3) App.cpp file

   App:: App(bb::cascades::Application *app)
: QObject(app)
{

..........................................
 
ListView *stampList = root->findChild<ListView*>("stampList");

    if(stampList)
    	setUpStampListModel(stampList);

..........................................
}

void App::setUpStampListModel(bb::cascades::ListView *stampList)
{
    // Create a new GroupDataModel; the GroupDataModel is a helper class that ListView uses for data handling.
    // It uses in-memory storage so we can populate data.
    // We load the GroupDataModel with help from the JsonDataAcces function, load().
	bb::data&colon;:JsonDataAccess jda;

    QVariantList mainList = jda.load("app/native/assets/contacts.json").value<QVariantList>();

    if (jda.hasError()) {
        bb::data&colon;:DataAccessError error = jda.error();
        qDebug() << "JSON loading error: " << error.errorType() << ": " << error.errorMessage();
        return;
    }

    // Sort on region in the model so we will get different categories.
   GroupDataModel *stampModel = new GroupDataModel(QStringList() << "type");

    stampModel->setParent(this);
    stampModel->insertList(mainList);
    stampModel->setGrouping(ItemGrouping::ByFullValue);

    stampList->setDataModel(stampModel);
}

void App::FunctionInvokedByQML()
{
..........................................
}

 

this is the problem: the button in myCustomCom.qml is clicked,how to invoke function(FunctionInvokedByQML()) from C++ file ???

 

thanks a lot !