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

問題は、onClear内部的に呼び出す which を呼び出すとdelete、表示されていたすべての結果が削除されることです。しかしその後、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実際には、または他Layoutの sを使用している場合でも、この問題を簡単に解決できます。

    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 に答える