Что-то должно отсутствовать в коде OPs.
Кроме того, на мой взгляд, вызов Vlayout->update()
не нужен.
Я отправил MCVE на продемонстрировать:
testQWidgetAdd.cc
:
// Qt header:
#include <QtWidgets>
// main application
int main(int argc, char **argv)
{
qDebug() << "Qt Version:" << QT_VERSION_STR;
QApplication app(argc, argv);
// setup GUI
QWidget qWinMain;
qWinMain.setWindowTitle("Test Add Widget");
QVBoxLayout qVBox;
QPushButton qBtn("Add QLabel");
qVBox.addWidget(&qBtn);
qWinMain.setLayout(&qVBox);
qWinMain.show();
int i = 1;
// install signal handlers
QObject::connect(&qBtn, &QPushButton::clicked,
[&](bool) {
qVBox.addWidget(new QLabel(QString("QLabel %1").arg(i++)));
});
// runtime loop
return app.exec();
}
CMakeLists.txt
:
project(QWidgetAdd)
cmake_minimum_required(VERSION 3.10.0)
set_property(GLOBAL PROPERTY USE_FOLDERS ON)
set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD_REQUIRED ON)
set(CMAKE_CXX_EXTENSIONS OFF)
find_package(Qt5Widgets CONFIG REQUIRED)
include_directories("${CMAKE_SOURCE_DIR}")
add_executable(testQWidgetAdd testQWidgetAdd.cc)
target_link_libraries(testQWidgetAdd Qt5::Widgets)
Вывод:
и после многократного нажатия кнопки «Добавить QLabel»:
По запросу OP предоставил полный код на pastebin там я извлек следующий фрагмент из:
Base::Base(QWidget *parent)
: QWidget(parent)
{
QHBoxLayout* Hlayout=new QHBoxLayout(this);
Vlayout=new QVBoxLayout(this);
QPushButton *m=new QPushButton("exit",this);
QPushButton *l=new QPushButton("+",this);
Hlayout->addWidget(l);
Hlayout->addWidget(m);
Vlayout->addLayout(Hlayout);
connect(l,SIGNAL(clicked()),this,SLOT(AddWidget()));
connect(m,SIGNAL(clicked()),qApp,SLOT(quit()));
m->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
l->setSizePolicy(QSizePolicy::Expanding,QSizePolicy::Expanding);
}
, и это именно сломанная часть:
QHBoxLayout* Hlayout=new QHBoxLayout(this);
Vlayout=new QVBoxLayout(this);
The пошаговое объяснение:
class Base
получено из QWidget
. Следовательно, применяется управление макетом QWidget
. QWidget
поддерживает один макет для управления размещением и размером дочерних элементов. Он должен применяться QWidget :: setLayout () . Выдержка из do c:
Если на этом виджете уже установлен менеджер компоновки, QWidget не позволит вам установить другой.
Макет может быть построен с родительским виджетом или без него.
Если макет построен с родительским виджетом (указателем на), макет устанавливается на виджет "неявно". В противном случае он должен быть установлен явно (с помощью QWidget::setLayout()
) или может быть добавлен в другой макет.
Хотя я лично предпочитаю всегда задавать макет явно (но это может быть дело вкуса).
Фактическая ошибка OP: Hlayout
и Vlayout
построены с this
, но нельзя установить два макета на this
. Таким образом, второй игнорируется.
Следовательно, виджеты, добавленные в Vlayout
, не могут стать видимыми, потому что Vlayout
не установлен в this
, а QLabel
не могут стать дочерними элементами this
.
Возможное исправление:
Вместо
QHBoxLayout* Hlayout=new QHBoxLayout(this);
должно быть
QHBoxLayout* Hlayout=new QHBoxLayout();
Строка, в которую нужно добавить Hlayout
Vlayout
уже есть (но раньше не давал ожидаемого эффекта):
Vlayout->addLayout(Hlayout);