3

我有一段代码可以做到这一点:一个名为的方法prepareUI使 UI 准备好能够加载输入其中的搜索结果。onClear当需要清除已经显示的结果时调用的方法。还有一个名为的方法populateSearchResults,它获取搜索数据并使用它加载 UI。保存数据的容器是一个公开可用的指针,因为需要从以下位置清除结果onClear

void MyClass::prepareSearchUI() {
        //there may be many search results, hence need a scroll view to hold them
        fResultsViewBox = new QScrollArea(this);
        fResultsViewBox->setGeometry(28,169,224,232);
        fSearchResultsLayout = new QGridLayout();
}

void MyClass::onClear() {
    //I have tried this, this causes the problem, even though it clears the data correctly
    delete fSearchResultContainer;
    //tried this, does nothing
    QLayoutItem *child;
    while ((child = fSearchResultsLayout->takeAt(0)) != 0)  {
        ...
        delete child;
    }
}

void MyClass::populateWithSearchesults(std::vector<std::string> &aSearchItems) {
    fSearchResultContainer = new QWidget();
    fSearchResultContainer->setLayout(fSearchResultsLayout);

    for (int rowNum = 0; rowNum < aSearchItems.size(); rowNum++) {
        QHBoxLayout *row = new QHBoxLayout();
        //populate the row with some widgets, all allocated through 'new', without specifying any parent, like
        QPushButton *loc = new QPushButton("Foo");
        row->addWidget(loc);
        fSearchResultsLayout->addLayout(row, rowNum, 0,1,2);    
    }
    fResultsViewBox->setWidget(fSearchResultContainer);
}

问题是,当我调用onClearwhich internal callsdelete时,它确实删除了所有显示的结果。但在那之后,如果我populateWithSearchesults再次调用,我的应用程序就会崩溃,并且堆栈跟踪会显示这个方法在它崩溃的地方。

我该如何解决这个问题?

4

2 回答 2

4

看来您对所有权有一些误解。AQLayout拥有添加到它的任何项目的所有权:http: //doc.qt.io/qt-5/qlayout.html#addItem

这意味着QLayout负责删除这些项目。如果您删除它们,那么QLayout也会尝试删除它们,然后您会遇到现在看到的崩溃。

QLayout没有很好的删除内容和重新添加内容的功能(例如,removeWidget可能不会像您希望的那样工作。)但是这是有原因的。

QLayout不打算用作列表视图。

你想要的是一个,等待它,QListView。它甚至会为您处理滚动功能,并使添加和删除元素成为可能。

于 2015-02-04T16:38:00.623 回答
0

实际上,即使您正在使用QGridLayout或任何其他Layouts ,您也可以轻松解决此问题:

    subLayout->removeWidget(m_visibleCheckBox);//removes and then it causes some zigzag drawing at (0,0)

    m_visibleCheckBox->setVisible(false);//asks to redraw the component internally

    setLayout(subLayout);//for safety as we may use that layout again and again

如果您只使用第一行,它将导致:

qt removeWidget 最好的方法

于 2020-12-09T13:48:22.680 回答