文章目录

    • 一、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)

作用:用于通知当前选中项发生变化时的事件。

参数说明:
- List item

触发时机:

  • 用户用鼠标或键盘改变了选中项;
  • 程序调用了 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)

作用:当用户按下鼠标按钮(通常是左键)在某个列表项上时触发,也就是说这个信号在鼠标按下瞬间发出,而不是释放或点击完成

触发条件:

  • List 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();}
});

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。
如若转载,请注明出处:http://www.pswp.cn/pingmian/87616.shtml
繁体地址,请注明出处:http://hk.pswp.cn/pingmian/87616.shtml
英文地址,请注明出处:http://en.pswp.cn/pingmian/87616.shtml

如若内容造成侵权/违法违规/事实不符,请联系英文站点网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

React Native 亲切的组件们(函数式组件/class组件)和陌生的样式

写多了taro, 看见react native中的组件好亲切啊&#xff0c;几乎一模一样。 一、函数式组件 — 常用 1&#xff09;无状态&#xff0c;每次刷新都是生成一个新的状态 2&#xff09;基于状态变化的管理 3&#xff09;简洁&#xff0c;代码少&#xff0c;易于服用 import Reac…

Spring boot之身份验证和访问控制

本文笔记跟随于遇见狂神说老师的视频 一.SpringSecurity&#xff08;安全&#xff09; 1.相关概念 在web开发中&#xff0c;安全第一位&#xff0c;有简单的方法&#xff0c;比如&#xff1a;拦截器&#xff0c;过滤器 也有安全框架&#xff0c;比如&#xff1a;SpringSecu…

C#使用开源框架NetronLight绘制流程图

之前使用MindFusion.Diagramming绘制流程图确认很方便&#xff0c;只能试用版&#xff0c;如果长期使用&#xff0c;需要收费。 C#使用MindFusion.Diagramming框架绘制流程图(2):流程图示例_c# 画流程图控件-CSDN博客 这里找一个简易开源框架NetronLight&#xff0c;GIT下载地…

支持向量机(SVM)在脑部MRI分类中的深入应用与实现

🧑 博主简介:CSDN博客专家、CSDN平台优质创作者,高级开发工程师,数学专业,10年以上C/C++, C#, Java等多种编程语言开发经验,拥有高级工程师证书;擅长C/C++、C#等开发语言,熟悉Java常用开发技术,能熟练应用常用数据库SQL server,Oracle,mysql,postgresql等进行开发应用…

AtCoder AT_abc413_c [ABC413C] Large Queue 题解

题目大意 有一个初始为空的序列 A A A&#xff0c; Q Q Q 次操作分为两类&#xff1a; 第一类&#xff1a;将 c c c 个 x x x 放到 A A A 的末尾。第二类&#xff1a;将前 k k k 个数的和输出并移除它们。 思路 这是一个求和问题&#xff0c;想到的第一个思路是前缀和…

「源力觉醒 创作者计划」_文心大模型开源:开启 AI 新时代的大门

在人工智能的浩瀚星空中&#xff0c;大模型技术宛如一颗璀璨的巨星&#xff0c;照亮了无数行业前行的道路。自诞生以来&#xff0c;大模型凭借其强大的语言理解与生成能力&#xff0c;引发了全球范围内的技术变革与创新浪潮。百度宣布于 6 月 30 日开源文心大模型 4.5 系列&…

Git 怎么判断是否冲突?

&#x1f4cc; [Q&A] Git 怎么判断是否冲突&#xff1f; Git 使用的是三路合并算法&#xff08;Three-way Merge&#xff09;&#xff0c;它比较&#xff1a; 共同祖先提交&#xff08;base&#xff09; 当前分支的改动&#xff08;ours&#xff09; 被合并分支的改动&am…

在sf=0.1时测试fireducks、duckdb、polars的tpch

首先&#xff0c;从https://github.1git.de/fireducks-dev/polars-tpch下载源代码包&#xff0c;将其解压缩到/par/fire目录。 然后进入此目录&#xff0c;运行 SCALE_FACTOR0.1 ./run-fireducks.sh&#xff0c;脚本会首先安装所需的包&#xff0c;编译tpch的数据生成器&#x…

AWS多账号管理终极指南:从安装配置到高效使用

引言:为什么需要多账号管理? 在云计算时代,企业使用多个AWS账号已成为最佳实践。根据AWS Well-Architected Framework,多账号架构可以: 实现环境隔离(生产/测试/开发)满足不同业务单元的安全要求简化资源管理和成本分配符合合规性要求(如SOC2、ISO27001)本文将手把手…

UE5音频技术

1 . 调制器 Modulator 调整参数 调制器可以使声音每次音高都不一样 2. 随机 节点 3. 混音器 Mixer 混合两个音频 4. 串联器 Concatenator 按循序播放 5.多普勒 Doppler 根据距离音频变化 6.包络线 Enveloper 武器充能发射 7.混响

创客匠人视角:创始人 IP 打造与知识变现的培训赋能体系

在知识付费行业进入精耕期的当下&#xff0c;为何部分企业投入大量培训却收效甚微&#xff1f;创客匠人 CEO 老蒋通过服务 5W 知识博主的经验指出&#xff1a;唯有将创始人 IP 思维与培训体系深度融合&#xff0c;才能让培训成为知识变现的 “转换器”。一、内训体系重构&…

基于Java+SpringBoot的三国之家网站

源码编号&#xff1a;S591 源码名称&#xff1a;基于SpringBoot的三国之家网站 用户类型&#xff1a;双角色&#xff0c;用户、管理员 数据库表数量&#xff1a;20 张表 主要技术&#xff1a;Java、Vue、ElementUl 、SpringBoot、Maven 运行环境&#xff1a;Windows/Mac、…

推荐算法系统系列五>推荐算法CF协同过滤用户行为挖掘(itembase+userbase)

注&#xff1a;此文章内容均节选自充电了么创始人&#xff0c;CEO兼CTO陈敬雷老师的新书《GPT多模态大模型与AI Agent智能体》&#xff08;跟我一起学人工智能&#xff09;【陈敬雷编著】【清华大学出版社】 配套视频 推荐算法系统实战全系列精品课【陈敬雷】 文章目录 推荐算…

pytest之fixture中yield详解

1. fixture——yield介绍 fixture的teardown操作并不是独立的函数&#xff0c;用yield关键字呼唤teardown操作。前面通过fixture实现了在每个用例之前执行初始化操作&#xff0c;那么用例执行完之后&#xff0c;如需要清除数据&#xff08;或还原&#xff09;操作&#xff0c;…

Nginx 动静分离原理与工作机制详解:从架构优化到性能提升

前言&#xff1a;在 Web 应用架构不断演进的今天&#xff0c;如何高效处理日益增长的访问量和复杂的业务逻辑&#xff0c;成为开发者必须面对的挑战。当我们在浏览器中打开一个网页&#xff0c;那些直观可见的 HTML 页面、精美绝伦的图片、流畅运行的 JavaScript 脚本&#xff…

介绍electron

一、Electron 是什么&#xff1f; Electron 是一个基于 Chromium 和 Node.js 的框架&#xff0c;允许开发者使用前端技术&#xff08;HTML/CSS/JavaScript&#xff09;构建原生桌面应用。其核心优势在于&#xff1a; 跨平台&#xff1a;一次开发&#xff0c;生成 Windows、ma…

DeepSeek与诡秘之主

1、大模型像个腐儒 其实从大模型的训练方式来看&#xff0c;它算不上天赋异禀。尤其在成长阶段&#xff0c;大模型那种种令人惊艳的表现&#xff0c;足够让人误以为这是个天才。 可人这种生物&#xff0c;注定是贪婪的。在大模型成长后期&#xff0c;伴随着各种技巧的验证&…

动手实践OpenHands系列学习笔记5:代理系统架构概述

笔记5&#xff1a;代理系统架构概述 一、引言 AI代理系统是一种能够自主执行任务的智能软件架构&#xff0c;OpenHands作为AI驱动的软件开发代理平台&#xff0c;拥有完整的代理系统架构设计。本笔记将探讨AI代理架构的基本原理&#xff0c;并通过分析OpenHands核心架构&…

智能电动汽车 --- 车辆网关路由缓存

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 简单,单纯,喜欢独处,独来独往,不易合同频过着接地气的生活,除了生存温饱问题之外,没有什么过多的欲望,表面看起来很高冷,内心热情,如果你身…

Spring中实现依赖注入(DI)的三种方式

1. Autowired 字段注入&#xff08;不推荐&#xff09;​ Service public class UserService {Autowired // 直接在字段上注入private UserRepository userRepository; } ​​原理​​&#xff1a;Spring 启动时扫描所有 Component、Service 等注解的类&#xff0c;发现 Aut…