Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

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?


  • Lifetime Qt Champion

    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.


  • Moderators

    @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).

    @shahriar25

    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.


  • Moderators

    @shahriar25
    This is a very unusual requirement. I doubt qobject_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


  • Moderators

    @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


Log in to reply