首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

Qt QListWidget 批量刪除選中項目正確姿勢:while 迴圈配合 takeItem

     編輯:關於C語言

Qt QListWidget 批量刪除選中項目正確姿勢:while 迴圈配合 takeItem

前言

在 Qt 中遍歷容器並刪除元素是經典陷阱:迭代器失效、索引錯亂。對於 QListWidget 批量刪除選中項目,正確做法是反覆取第一個選中項目直到無選中,而非正向遍歷。

一、錯誤示範


// ❌ 錯誤 1:正向遍歷索引刪除
for (int i = 0; i < listWidget->count(); ++i) {
    if (listWidget->item(i)->isSelected())
        delete listWidget->takeItem(i);  // 索引錯亂,漏刪/越界
}

// ❌ 錯誤 2:使用迭代器
for (auto it = listWidget->selectedItems().begin(); it != selectedItems().end(); ++it) {
    delete *it;  // selectedItems() 返回臨時副本,迭代器無效
}

二、正確實現:while + takeItem(0)


// 正確:批量移動選中項到另一個 QListWidget
while (ui->lwg_Source->selectedItems().size() > 0) {
    QListWidgetItem* sel = ui->lwg_Source->selectedItems().at(0);
    if (sel) {
        int row = ui->lwg_Source->row(sel);
        sel = ui->lwg_Source->takeItem(row);  // 從源列表取出,所有權轉移
        ui->lwg_Dest->addItem(sel);           // 加入目標列表,無需 delete/new
    }
}

核心原理

  1. selectedItems() 每次調用返回當前選中項的新列表 (值語義副本)
  2. 始終取 at(0) 第一個,避開索引變化問題
  3. takeItem(row) 從列表移除並返回項指針,不釋放記憶體
  4. 同一 QListWidgetItem* 可直接 addItem 到另一列表,所有權轉移

三、完整功能封裝


// 通用批量刪除:從同一列表移除選中項
void removeSelectedItems(QListWidget* list) {
    while (list->selectedItems().size() > 0) {
        QListWidgetItem* item = list->takeItem(list->row(list->selectedItems().at(0)));
        delete item;  // 真正刪除需手動 delete
    }
}

// 批量移動:源列表選中項 → 目標列表
void moveSelectedItems(QListWidget* src, QListWidget* dst) {
    while (src->selectedItems().size() > 0) {
        QListWidgetItem* item = src->takeItem(src->row(src->selectedItems().at(0)));
        dst->addItem(item);
    }
}

// 批量複製:源列表選中項 → 目標列表 (深拷貝)
void copySelectedItems(QListWidget* src, QListWidget* dst) {
    for (QListWidgetItem* item : src->selectedItems()) {
        dst->addItem(new QListWidgetItem(*item));  // 複製構造
    }
}

四、關鍵 API 對比

方法行為記憶體適用場景
takeItem(row)移除並返回項指針調用者擁有,需 delete 或 addItem移動/刪除
removeItemWidget(item)移除項上的自定義控件不影響項本身自定義委託清理
clear()移除所有項並 delete內部自動 delete清空列表
selectedItems()返回選中項指針列表 (副本)不轉移所有權只讀遍歷/批量操作判斷

五、進階:支援多選模式設置


// 設置選擇模式 (在構造函數或 UI 設計器中)
ui->lwg_Source->setSelectionMode(QAbstractItemView::ExtendedSelection);  // Ctrl/Shift 多選
// 或
ui->lwg_Source->setSelectionMode(QAbstractItemView::MultiSelection);     // 點擊即多選

六、總結

Qt 容器批量刪除鐵律:

  1. 不要在正向遍歷中刪除 (索引/迭代器失效)
  2. 用 while (container.size() > 0) { takeFirst() } 模式
  3. QListWidget::takeItem() 返回項所有權,配合 addItem() 實現零拷貝移動
  4. 真正刪除記憶體需顯式 delete

此模式同樣適用於 QList、QVector 等順序容器的批量清理操作。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved