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
oddboy
Posts: 136
Registered: ‎05-24-2011
My Device: Z30 running 10.2 and Playbook 4GLTE running OS2.1
My Carrier: rogers
Accepted Solution

dynamically load Options into a DropDown in C++

hey guys,

 

I am trying to dynamically load Option items into a DropDown using C++.  I have a function in my WorkManager class file that does the trick:

 

QStringList WorkManager::getListOfItems() {
	int i = 0;
	QStringList taskNames;  // used for debugging mainly, so i can print the list out to debug
	QList<QObject *>  myObjects = m_model->toListOfObjects();
	DropDown * dpList = bb::cascades::Application::instance()->scene()->findChild<DropDown*>("scriptListDropDown");
	if (dpList != 0 ) {
		dpList->setSelectedOption(0);
		dpList->removeAll();
		for (i = 0; i < myObjects.size(); i++) {
			Task * myTask = (Task *) myObjects[i];
			taskNames.append(myTask->taskName());
			dpList->add(Option::create().text(myTask->taskName()).value(myTask->command()));
//			delete myTask;  // do I need to delete the task object?
		}
//		qDebug() << "WorkManager::getLIstOfItems(), ---> list of tasks is : " << taskNames;
		return taskNames;
	} else  {
		qDebug() << "WorkManager::getListOfItems(), ---> dpList was 0";
		return taskNames;  // empty list
	}
}

 

 

I also found this thread:http://supportforums.blackberry.com/t5/Native-Development/Adding-options-to-a-DropDown-from-c/m-p/21... which helped me get the DropDown populated when the app starts.

 

However, I need to re-populate the list from time to time when the list (a GroupDataModel) changes.  calling the function above a second time from anywhere in my app seems to crash the app immediately.

 

I think/thought it might have something to do with the onSelectedValueChanged slot, but I can't figure it out.

 

it seems to crash right where I do dpList->removeAll().  

 

I also can't seem to find the right place to call this function in an object of my class type.  I think this is because the DropDown isn't ready yet as the dpList * is always 0 unless i call it after the line: 

 

app->setScene(root);

 in the applicationui.cpp file.  Calling it there works on startup, but trying to update the list later (by removeAll(), and recreating it) causes the app to crash.

 

 

is there a better way to do this?  ...and do it safer?  I can't figure out how to do this.

 

thanks!

 

J

 

 

 

bron: a cron-like scheduler for BlackBerry 10
http://apps.oddelement.com
Please use plain text.
Developer
greenmr
Posts: 882
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: dynamically load Options into a DropDown in C++

First off, drop this:

 

dpList->setSelectedOption(0);

Not only is it not needed, but it will blow up your app if the function gets called when there are already no options in the DropDown.

 

Also, do NOT delete the task, as it is still owned by the datamodel. I also see that you are using C-style casting, which just blindly accepts your cast even if it is wrong. Instead, if you know for sure what type it will be do it this way instead:

 

Task* myTask = static_cast<Task*>(myObjects[i]);

If you are not certain whether the type you are casting from is the type you need, use dynamic_cast instead:

 

Task* myTask = dynamic_cast<Task*>(myObjects[i]);

The benefit of this over static_cast is that if the type you are trying to cast from is not compatible, then myTask will be set to NULL.

 

Alternately, Qt offers a replacement for dynamic_cast which works on platforms where regular C++ casts don't.

 

Task* myTask = qobject_cast<Task*>(myObjects[i]);

This is functionally equivalent to dynamic_cast, but as I said, it works on every platform Qt exists on, whereas dynamic_cast may not.

 

Once you've done that get back to us.

 


oddboy wrote:

hey guys,

 

I am trying to dynamically load Option items into a DropDown using C++.  I have a function in my WorkManager class file that does the trick:

 

QStringList WorkManager::getListOfItems() {
	int i = 0;
	QStringList taskNames;  // used for debugging mainly, so i can print the list out to debug
	QList<QObject *>  myObjects = m_model->toListOfObjects();
	DropDown * dpList = bb::cascades::Application::instance()->scene()->findChild<DropDown*>("scriptListDropDown");
	if (dpList != 0 ) {
		dpList->setSelectedOption(0);
		dpList->removeAll();
		for (i = 0; i < myObjects.size(); i++) {
			Task * myTask = (Task *) myObjects[i];
			taskNames.append(myTask->taskName());
			dpList->add(Option::create().text(myTask->taskName()).value(myTask->command()));
//			delete myTask;  // do I need to delete the task object?
		}
//		qDebug() << "WorkManager::getLIstOfItems(), ---> list of tasks is : " << taskNames;
		return taskNames;
	} else  {
		qDebug() << "WorkManager::getListOfItems(), ---> dpList was 0";
		return taskNames;  // empty list
	}
}

 

 

I also found this thread:http://supportforums.blackberry.com/t5/Native-Development/Adding-options-to-a-DropDown-from-c/m-p/21... which helped me get the DropDown populated when the app starts.

 

However, I need to re-populate the list from time to time when the list (a GroupDataModel) changes.  calling the function above a second time from anywhere in my app seems to crash the app immediately.

 

I think/thought it might have something to do with the onSelectedValueChanged slot, but I can't figure it out.

 

it seems to crash right where I do dpList->removeAll().  

 

I also can't seem to find the right place to call this function in an object of my class type.  I think this is because the DropDown isn't ready yet as the dpList * is always 0 unless i call it after the line: 

 

app->setScene(root);

 in the applicationui.cpp file.  Calling it there works on startup, but trying to update the list later (by removeAll(), and recreating it) causes the app to crash.

 

 

is there a better way to do this?  ...and do it safer?  I can't figure out how to do this.

 

thanks!

 

J

 

 

 






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Please use plain text.
Developer
oddboy
Posts: 136
Registered: ‎05-24-2011
My Device: Z30 running 10.2 and Playbook 4GLTE running OS2.1
My Carrier: rogers

Re: dynamically load Options into a DropDown in C++

i did two things.

 

I removed the setSelectedIndex(0), and i changed the (Task *) casting to static_cast<Task *>.

 

works like a charm now.

 

for my own education, why does this work?  was the C-style casting doing something that static_cast does differently / better?  I'd love to know.  my original function worked one time, but not subsequent times, so I just don't understand why this worked.  

 

regardless, THANK YOU!

 

bron: a cron-like scheduler for BlackBerry 10
http://apps.oddelement.com
Please use plain text.
Developer
greenmr
Posts: 882
Registered: ‎03-20-2013
My Device: Red LE Developer Z10
My Carrier: Fido

Re: dynamically load Options into a DropDown in C++

[ Edited ]

Glad to hear you are up and running now, I actually expected we'd have a bit more work to do. I suspect it may have been the setSelectedIndex(0) that was crashing your app, although if the DropDown wasn't empty before calling it, it shouldn't have mattered.

 

As for your casting question, I don't have a solid answer for that either I'm afraid. What I CAN tell you is that C-style casting basically tells the compiler "treat this thing as a <something>, even if it isn't". A static_cast, however, tells the compiler "change this thing into a <something>" and a dynamic_cast says "change this thing into a <something>, and if you can't change it into NULL instead".

 

Note that static_cast makes the compiler generate code that assumes that the cast is valid so it isn't checked at run time, and it will fail then if this is not true. dynamic_cast, however, makes code that checks at run time if the cast is valid before doing it, and just returns NULL if it isn't. reinterpret_cast is basically just a C++ way of writing the C-style casting, since it just tells the compiler "this thing is what I tell you it is, even if it isn't". At run time an invalid reinterpret_cast won't fail on the cast like static_cast does, but your app will crash when you try to access non-existent member variables or functions.


oddboy wrote:

i did two things.

 

I removed the setSelectedIndex(0), and i changed the (Task *) casting to static_cast<Task *>.

 

works like a charm now.

 

for my own education, why does this work?  was the C-style casting doing something that static_cast does differently / better?  I'd love to know.  my original function worked one time, but not subsequent times, so I just don't understand why this worked.  

 

regardless, THANK YOU!

 






Developer of Built for BlackBerry certified multiFEED RSS/Atom feed reader and aggregator.
Please use plain text.