Qt-清除布局后,无法将小部件正确添加到QHBoxLayout

时间:2019-02-20 20:18:11

标签: qt

我有一个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);
}

此功能与以前用于将小部件添加到布局中的功能相同,并且是在Construction上首次使用的功能:

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 :(得分:0)

如“编辑”中所述,问题来自于在布局中添加的DeviceWidget,而这些覆盖eventFilter。可能有一种在eventFilter中添加案例以使其起作用的方法,但就我而言,最好(1)(2):< / p>

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);

对于其他事件(输入/离开),我为void enterEvent(QEvent* event)覆盖了void leaveEvent(QEvent* event)class DeviceWidget。这就是导致我选择似乎更好的第二种选择的原因。

2。。完全删除eventFilterinstallEventFilter,因为它们仅在单击小部件时用于发出信号,并在光标悬停小部件时执行操作。而是像之前为悬停事件所说的那样,为enterEvent覆盖leaveEventclass DeviceWidget

然后,class DeviceObjecy中的void mousePressEvent(QMouseEvent*)会覆盖点击事件。