Проблема с просмотром изменений приложения с помощью функции update () - PullRequest
1 голос
/ 05 мая 2020

Я начинаю изучать программирование с помощью qt и, чтобы познакомиться с библиотекой, делаю простые небольшие программы. Один из этих планов - создать QLabels, которые следует добавлять в приложение каждый раз при нажатии кнопки, но я не понимаю, почему они не появляются. Вот код:

файл .h:

class Base : public QWidget
{
    Q_OBJECT
public:
    explicit Base(QWidget *parent = 0);
    ~Base();

public slots:
    void AddWidget();

private:
    QVBoxLayout *Vlayout;
};

файл. cpp

Base::Base(QWidget *parent)
    : QWidget(parent)
{
    Vlayout=new QVBoxLayout(this);

    QPushButton *l=new QPushButton("+",this);

    Vlayout->addWidget(l);

    connect(l,SIGNAL(clicked()),this,SLOT(AddWidget()));
}

Base::~Base()
{}

void Base::AddWidget(){

    Vlayout->addWidget(new QLabel("Added",this));
    Vlayout->update();
}

Большое спасибо!

1 Ответ

1 голос
/ 05 мая 2020

Что-то должно отсутствовать в коде 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)

Вывод:

snapshot of testQWidgetAdd.exe

и после многократного нажатия кнопки «Добавить QLabel»:

snapshot of testQWidgetAdd.exe


По запросу 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);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...