Need a few secrets about Qt in C/C++...



  • I've been using C/C++ for nearly 30 years. I've been using Qt for nearly 2 weeks. One thing that mystifies me a bit is how widgets and and layouts are created (programmatically); much of the examples show Qt making, say, a form, and creating, say, a QLineEdit on the stack in the procedure, attaching it to the layout, and then return from the procedure. I would be expecting this to throw the QLineEdit out of scope, and have it crash, but Qt seems quite happy. Does it copy it over, instead of referencing it?

    Rough pseudo-code example:

    void addElementsToForm()
    {
    QFormLayout *thisForm =new QFormLayout(mainLayout);
    thisForm->addRow(new QLineEdit(_tr("status"));
    }

    I would think both the 'thisForm' and the instance of QLineEdit would go out of scope, but it seems happy. Can someone confirm this is correct?
    Also, if you create a new QLineEdit here that you need to access later (out of this procedure), how do you get access to that? Do you crawl the children looking for the name you gave the label ("status") or do a find child? My inclination is to save that instance in a class object so I can get at it, but it seems a lot of examples don't bother with that. Any insight is appreciated. Thanks



  • Hi and welcome to devnet,

    little fix: QFormLayout::addRow() requires 2 parameters.

    BTW, Qt manages children in a very user-friendly way.
    Each time you create an QObject instance (or a subclass) you can specify the parent; each QObject has a list of his children (pointers) and handle the destruction of these automatically.
    For that reason is really suggested to create objects in the heap assigning their a paren

    void MyWidget::foo() {
        QWidget *w = new QWidget(this);
        QLabel* l = new QLabel(tr("Hello"), this);
    }
    

    in that case w and l are children of this. this stores a pointers to w and l and when is destroyed it takes care of destroying all his children


  • Moderators

    Hi, and welcome to the Qt Dev Net!

    @Tabj said:

    void addElementsToForm()
    {
    QFormLayout *thisForm =new QFormLayout(mainLayout);
    thisForm->addRow(new QLineEdit(_tr("status"));
    }

    I would think both the 'thisForm' and the instance of QLineEdit would go out of scope

    Both the QFormLayout and the QLineEdit are created using new, so they are put in the heap, not the stack.

    Also, if you create a new QLineEdit here that you need to access later (out of this procedure), how do you get access to that? Do you crawl the children looking for the name you gave the label ("status") or do a find child? My inclination is to save that instance in a class object so I can get at it, but it seems a lot of examples don't bother with that.

    Yes, you can save a copy of the pointer. The examples didn't bother, probably because they didn't need access to the pointer afterwards.

    Crawling the child list works too, but it's probably a bit slower.

    Like you, I'm inclined to save the pointer.



  • @mcosta Hi and thanks; it wasn't so much the object being on the heap but the pointer was local to procedure and would go out of scope, so I didn't know how people were handling it. @JKSH says he keeps pointers around, which is my inclination too, so maybe it's just the examples cheaping it out. Thanks!



  • @JKSH Thanks, makes sense - the examples were confusing me - wouldn't you want access to one of those fields after? That's why I couldn't figure out why they seemed to be skirting that issue. If it's for the sake of brevity in examples, that's understandable (though I'd like some note somewhere on it); my inclination is to hold onto a pointer too, so that's what I'll go ahead with. Just wanted to make sure I wasn't missing something here. Thanks.



  • @Tabj said:

    @JKSH says he keeps pointers around, which is my inclination too

    Honestly I keep pointers only to objects that I need to manage directly after creation (for example I don't keep pointers to QLabel if I don't need to change their text; the same for layouts and so on..)



  • @mcosta Yes, of course, but examples have lots of line edits created on the fly but no way to save the pointer. A use-once-and-discard, like a label, I don't mind ignoring (assuming you don't have to change it) but some of these other widgets you obviously have to access later. Thanks



  • You're right but sometimes you don't need to store a pointer to these objects because you handle the value in signals&slots

    For instance:

    class MyObject: public QWidget 
    {
      Q_OBJECT
    
    ...
    Q_SIGNALS:
        void newText(const QString& text);
    
    public Q_SLOTS:
        void handleText(const QString&);
    
    ...
    };
    
    MyObject::MyObject(QWidget* parent): QWidget(parent)
    {
    ...
        QLineEdit *le = new QLineEdit(this);
        connect (le, &QLineEdit::textChanged, this, &MyObject::handleText);
        connect (this, &MyObject::newText, le, &QLineEdit::setText);
    ...
    }
    


  • @Tabj You might benefit from my three courses on Qt in the Pluralsight library. PS is currently having a 40% off sale (until April 30th) on annual subscriptions. If you want a week long VIP pass (should be long enough to watch the three Qt courses) send me a chat through this forum and I'll get you one. You might also enjoy a lot of the C++ offerings especially if you're not up to speed on C++x11.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.