Solved QWidget & inheritance
-
Hi
I have a QWidget (pointer) and I want to change it in runtime to different widgets that inherit QWidget. I want to be able to use the new widget's functions but I can't do it. can anyone help?
Thanks in advance.QWidget *widget;
widget = new QProgressBar();
widget->setRange(0,100); //Error (the function not recognized)
-
To make this work, you will have to convert the pointer to your widget first, e.g.
QProgressBar *p = qobject_cast<QProgressBar *>(widget); if(p) p->setRange(...);
If you want to do something similar with other types of widgets (QLabel, QSlider, ...), you would have to convert the pointer every time you want to call a function that is not virtual in QWidget itself. I.e.
QWidget *widget; widget = new QLabel(); widget->sizeHint();//works, since QWidgets implementation has been overridden in QLabel widget->setText("...");//does *not* work since you are calling this method on a QWidget! QLabel *l = qobject_cast<QLabel *>(widget); if(l) l->setText("...");//works, since you are explicitely calling QLabels implementation of the method
-
Hi @thEClaw
what if I want to delete the widget that is a QProgressbar after a while? if I delete the widget, the new pointer that is a QProgressBar is deleted too? -
If you delete the object your pointer is pointing to then the object will be deleted even if it is QProgressBar:
QWidget *widget; widget = new QProgressBar(); delete widget; // Will delete QProgressBar
As far as I know Qt uses virtual destructors for base classes, so even if the pointer is of base class type the correct destructor will be called.
-
@jsulm said:
As far as I know Qt uses virtual destructors for base classes
Yes.
QObject
's destructor is virtual. Classes that derive from other bases might not have a virtual destructor, though (e.g.QStringList
, not that you would want to create that in the heap).I have a QWidget (pointer) and I want to change it in runtime to different widgets that inherit QWidget. I want to be able to use the new widget's functions but I can't do it. can anyone help?
You can, as @thEClaw has show, however the rationale behind that somewhat escapes me. Why do you want to do that?
-
Hi @kshegunov
I want the user to enter the widget's name an the program to show that widget and change it by entering sth. -
@shahriar25
This is a very unusual requirement. I doubtqobject_cast
will help you for this, though. You probably want to create objects by class name, which is possible through the meta-object system, however it's a bit hackish. Something along the lines of:QWidget * parent; // The parent of the widget we are creating QByteArray className = QByteArrayLiteral("QDialog*"); int typeId = QMetaType::type(className); if (typeId == 0) ; // Error - class is not registered //< Here is needed an additional check if that class actually derives from QObject const QMetaObject * metaObject = QMetaType::metaObjectForType(typeId); QObject * widget = metaObject->newInstance(Q_ARG(QWidget *, parent));
But why do you need to do that in the first place?
-
@kshegunov
wow your code really creates an object by it's name. this is an interesting thing. but this is not what I want. my program get predefined commands from user or an external program and does something specific. the commands are limited and I want to create about 10 widgets one at a time. so thEClaw's answer is enough here. thank you all -
@shahriar25 said:
wow your code really creates an object by it's name.
It should, but I can't claim merit for it. I think I read about that approach some time ago in the mailing list.
but this is not what I want. my program get predefined commands from user or an external program and does something specific.
I see. Then I must have misunderstood you. But in any case, I'm glad it worked out in the end.
-
Yes of course but only with your help this becomes possible