Important: Please read the Qt Code of Conduct -

Can't remove HLayout from VLayout

  • I have a UI. That UI contains a vertical layout.

    I add multiple horizontal layouts to that layout; each horizontal layout contains some widgets. In effect, when i add horizontal layouts, I'm adding rows of buttons. Here is how I am adding these rows of buttons:

    QHBoxLayout *hLayout = new QHBoxLayout;
    QPushButton* remButton = PBS_NEW QPushButton();
    QComboBox* comboBox1 = PBS_NEW QComboBox();
    QComboBox* comboBox2 = PBS_NEW QComboBox();
    QLineEdit* lineEdit = PBS_NEW QLineEdit();
    QCheckBox* box = PBS_NEW QCheckBox();

    At a later time, I want to remove that row of buttons. I decide to do this by removing the horizontal layout. But it doesn't work. The buttons are still visible (and pressable) although the formatting seems to go wrong; the row of buttons overlaps other rows.

    Here is how I am trying to remove that row of buttons:

    // take the horizonal layout that needs to be removed
    QHBoxLayout* layoutToRemove = static_cast<QHBoxLayout*>(ui.matchCriteriaVLayout->takeAt(rowToRemove));
    // delete all horiztonal layout's children (i.e. contents)
    QLayoutItem *child;
    while ((child = layoutToRemove->takeAt(0)) != 0)
    	delete child;
    // delete the hlayout itself
    delete layoutToRemove;

    What am I doing wrong? What am I missing?

  • Qt Champions 2017

    Can u try inside your while loop
    delete child->widget()
    delete child

  • Brilliant. That certainly makes it look a lot better. I will double-check that it is deleteing everything and I'm not leaving the layout in a bad state, but so far that looks good.

    Thank you very much. If this works out well, I'll come back and mark this solved.

  • Qt Champions 2017

    Cool. If the issue is resolved, request you to move the issue to SOLVED state.

  • Moderators

    @MoschopsRedux The only problem with this solution is your layout, potentially, does not own those widgets. If you do the delete child->widget() you are deleting something another component may use later on and your app will crash.

    This may not be the actual case in your specific application but it's a bad habit to get into.

    You would be better off doing a child->widget()->deleteLater() to let it handle any outstanding messages and let Qt's message loop clean it up. This will cause it's parents to forget about it properly and not think the memory for their children still exists.

Log in to reply