Qt - Неправильно добавлять виджеты в QHBoxLayout после очистки макета - PullRequest
0 голосов
/ 20 февраля 2019

У меня есть QHBoxLayout, в который я добавил несколько виджетов.Мне нужно иметь возможность динамически обновлять макет, поэтому я использую его для очистки макета:

void ClearLayout(QLayout* layout)
{
    if (!layout)
        return;

    QLayoutItem* item;
    while ((item = layout->takeAt(0)) != nullptr)
    {
        delete item->widget();
        ClearLayout(item->layout());
    }
}

Это действительно удаляет все виджеты и макеты.После этого layout->isEmpty() возвращает true и layout->count() возвращает 0.

Однако, когда я пытаюсь добавить новые виджеты (такой же тип других ранее добавленных, но новых экземпляров), это не работает!

AddWidget()
{
    // DeviceWidget inherits QWidget
    DeviceWidget* deviceWidget = new DeviceWidget;
    deviceWidget->setFixedSize(150, 200);

    connect(deviceWidget->GetSignalObject(), &DeviceObject::Selected, this, 
        &DeviceLayout::SelectedDevice);

    layout->addWidget(deviceWidget, 0, Qt::AlignCenter);
}

Это та же самая функция, которая использовалась ранее для добавления виджетов в макет и работала в первый раз при конструировании:

MainLayout(QWidget* parent) : QHBoxLayout(parent)
{
    layout = new QHBoxLayout;
    addLayout(layout);

    uint32 nb = GetDeviceNumber(); // returns 2
    for (uint32 i = 0; i < deviceNb; ++i)
        AddDeviceWidget();
}

После попытки добавить 2 виджета у меня есть layout->isEmpty()возвращает true и layout->count() возвращает 2, поэтому я в замешательстве ...

Console Output

спасибо за любую предоставленную помощь:)

РЕДАКТИРОВАТЬ:

Кажется, проблема связана с моим классом DeviceWidget, так как попытка добавить простой QLabel к очищенному макету сработала.Вот конструктор DeviceWidget:

DeviceWidget::DeviceWidget(QWidget* parent) : QWidget(parent)
{
    QVBoxLayout* vLayout = new QVBoxLayout;

    QLabel* deviceIcon = new QLabel("DeviceIcon", this);
    deviceIcon->setFixedSize(128, 128);
    deviceIcon->setPixmap(QPixmap::fromImage(QImage("Resources/Icons/device.png")));
    deviceIcon->setObjectName("DeviceIcon");

    // StatusWidget inherits QWidget
    // Just override paintEvent to display a colored filled disk
    m_status = new StatusWidget(20, Status::Close, this);
    m_status->setObjectName("DeviceStatus");

    vLayout->addWidget(deviceIcon, 0, Qt::AlignCenter);
    vLayout->addWidget(m_status, 0, Qt::AlignCenter);

    // DeviceObjct inherits from QObject an add a signal
    m_object = new DeviceObject(size());

    // Function clearing the stylesheet background-color
    Clear();

    setLayout(vLayout);
    installEventFilter(this);
    setObjectName(QString("DeviceWidget"));
}

Комментирование installEventFilter(this) заставит его работать, поэтому я думаю, что мне нужно добавить фильтр событий, чтобы он работал, но я не знаю, какой

1 Ответ

0 голосов
/ 21 февраля 2019

Как сказано в Edit, проблема исходит от DeviceWidget, добавленного в макет, который переопределяет eventFilter.Вероятно, есть способ добавить кейс в eventFilter, чтобы он работал, но в моем случае лучше было либо (1) , либо (2) :

1. Удалить eventFilter из class DeviceWidget и поместить его в class DeviceObject: присутствует m_object для выдачи сигнала в соответствии с событием:

DeviceObject.h:

DeviceObject(QObject* parent);
bool eventFilter(QObject* obj, QEvent* event) override;

signals:
    void Select(uint32 i);

Затем в class DeviceWidget по-прежнему вызывать installEventFilter, но с параметром m_object: installEventFilter(m_object);

Для другого события (Enter / Leave) я переопределил void enterEvent(QEvent* event) и void leaveEvent(QEvent* event) для class DeviceWidget.Вот что привело меня ко второму варианту, который кажется лучше.

2. Полностью удалить eventFilter и installEventFilter, так как он используется только для генерации сигнала при нажатии на виджет и делаетвещи, когда курсор наводит на виджет.Вместо этого переопределите enterEvent и leaveEvent для class DeviceWidget, как сказано выше для события hover.

Затем в class DeviceObjecy переопределить void mousePressEvent(QMouseEvent*) для события клика.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...