文章目錄
- 一、QListWidget的簡介
- 二、QListWidget的基本用法
- 三、QListWidget的數據操作
- 2.1 插入數據
- 2.2 查找數據
- 2.3 選項設置
- 四、QListWidget的信號與槽
一、QListWidget的簡介
??QListWidget 是 Qt 框架中用于顯示和操作條目列表的控件,它是 QListView 的一個子類,提供了更高層級的封裝,允許你以面向 item 的方式 管理列表內容。
二、QListWidget的基本用法
#include <QListWidget>
#include <QDebug>MainWindow::MainWindow(QWidget *parent): QWidget(parent)
{this->setFixedSize(800, 600);QListWidget* listWidget = new QListWidget(this);// 添加文本項listWidget->addItem("Apple");listWidget->addItem("Banana");// 添加帶圖標的項QListWidgetItem* item = new QListWidgetItem(QIcon(":/icons/pineapple.png"), "Pineapple");listWidget->addItem(item);// 設置多選模式listWidget->setSelectionMode(QAbstractItemView::MultiSelection);// 響應點擊事件connect(listWidget, &QListWidget::itemClicked, this, [](QListWidgetItem* item){qDebug() << "你點擊了: " << item->text();});
}
三、QListWidget的數據操作
2.1 插入數據
2.1.1 void QListWidget::addItem(const QString &label)
作用:用于向列表中添加一個文本條目。
參數:label:要顯示的文本內容(QString 類型)。
效果:
- 在列表末尾添加一個新項,內容為 label。
- 內部自動創建一個 QListWidgetItem 并加入 QListWidget。
示例用法:
QListWidget* listWidget = new QListWidget(this);// 添加幾個條目
listWidget->addItem("蘋果");
listWidget->addItem("香蕉");
listWidget->addItem("葡萄");
2.1.2 void QListWidget::addItems(const QStringList &labels)
作用:用于批量添加多個條目到列表中,每個條目都是一個文本項。
參數:labels:一個 QStringList 類型的字符串列表,每個字符串會變成一個條目。
示例用法:
QStringList fruits;
fruits << "蘋果" << "香蕉" << "葡萄" << "橘子";QListWidget* listWidget = new QListWidget(this);
listWidget->addItems(fruits);
這將向列表中依次添加 4 個條目,文本分別是 “蘋果”、“香蕉”、“葡萄” 和 “橘子”。
2.1.3 void QListWidget::addItem(QListWidgetItem *item)
作用:用于向列表中添加一個自定義的條目對象。
參數:item:指向一個 QListWidgetItem 對象的指針,表示你要添加的條目。
效果:
- 將該條目插入到列表末尾。
- QListWidget 會自動接管該對象的所有權,無需手動釋放。
示例用法:添加帶圖標和自定義樣式的項
QListWidget* listWidget = new QListWidget(this);// 創建一個自定義的條目
QListWidgetItem* item = new QListWidgetItem(QIcon(":/icons/star.png"), "重要任務");// 設置附加樣式
item->setFont(QFont("Microsoft YaHei", 12, QFont::Bold));
item->setForeground(Qt::red);
item->setBackground(Qt::yellow);
item->setToolTip("這是一個高優先級任務");// 添加到列表中
listWidget->addItem(item);
使用 setData() 來綁定自定義數據:
在 Qt 中,setData() 是 QListWidgetItem 的成員函數,用于將自定義數據綁定到某個列表項上,便于后續查找、操作或傳遞附加信息。
函數原型:
void QListWidgetItem::setData(int role, const QVariant &value);
參數說明:
- role:數據的“角色”,例如 Qt::UserRole、Qt::DisplayRole
- value:任意類型的數據,必須能被包裝成 QVariant(如 int, QString, bool, QPointF, 自定義結構體等)
常用角色:
- Qt::UserRole:開發者自定義使用的第一個角色。
- Qt::UserRole + 1, +2, …:可自定義多個字段。
- Qt::DisplayRole:值為0,控制 item 的主顯示文本。
- Qt::ToolTipRole:值為3,控制鼠標懸停提示。
示例:綁定一個 ID 到列表項
QListWidget* listWidget = new QListWidget(this);QListWidgetItem* item = new QListWidgetItem("任務一");
item->setData(Qt::UserRole, 101); // 綁定任務 ID
listWidget->addItem(item);// 點擊時讀取 ID
connect(listWidget, &QListWidget::itemClicked, this, [](QListWidgetItem* item){int taskId = item->data(Qt::UserRole).toInt();qDebug() << "點擊任務 ID:" << taskId;
});
進階用法:綁定多個字段
QListWidgetItem* item = new QListWidgetItem("設備 A");
item->setData(Qt::UserRole, 42); // 設備ID
item->setData(Qt::UserRole + 1, "在線"); // 狀態
item->setData(Qt::UserRole + 2, QColor("green")); // 狀態顏色
listWidget->addItem(item);
讀取方式:
int deviceId = item->data(Qt::UserRole).toInt();
QString status = item->data(Qt::UserRole + 1).toString();
QColor color = item->data(Qt::UserRole + 2).value<QColor>();
自定義結構體綁定:
如果你有一個結構體,也可以用 QVariant 包裝它,只要注冊了類型:
struct TaskInfo {int id;QString name;
};
Q_DECLARE_METATYPE(TaskInfo)
注冊類型:
qRegisterMetaType<TaskInfo>("TaskInfo");
綁定使用:
TaskInfo info = {123, "檢查任務"};
QVariant var;
var.setValue(info);QListWidgetItem* item = new QListWidgetItem("任務123");
item->setData(Qt::UserRole, var);
如何注冊自定義結構體到 QVariant?
步驟一:定義并聲明結構體
1.定義結構體并使用 Q_DECLARE_METATYPE
struct TaskInfo {int id;QString name;
};
Q_DECLARE_METATYPE(TaskInfo) // 必須放在 struct 定義之后
Q_DECLARE_METATYPE 告訴 Qt 怎么將 TaskInfo 包裝進 QVariant。
步驟二:注冊類型
2. 在主函數或初始化階段注冊
#include <QMetaType>// 一般在 main() 或 QApplication 初始化前注冊
int main(int argc, char *argv[]) {qRegisterMetaType<TaskInfo>("TaskInfo");QApplication app(argc, argv);...
}
如果只打算把它塞進 QVariant(不跨線程、不用信號槽傳輸),可以省略 qRegisterMetaType,只用 Q_DECLARE_METATYPE。
示例:綁定結構體到 QListWidgetItem
TaskInfo task{101, "圖像識別任務"};QVariant v;
v.setValue(task);QListWidgetItem* item = new QListWidgetItem(task.name);
item->setData(Qt::UserRole, v);
listWidget->addItem(item);
讀取時還原結構體:
QVariant v = item->data(Qt::UserRole);
TaskInfo task = v.value<TaskInfo>();
qDebug() << "ID:" << task.id << " Name:" << task.name;
2.1.4 void QListWidget::insertItem(int row, QListWidgetItem *item)
作用:用于在指定位置插入一個自定義的條目(QListWidgetItem)。
參數說明:
- row:插入位置的行索引(從 0 開始)
- item:要插入的條目對象指針(QListWidgetItem*)
使用示例:
QListWidget* listWidget = new QListWidget(this);// 添加幾個初始條目
listWidget->addItem("蘋果");
listWidget->addItem("香蕉");// 創建要插入的新條目
QListWidgetItem* item = new QListWidgetItem("插入的葡萄");// 插入到索引 1 的位置(即“香蕉”之前)
listWidget->insertItem(1, item);
插入后,列表將變為:
示例:在當前選中項上方插入
int row = listWidget->currentRow(); // 獲取當前選中行
QListWidgetItem* newItem = new QListWidgetItem("新任務");
listWidget->insertItem(row, newItem);
2.1.5 void QListWidget::insertItem(int row, const QString &label)
作用:用于在指定位置插入一個文本條目。
參數說明:
- row:插入位置的索引,從 0 開始計數。
- label:要插入的條目顯示文本(QString 類型)
使用示例:
QListWidget* listWidget = new QListWidget(this);// 添加初始條目
listWidget->addItem("第一項");
listWidget->addItem("第三項");// 在第 1 行插入“第二項”
listWidget->insertItem(1, "第二項");
2.1.6 void QListWidget::insertItems(int row, const QStringList &labels)
作用:用于批量在指定位置插入多個純文本條目。
參數說明:
- row:插入起始位置索引(從 0 開始)
- labels:一組要插入的字符串(QStringList)
示例:在指定位置插入多個條目
QListWidget* listWidget = new QListWidget(this);// 初始添加兩個條目
listWidget->addItem("星期一");
listWidget->addItem("星期五");// 要插入的新項
QStringList midWeek = { "星期二", "星期三", "星期四" };// 插入到索引 1(即“星期五”之前)
listWidget->insertItems(1, midWeek);
輸出結果:
2.2 查找數據
2.2.1 QListWidgetItem *QListWidget::currentItem() const
作用:
- 如果當前列表中有一項被選中,它將返回指向該項的指針。
- 如果沒有項被選中,返回 nullptr。
- “當前項”并不一定是“多選”狀態下選中的所有項之一,而是焦點所在的那一項。
使用示例:
QListWidget *listWidget = new QListWidget(this);// 添加一些項
listWidget->addItem("蘋果");
listWidget->addItem("香蕉");
listWidget->addItem("橘子");// 獲取當前項
QListWidgetItem *item = listWidget->currentItem();
if (item) {qDebug() << "當前選中的項是:" << item->text();
} else {qDebug() << "當前沒有選中任何項";
}
可以在信號 currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) 中使用它,
例如:
connect(listWidget, &QListWidget::currentItemChanged,this, [](QListWidgetItem *current, QListWidgetItem *previous){if (current) {qDebug() << "新選中項:" << current->text();}
});
2.2.2 int QListWidget::currentRow() const
作用:
獲取當前被選中的項在列表中的行號(從 0 開始計數)。
- 如果列表中當前有選中的項,它返回該項的索引(行號)。
- 如果沒有任何項被選中,則返回 -1。
使用示例:
QListWidget *listWidget = new QListWidget(this);// 添加一些項
listWidget->addItem("第一行");
listWidget->addItem("第二行");
listWidget->addItem("第三行");// 設置當前選中第二項(行號 1)
listWidget->setCurrentRow(1);// 獲取當前選中的行號
int row = listWidget->currentRow();
qDebug() << "當前選中項的行號是:" << row;
結合 currentItem() 一起使用:
QListWidgetItem *item = listWidget->currentItem();
int row = listWidget->currentRow();if (item && row != -1) {qDebug() << "當前項內容:" << item->text();qDebug() << "當前項所在行號:" << row;
}
2.2.3 QListWidgetItem *QListWidget::item(int row) const
作用:
- 數 row 是項在列表中的索引,從 0 開始。
- 如果索引有效(0 ≤ row < count),返回對應項的指針。
- 如果索引越界,返回 nullptr。
使用示例:
QListWidget *listWidget = new QListWidget(this);// 添加項
listWidget->addItem("A");
listWidget->addItem("B");
listWidget->addItem("C");// 獲取第 1 行(第二項)
QListWidgetItem *item = listWidget->item(1);
if (item) {qDebug() << "第1行的項是:" << item->text(); // 輸出 "B"
} else {qDebug() << "行號無效,未找到項。";
}
常見用途:
遍歷所有項:
for (int i = 0; i < listWidget->count(); ++i) {QListWidgetItem *item = listWidget->item(i);qDebug() << "第" << i << "行的內容:" << item->text();
}
設置某一行文本:
QListWidgetItem *item = listWidget->item(2);
if (item)item->setText("新內容");
2.2.4 QListWidgetItem *QListWidget::itemAt(const QPoint &p) const
作用:
返回在 QListWidget 中,指定坐標 p(窗口坐標)下的項(QListWidgetItem*)。
- 參數 p 是一個 QPoint,表示相對于 QListWidget 視圖坐標系統中的一個點(例如鼠標點擊的位置)。
- 如果該位置有對應的項,則返回該項的指針;
- 如果該位置沒有任何項(空白區域),則返回 nullptr。
使用示例:
void MyWidget::mousePressEvent(QMouseEvent *event)
{QPoint pos = event->pos(); // 獲取點擊的位置QListWidgetItem *item = myListWidget->itemAt(pos);if (item) {qDebug() << "點擊了項:" << item->text();} else {qDebug() << "點擊的是空白區域";}
}
注意:如果在外部控件中處理鼠標事件,可能需要將坐標從全局或父窗口坐標轉換到 QListWidget 的局部坐標,
例如:
QPoint localPos = listWidget->mapFromGlobal(QCursor::pos());
QListWidgetItem *item = listWidget->itemAt(localPos);
2.2.5 QListWidgetItem *QListWidget::itemAt(int x, int y) const
作用:
返回位于 QListWidget 中指定坐標位置 (x, y) 的項指針(QListWidgetItem*)。
- x 和 y 是相對于 QListWidget 視圖的坐標(通常來源于鼠標事件)。
- 如果該位置有一項,則返回該項的指針;
- 如果該位置是空白區域,則返回 nullptr。
使用示例:
void MyWidget::mousePressEvent(QMouseEvent *event)
{int x = event->x();int y = event->y();QListWidgetItem *item = myListWidget->itemAt(x, y);if (item) {qDebug() << "你點擊了項:" << item->text();} else {qDebug() << "你點擊了空白區域";}
}
2.2.6 QWidget *QListWidget::itemWidget(QListWidgetItem *item) const
作用:
獲取與指定 QListWidgetItem 關聯的自定義子控件(QWidget*)。
- 如果該 item 使用了 setItemWidget() 設置了一個控件,該函數返回該控件;
- 如果該項沒有關聯控件,則返回 nullptr;
- 該函數主要用于實現“列表項嵌套控件”的復雜 UI,例如在列表中顯示按鈕、復選框、進度條等。
使用示例:
// 創建一個 QListWidget 和一個自定義控件
QListWidget *listWidget = new QListWidget(this);
QListWidgetItem *item = new QListWidgetItem(listWidget);QPushButton *button = new QPushButton("點擊我");
listWidget->addItem(item);
listWidget->setItemWidget(item, button);// 獲取這個控件
QWidget *w = listWidget->itemWidget(item);
if (w) {qDebug() << "找到控件類型:" << w->metaObject()->className(); // 輸出 QPushButton
}
典型用途:
實現帶復選框的列表項:
QCheckBox *check = new QCheckBox("選項A");
QListWidgetItem *item = new QListWidgetItem(listWidget);
listWidget->addItem(item);
listWidget->setItemWidget(item, check);
獲取狀態:
QCheckBox *check = qobject_cast<QCheckBox *>(listWidget->itemWidget(item));
if (check && check->isChecked()) {qDebug() << "該項被選中了!";
}
2.2.7 void QListWidget::removeItemWidget(QListWidgetItem *item)
作用:
將綁定在某個 QListWidgetItem 上的子控件(通過 setItemWidget() 設置的 QWidget)從列表項中移除,但不刪除該控件。
- 該函數不會銷毀控件,只是將它從 QListWidget 的布局中移除。
- 如果你需要徹底銷毀控件,應該手動調用 delete。
使用示例:
QListWidgetItem *item = new QListWidgetItem(listWidget);
QPushButton *button = new QPushButton("按鈕");
listWidget->addItem(item);
listWidget->setItemWidget(item, button);// 移除控件
listWidget->removeItemWidget(item);// 控件仍然存在,可以手動銷毀
button->deleteLater();
注意事項:
- removeItemWidget() 不會刪除 QListWidgetItem;
- 也不會刪除綁定的 QWidget;
- 被移除的控件不會自動重新顯示在 UI 中,除非你手動添加到別處;
- 控件的父對象仍是 QListWidget,因此在不需要時應調用 delete 或 deleteLater() 銷毀。
刪除項并清理控件的完整做法:
QWidget *widget = listWidget->itemWidget(item);
listWidget->removeItemWidget(item);
delete widget; // 或 widget->deleteLater();
delete item;
2.2.8 int QListWidget::row(const QListWidgetItem *item) const
作用:
返回指定 QListWidgetItem* 在 QListWidget 中的行號(索引)。
- 行號從 0 開始;
- 如果 item 是當前 QListWidget 中的有效項,則返回其索引;
- 如果該項不在列表中,返回 -1。
使用示例:
QListWidget *listWidget = new QListWidget(this);// 添加項
QListWidgetItem *item1 = new QListWidgetItem("蘋果");
QListWidgetItem *item2 = new QListWidgetItem("香蕉");
listWidget->addItem(item1);
listWidget->addItem(item2);// 獲取某項所在行號
int index = listWidget->row(item2);
qDebug() << "香蕉在第幾行:" << index; // 輸出 1
注意事項:
- 參數必須是 listWidget 中已經存在的項;
- 如果是新創建的項,還未添加進列表,調用 row() 會返回 -1。
2.2.9 QList<QListWidgetItem *> QListWidget::selectedItems() const
作用:
返回當前所有被選中的 QListWidgetItem* 列表。
- 支持單選和多選模式;
- 單選時,返回列表最多包含一個元素;
- 多選時,返回所有選中項;
- 無選中項時,返回空列表。
使用示例:
QList<QListWidgetItem *> selectedItems = listWidget->selectedItems();if (selectedItems.isEmpty()) {qDebug() << "沒有選中任何項";
} else {for (QListWidgetItem *item : selectedItems) {qDebug() << "選中項文本:" << item->text();}
}
多選模式設置示例:
listWidget->setSelectionMode(QAbstractItemView::MultiSelection);
注意事項:
- 返回的是指向項的指針,不是索引;
- 若需刪除選中項,先使用 takeItem() 移除,再刪除指針。
刪除所有選中項示例:
auto selectedItems = listWidget->selectedItems();
for (auto item : selectedItems) {delete listWidget->takeItem(listWidget->row(item));
}
下面是一個完整的 Qt QListWidget 多選操作示例,演示如何設置多選模式,獲取所有選中項,并執行批量刪除操作。
#include <QApplication>
#include <QListWidget>
#include <QPushButton>
#include <QVBoxLayout>
#include <QWidget>
#include <QDebug>class MyWidget : public QWidget {Q_OBJECT
public:MyWidget(QWidget *parent = nullptr) : QWidget(parent) {listWidget = new QListWidget(this);deleteButton = new QPushButton("刪除選中項", this);// 設置多選模式listWidget->setSelectionMode(QAbstractItemView::MultiSelection);// 添加示例項listWidget->addItem("蘋果");listWidget->addItem("香蕉");listWidget->addItem("橘子");listWidget->addItem("葡萄");listWidget->addItem("西瓜");QVBoxLayout *layout = new QVBoxLayout(this);layout->addWidget(listWidget);layout->addWidget(deleteButton);connect(deleteButton, &QPushButton::clicked, this, &MyWidget::deleteSelectedItems);}private slots:void deleteSelectedItems() {// 獲取所有選中的項QList<QListWidgetItem *> selectedItems = listWidget->selectedItems();if (selectedItems.isEmpty()) {qDebug() << "沒有選中任何項。";return;}// 逐個刪除選中項for (QListWidgetItem *item : selectedItems) {// 先從列表中取出,再delete,避免內存泄漏delete listWidget->takeItem(listWidget->row(item));}}private:QListWidget *listWidget;QPushButton *deleteButton;
};int main(int argc, char *argv[]) {QApplication a(argc, argv);MyWidget w;w.show();return a.exec();
}
2.3 選項設置
2.3.1 void QListWidget::setCurrentItem(QListWidgetItem *item)
作用:
設置指定的 QListWidgetItem* 為當前選中項(即焦點所在項)。
- 使該項變為當前項,列表視圖會自動滾動到該項;
- 會觸發 currentItemChanged 信號;
- 如果傳入 nullptr,表示取消當前項的選中。
使用示例:
QListWidget *listWidget = new QListWidget(this);
listWidget->addItem("蘋果");
listWidget->addItem("香蕉");
listWidget->addItem("橘子");QListWidgetItem *item = listWidget->item(1); // 獲取第二項“香蕉”
listWidget->setCurrentItem(item); // 設置“香蕉”為當前選中項
結合信號使用:
connect(listWidget, &QListWidget::currentItemChanged,this, [](QListWidgetItem *current, QListWidgetItem *previous) {if (current) {qDebug() << "當前選中項變更為:" << current->text();}
});
注意事項:
- 只設置當前項,不一定改變“選中狀態”(selection)——視 selectionMode 而定;
- 如果需要同時設置當前項并選中它,可以先調用 setCurrentItem(),然后調用 setItemSelected(item, true)。
選中當前項示例:
listWidget->setCurrentItem(item);
listWidget->setItemSelected(item, true);
2.3.2 void QListWidget::setCurrentItem(QListWidgetItem *item, QItemSelectionModel::SelectionFlags command)
作用:
將指定的 QListWidgetItem* 設置為當前項,并根據 command 參數來控制選中和焦點的行為。
- 這個重載函數允許更精細地控制當前項的選擇和焦點狀態;
- command 是 QItemSelectionModel::SelectionFlags 枚舉類型,常用值包括:
- QItemSelectionModel::Clear — 清除當前選擇;
- QItemSelectionModel::Select — 選擇項;
- QItemSelectionModel::Deselect — 取消選擇;
- QItemSelectionModel::Toggle — 切換選擇狀態;
- QItemSelectionModel::Current — 設置當前項(焦點項)。
常用組合示例:
僅設置當前項(焦點項),不改變選中狀態:
listWidget->setCurrentItem(item, QItemSelectionModel::Current);
設置當前項并選中它:
listWidget->setCurrentItem(item, QItemSelectionModel::Select | QItemSelectionModel::Current);
取消當前項的選中狀態但仍保持當前焦點:
listWidget->setCurrentItem(item, QItemSelectionModel::Deselect | QItemSelectionModel::Current);
使用示例代碼:
QListWidget *listWidget = new QListWidget(this);
listWidget->addItem("蘋果");
listWidget->addItem("香蕉");
listWidget->addItem("橘子");QListWidgetItem *item = listWidget->item(1); // 第二項“香蕉”// 設置“香蕉”為當前項并選中
listWidget->setCurrentItem(item, QItemSelectionModel::Select | QItemSelectionModel::Current);
2.3.3 void QListWidget::setCurrentRow(int row)
作用:
設置 QListWidget 中指定行號(row)的項為“當前項”。
- 會觸發 currentItemChanged() 信號;
- 會自動滾動視圖,使該項可見;
- 并將焦點移動到該項;
- 如果 row 超出范圍(小于 0 或大于等于 count),不會改變當前項。
使用示例:
QListWidget *listWidget = new QListWidget(this);
listWidget->addItem("蘋果");
listWidget->addItem("香蕉");
listWidget->addItem("橘子");// 設置第二項為當前項(行號 1)
listWidget->setCurrentRow(1);
結合信號槽使用:
connect(listWidget, &QListWidget::currentItemChanged,this, [](QListWidgetItem *current, QListWidgetItem *previous) {if (current)qDebug() << "當前項變為:" << current->text();
});
注意事項:
- setCurrentRow() 只設置當前項(有焦點的項),并不影響其他選中項;
- 若在多選模式下使用,僅更改焦點,不會影響多選狀態;
- 如果需要選中該項,可結合使用 setItemSelected() 或使用另一個重載版本 setCurrentRow(int, QItemSelectionModel::SelectionFlags)。
2.3.4 void QListWidget::setCurrentRow(int row, QItemSelectionModel::SelectionFlags command)
作用:
設置 QListWidget 中指定行號 row 對應的項為“當前項”,并根據 command 參數控制其選中狀態或行為。這個函數相比 setCurrentRow(int row) 更加靈活,允許通過 QItemSelectionModel::SelectionFlags 控制選擇行為,例如是否選中該行、是否取消其他選中項、是否切換狀態等。
常用的 SelectionFlags:
來自枚舉 QItemSelectionModel::SelectionFlags,常用值如下:
使用示例
示例 1:設置某行為當前項并選中
listWidget->setCurrentRow(2, QItemSelectionModel::Select | QItemSelectionModel::Current);
示例 2:設置某行為當前項,但取消選中狀態
listWidget->setCurrentRow(1, QItemSelectionModel::Deselect | QItemSelectionModel::Current);
示例 3:只設置當前項(不選中)
listWidget->setCurrentRow(0, QItemSelectionModel::Current);
示例 4:清除所有選中項并設置新當前項
listWidget->setCurrentRow(3, QItemSelectionModel::Clear | QItemSelectionModel::Select | QItemSelectionModel::Current);
2.3.5 void QListWidget::setItemWidget(QListWidgetItem *item, QWidget *widget)
作用:
將一個 QWidget* 控件嵌入到指定的 QListWidgetItem 項上,使該項顯示為該控件。
- 這使你可以在 QListWidget 的每一項中使用如按鈕、復選框、進度條等自定義控件;
- 替代了 QListWidgetItem::setText() 的默認文本顯示方式;
- 一個項只能綁定一個控件;若再次設置會替換原控件。
基本使用示例:
QListWidget *listWidget = new QListWidget(this);// 創建列表項
QListWidgetItem *item = new QListWidgetItem(listWidget);
listWidget->addItem(item);// 創建控件(如按鈕)并設置到該項上
QPushButton *button = new QPushButton("點擊我");
listWidget->setItemWidget(item, button);
更多控件示例:
顯示復選框
QCheckBox *checkBox = new QCheckBox("選項A");
QListWidgetItem *item = new QListWidgetItem(listWidget);
listWidget->addItem(item);
listWidget->setItemWidget(item, checkBox);
顯示進度條
QProgressBar *progress = new QProgressBar();
progress->setValue(70);
QListWidgetItem *item = new QListWidgetItem(listWidget);
listWidget->addItem(item);
listWidget->setItemWidget(item, progress);
注意事項:
- 設置后,item->text() 不會顯示在界面中,控件會完全替代默認顯示;
- 控件將作為 listWidget 的子控件管理,一般不需要手動銷毀;
- 如需移除控件,請使用 removeItemWidget(),如果不再使用應手動 delete 控件。
2.3.6 QListWidgetItem *takeItem(int row)
作用:
用于從列表中移除并返回指定行的 QListWidgetItem 指針,但不刪除它。你可以隨后對這個 item 做進一步處理,比如修改、重新插入或手動刪除。
參數:row:要移除的 item 的索引(從 0 開始)
返回值:
- 返回指向被移除的 QListWidgetItem 的指針;
- 如果 row 無效(超出范圍),返回 nullptr。
常見用途:
- 移除某項后,保存或修改再重新插入;
- 手動刪除 item(注意:你拿到的是堆對象,需要 delete);
- 移動 item(先 takeItem,再 insertItem)。
示例:移除并刪除某一項
int row = 2;
QListWidgetItem *item = listWidget->takeItem(row);
if (item) {delete item; // 必須手動釋放內存!
}
示例:將一項從位置 A 移到位置 B
int from = 2;
int to = 0;
QListWidgetItem *item = listWidget->takeItem(from);
if (item) {listWidget->insertItem(to, item);
}
注意事項:
- 內存釋放 takeItem() 不刪除 item,你必須手動 delete
- 信號響應 takeItem() 不會觸發 itemChanged 之類信號
- 重新插入 可以 insertItem() 插回
四、QListWidget的信號與槽
4.1 void currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
作用:用于通知當前選中項發生變化時的事件。
參數說明:
觸發時機:
- 用戶用鼠標或鍵盤改變了選中項;
- 程序調用了 setCurrentItem() 或 setCurrentRow();
- 初次選中項或取消選中時,previous 或 current 為 nullptr。
示例:連接信號槽
示例 1:lambda 寫法(推薦)
connect(listWidget, &QListWidget::currentItemChanged,this, [](QListWidgetItem *current, QListWidgetItem *previous) {if (current) {qDebug() << "當前項文本:" << current->text();}if (previous) {qDebug() << "前一項文本:" << previous->text();}
});
示例 2:使用自定義槽函數
// 聲明槽函數
void onCurrentItemChanged(QListWidgetItem *current, QListWidgetItem *previous);// 連接信號
connect(listWidget, &QListWidget::currentItemChanged,this, &YourClass::onCurrentItemChanged);// 實現槽函數
void YourClass::onCurrentItemChanged(QListWidgetItem *current, QListWidgetItem *previous) {if (current)qDebug() << "當前項:" << current->text();if (previous)qDebug() << "之前項:" << previous->text();
}
4.2 void currentRowChanged(int currentRow)
作用:用于在當前選中行發生變化時通知你當前選中的行號。
參數說明:
觸發時機:
- 用戶點擊不同的項;
- 使用鍵盤上下箭頭切換項;
- 程序調用 setCurrentRow() 或 setCurrentItem();
示例:使用 lambda 響應行號變化
connect(listWidget, &QListWidget::currentRowChanged,this, [](int row) {qDebug() << "當前選中行:" << row;
});
示例:使用槽函數
// 連接信號
connect(listWidget, &QListWidget::currentRowChanged,this, &YourClass::onCurrentRowChanged);// 槽函數定義
void YourClass::onCurrentRowChanged(int row) {qDebug() << "當前選中行號:" << row;QListWidgetItem* item = listWidget->item(row);if (item)qDebug() << "對應文本:" << item->text();
}
4.3 void itemActivated(QListWidgetItem *item)
作用:當用戶激活某個條目時發出,常用于響應用戶雙擊某項或按下回車鍵激活當前項。
觸發方式:
示例:連接 itemActivated 信號
使用 lambda:
connect(listWidget, &QListWidget::itemActivated,this, [](QListWidgetItem *item) {if (item)qDebug() << "激活項文本:" << item->text();
});
使用自定義槽函數:
connect(listWidget, &QListWidget::itemActivated,this, &YourClass::onItemActivated);void YourClass::onItemActivated(QListWidgetItem *item) {if (item)qDebug() << "用戶激活了:" << item->text();
}
常見用途:
- 打開對應的詳細界面(如文件管理器中打開文件);
- 響應確認操作(如雙擊打開圖片);
- 與 QStackedWidget 聯動切換內容頁面;
- 啟動編輯、顯示彈窗、觸發某項動作等。
對比其他信號:
4.4 void itemChanged(QListWidgetItem *item)
作用:用于在某個條目的數據內容發生變化時發出,尤其適用于文本修改或勾選狀態改變等情況。
觸發條件:
前提條件:必須啟用可更改標志
為使條目可編輯或勾選,你必須設置適當的 Qt::ItemFlags,例如:
QListWidgetItem* item = new QListWidgetItem("默認文本");
item->setFlags(item->flags() | Qt::ItemIsEditable | Qt::ItemIsUserCheckable);
listWidget->addItem(item);
示例:響應 item 內容變更
connect(listWidget, &QListWidget::itemChanged,this, [](QListWidgetItem *item) {qDebug() << "項內容發生改變:" << item->text();
});
輸出結果:
示例:檢測復選框狀態改變
輸出結果:
注意事項:
- 即使程序修改數據也會觸發信號;
- 如果不希望程序內設置數據時觸發信號,可在修改前使用 blockSignals(true) 臨時關閉。
listWidget->blockSignals(true);
item->setText("程序修改的文本");
listWidget->blockSignals(false);
4.5 void itemClicked(QListWidgetItem *item)
作用:當用戶點擊列表中的某一項時發出。這是一個非常常用的信號,用于處理用戶點擊操作的邏輯響應。
參數說明:
觸發條件:
- 用戶用鼠標左鍵點擊某個列表項時觸發;
- 程序調用 setCurrentItem() 不會觸發;
- 只響應用戶行為,不響應程序設置。
示例:使用 lambda 響應點擊
connect(listWidget, &QListWidget::itemClicked,this, [](QListWidgetItem *item) {if (item)qDebug() << "用戶點擊了項:" << item->text();
});
示例:自定義槽函數響應
connect(listWidget, &QListWidget::itemClicked,this, &YourClass::onItemClicked);void YourClass::onItemClicked(QListWidgetItem *item) {qDebug() << "被點擊的項文本:" << item->text();
}
4.6 void itemDoubleClicked(QListWidgetItem *item)
作用:用于在用戶雙擊某個列表項時發出,常用于打開詳情、進入編輯模式、或執行確認操作等。
觸發條件:
參數說明:
示例:使用 lambda 處理雙擊
connect(listWidget, &QListWidget::itemDoubleClicked,this, [](QListWidgetItem *item) {if (item)qDebug() << "用戶雙擊了項:" << item->text();
});
示例:自定義槽函數處理雙擊行為
connect(listWidget, &QListWidget::itemDoubleClicked,this, &YourClass::onItemDoubleClicked);void YourClass::onItemDoubleClicked(QListWidgetItem *item) {if (item)qDebug() << "雙擊觸發操作:" << item->text();
}
4.7 void itemEntered(QListWidgetItem *item)
作用:當鼠標光標進入某一項區域時發出,可用于實現鼠標懸浮提示、預覽、動態樣式等效果。
使用前提:
要使用 itemEntered 信號,必須啟用列表控件的“鼠標追蹤模式”:
listWidget->setMouseTracking(true);
否則你將不會收到任何鼠標進入的事件。
觸發條件:
示例:連接信號處理懸浮提示
listWidget->setMouseTracking(true); // 必須啟用鼠標追蹤connect(listWidget, &QListWidget::itemEntered,this, [](QListWidgetItem *item) {if (item)qDebug() << "鼠標進入項:" << item->text();
});
示例:懸浮顯示 tooltip 提示
connect(listWidget, &QListWidget::itemEntered,this, [](QListWidgetItem *item) {if (item)QToolTip::showText(QCursor::pos(), "提示:" + item->text());
});
常見用途:
- 鼠標懸浮項高亮顯示;
- 動態顯示 tooltip、縮略圖、預覽信息;
- 進入某項區域觸發臨時動作或動畫;
- 聯動其他控件響應懸停項。
4.8 void itemPressed(QListWidgetItem *item)
作用:當用戶按下鼠標按鈕(通常是左鍵)在某個列表項上時觸發,也就是說這個信號在鼠標按下瞬間發出,而不是釋放或點擊完成
觸發條件:
參數說明:
示例:使用 lambda 連接信號
connect(listWidget, &QListWidget::itemPressed,this, [](QListWidgetItem *item) {if (item)qDebug() << "鼠標按下項:" << item->text();
});
示例:使用自定義槽函數
connect(listWidget, &QListWidget::itemPressed,this, &YourClass::onItemPressed);void YourClass::onItemPressed(QListWidgetItem *item) {if (item)qDebug() << "按下了項:" << item->text();
}
常見用途:
- 實現拖拽開始的檢測(配合 mouseMoveEvent);
- 右鍵菜單彈出前的準備工作;
- 點擊按下時做一些視覺反饋(比如按下陰影效果);
- 處理復雜點擊行為(例如區分按下和釋放事件)。
4.9 void itemSelectionChanged()
作用:當列表中選中項的集合發生變化時觸發。無論是單選還是多選模式,只要選中項發生增減或變化,這個信號都會被發出。
觸發條件:
- 用戶用鼠標或鍵盤改變選中項(單選或多選);
- 程序調用諸如 setCurrentItem(), setItemSelected(), clearSelection() 等函數改變選中狀態;
- 只要選中項集合變化就會觸發。
示例:響應選中項集合變化
connect(listWidget, &QListWidget::itemSelectionChanged,this, [=]() {QList<QListWidgetItem*> selectedItems = listWidget->selectedItems();qDebug() << "當前選中項數量:" << selectedItems.size();for (auto item : selectedItems) {qDebug() << "選中項文本:" << item->text();}
});