QT 5.6 QVBoxLayout removeWidget, затем addWidget не работает должным образом

Я искал везде и не нашел ничего, что решило бы это. Я делаю QVBoxLayout, а затем совершаю веб-вызов данных. Когда данные возвращаются, я добавляю 4 пользовательских виджета в этот QVBoxLayout

verticalLayout->addWidget(nsd);

Для первых четырех это прекрасно работает. Все появляется по мере необходимости. Однако я хочу удалить любой из четырех виджетов, а затем добавить виджет внизу. Удаление работает нормально

 verticalLayout->removeWidget(nsd);
delete nsd;

Я знаю, что это прекрасно работает, потому что тогда этот виджет больше не рисует на моем экране. Проблема в том, что добавление виджета не работает полностью. Я называю тот же код

verticalLayout->addWidget(nsd);

и проверка verticalLayout->count() говорит мне, что есть 4 элемента. Виджет создается с тем же родительским виджетом, который был добавлен ранее. Событие рисования нового виджета никогда не вызывается. Кроме того, 3, которые отображаются на экране, расположены с интервалом в 3 элемента. Это не значит, что где-то есть дыра. Я также попытался добавить затем удалить, но это та же проблема. Новый предмет никогда не вытягивается и его размер никогда не учитывается.

1 ответ

Решение

Если вы хотите полностью избавиться от виджета, вам нужно только уничтожить его. Вам не нужно беспокоиться, если это было в макете. Если виджет размещен динамически, то delete nsd все, что вам нужно, layout->removeWidget звонок не нужен. Вам также не нужно давать виджетам каких-либо явных родителей - вставка в макет установит правильного родителя.

Следующее работает и безопасно независимо от типа добавляемого / удаляемого виджета. Если удаление имело целевой виджет в стеке вызовов, вы должны использовать deleteLater вместо простого delete, Но это никогда не может иметь место, когда вы удаляете его в ответ на сигнал от несвязанного виджета, если только целевой виджет повторно не входит в цикл обработки событий (аааа! Это не должно быть).

// https://github.com/KubaO/stackrun/tree/master/questions/layout-addremove-37814292
#include <QtWidgets>

int main(int argc, char ** argv) {
   QApplication app(argc, argv);
   QWidget widget;
   QVBoxLayout layout(&widget);
   QPushButton button;
   QLabel label("Hello");
   layout.addWidget(&button);
   layout.addWidget(&label);

   auto onClick = [&]{
      if (layout.count() == 3) {
         delete layout.itemAt(2)->widget();
         button.setText("Add");
      } else {
         layout.addWidget(new QLabel("Hello too!"));
         button.setText("Remove");
      }
   };
   QObject::connect(&button, &QPushButton::clicked, onClick);
   onClick();

   widget.show();
   return app.exec();
}
Другие вопросы по тегам