PDA

View Full Version : Problem with qobject_cast



Tepi
28th August 2009, 13:27
Hi there,

I have some strange problem with the qobject_cast. I was successfully using the same code at the another class and after I moved the code to the new class it won't work anymore. If I build the project with the debug configuration and run it at the debug mode I can't even debug it normally because debugger stops automatically at the qmetaobject.cpp files "QObject *QMetaObject::cast(QObject *obj) const" function. And this happens even though I haven't set the breakpoint in it... And it won't continue debugging through there even I press "Continue".

Here's the code where I use qobject_cast... the problem goes away if I comment out these lines. So the problem should be related to this, I assume ;)

Note that at the code the "component" is type QWidget *component


void GUIComponent::setComponentOptions(const QString componentOptions)
{
options = componentOptions;

if(QSlider *slider = qobject_cast<QSlider *>(component))
{
if(options == "horizontal")
slider->setOrientation(Qt::Horizontal);
}
else if(QPushButton *button = qobject_cast<QPushButton *>(component))
{
button->setText(options);
}
}


Probably it is just some stupid mistake like usually ;)

Any help would be greatly appreciated.

victor.fernandez
28th August 2009, 13:55
Where is "component" initialized? Are you sure it's initialized and it's a valid pointer? Could you provide a backtrace when you application crashes?

Appart from that, I would recommend you not to declare the pointer in the same if():



QSlider *slider = qobject_cast<QSlider *>(component);
if(slider) {
if(options == "horizontal")
slider->setOrientation(Qt::Horizontal);

} else {
QPushButton *button = qobject_cast<QPushButton *>(component);
if(button)
button->setText(options);
}

caduel
28th August 2009, 16:01
what (type especially) is "component"?

(btw, I disagree on the "don't declare a pointer in an if" thing.)

Tepi
31st August 2009, 06:52
component type: QWidget *

So it's a pointer to a QWidget but it usually points to some specific widget like for example QSlider, QPushButton or anything that is inherited from QWidget.

The widget gets initialized at the another class (xml parser) and pointer to that widget is then passed on to the "component" with setter function.



void ServiceDescriptionParser::readComponentType(GUICom ponent *component)
{
Q_ASSERT(isStartElement() && name() == "type");

QString type = readElementText();

if(type == "slider") {
QSlider *slider = new QSlider();
component->setComponent(slider);
qDebug() << "GUI Element Type: " << type;
}
else if (type == "button") {
QPushButton *button = new QPushButton();
component->setComponent(button);
qDebug() << "GUI Element Type: " << type;
}
}


And the setter function...



void GUIComponent::setComponent(QWidget *component)
{
this->component = component;
parentService->addWidget(this->component);
}

victor.fernandez
31st August 2009, 07:33
Are you 100% sure you are not calling setComponentOptions() before setComponent()? Did you set component to 0 in the constructor to avoid having a pointer to some arbitrary (invalid) place in the memory between the moment where the class is instanced and setComponent() is called? Are you also sure the component is not deleted somewhere else without calling setComponent()? You could use QPointer in order to prevent this situation from happening.

Tepi
31st August 2009, 07:33
Thank you guys for your replies.

I got it solved... it was just a stupid mistake, as I thought :)

The problem was that I didn't set the "component" pointer to NULL at the start and therefore I didn't even put any inspection before trying to do the casting.

So the solution was to set the "component" to NULL when I initialize the instance which includes the "component" and then do the inspection...


if(component != NULL)

...before the qobject_cast functions.

Tepi
31st August 2009, 08:03
Seems like you would have solved the problem also Victor, we posted the solution for this problem simultaneously ;)

I spent last friday struggling with this problem and after the weekend the solution just came to me... so obvious. This just shows how the coding works, you just need some breaks for any now and then to get some fresh ideas, because when you stare your own code too long time you just become "numb" for it. :D