清除并重新填充QFormLayout

时间:2018-01-02 18:00:26

标签: c++ qt

我试图设置QFormLayout,以便某些按钮显示或隐藏它们下方的部分,并在我要隐藏的小部件上使用setHidden导致布局错误由于表格填充仍然显示。

所以我尝试了这个:

#include <QApplication>
#include <QCheckBox>
#include <QLabel>
#include <QFormLayout>
#include <QMainWindow>


class MainWindow : public QMainWindow
{
    Q_OBJECT

    QCheckBox     checkA;
    QFormLayout * m_formLayout;
    QWidget     * m_widget;

public:
    explicit MainWindow(QWidget *parent = 0) :
        QMainWindow(parent),
        m_formLayout(0L),
        m_widget(0L)
    {
        populate();
        connect(&checkA, &QCheckBox::stateChanged, this, &MainWindow::populate);
    }

    virtual ~MainWindow() { clear(); }

    bool doesOwnObject(void * it) const
    {
        return (uintptr_t)this <= (uintptr_t)it && (uintptr_t)it < (uintptr_t)(this+1);
    }

    void clear()
    {
        if(m_formLayout)
        {
            QLayoutItem *child;
            while ((child = m_formLayout->takeAt(0)) != 0)
            {
                QLayout     * layout = child->layout();
                QSpacerItem * spacer = child->spacerItem();
                QWidget     * widget = child->widget();

                if(layout && !doesOwnObject(layout)) delete layout;
                if(spacer && !doesOwnObject(spacer)) delete spacer;
                if(widget && !doesOwnObject(widget)) delete widget;
            }

            delete m_formLayout;
            m_formLayout = 0L;
        }
    }

    void populate()
    {
        if(m_widget) { clear(); return; }

        m_widget = new QWidget(this);
        setCentralWidget(m_widget);
        m_formLayout = new QFormLayout(m_widget);

        m_formLayout->addRow(tr("Show Check Box B:"), &checkA);
    }
};

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();

    return a.exec();
}

但这似乎并不起作用,因为clear()似乎并没有真正减少表单布局。小部件保留在删除QFormLayout之前的位置。如果m_widget被删除,那么程序会在尝试删除checkA时崩溃,因为checkA尚未从现在删除的表单中删除。

我该如何解决这个问题?

2 个答案:

答案 0 :(得分:0)

我已经找到了一个具有理想(或我所理解的)行为的解决方案。但是,我已将所有内容都移到了指针上(因为我习惯使用Qt)。

标题文件:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include <QCheckBox>
#include <QLayoutItem>
#include <QFormLayout>
#include <QMainWindow>
#include <QLabel>

class MainWindow : public QMainWindow
{
    Q_OBJECT

    QCheckBox *checkA, *checkB;
    QLabel *labelA, *labelB, *labelC;
    QFormLayout * m_formLayout;

public:
    explicit MainWindow(QWidget *parent = 0);

    virtual ~MainWindow();

    void clear();
public slots:
    void populate();
};

#endif // MAINWINDOW_H

cpp文件:

#include "mainWindow.h"

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    QWidget * centralWidget = new QWidget(this);
    setCentralWidget(centralWidget);
    m_formLayout = new QFormLayout(centralWidget);
    checkA = new QCheckBox;
    labelA = new QLabel("Show Check Box B:");
    connect(checkA, &QCheckBox::stateChanged, this, &MainWindow::populate);
    int row = 0;
    m_formLayout->insertRow(row++, labelA, checkA);
    checkB = new QCheckBox;
    labelB = new QLabel("Check Box B:");
    m_formLayout->insertRow(row++, labelB, checkB);
    labelC = new QLabel("Bottom label");
    m_formLayout->insertRow(row++,labelC);

    populate();
}

MainWindow::~MainWindow() {
}

void MainWindow::clear()
{
    if (!checkA->isChecked())
    {
        checkB->hide();
        labelB->hide();
    }
}

void MainWindow::populate()
{
    clear();
    if(checkA->isChecked())
    {
        checkB->show();
        labelB->show();
    }
}

答案 1 :(得分:0)

解决方案:

S

必须调用setParent。