对于Qt:QListWidget常见属性以及QListWidgetItem类的解析

开篇介绍:

hello 大家,本篇博客我们来学习QListWidget常见属性以及QListWidgetItem类。

在 Qt 桌面应用开发中,我们除了会遇到 "单元素输入"(如 QLineEdit、QSlider、QDial)的需求,还会经常遇到一个更通用、更常见、更核心的需求:展示和管理一个纵向的列表------ 比如展示文件列表、展示联系人列表、展示播放列表、展示设置选项列表、展示搜索结果列表。在这些场景下,你需要一个控件能把多个条目纵向排列,支持用户选中、点击、双击、新增、删除条目 ------ 这正是 QListWidget 的用武之地。

为了满足这个需求,Qt 专门为我们提供了一个开箱即用、功能强大、使用最广泛的列表控件:QListWidget(列表控件)。QListWidget 就像 "一个纵向排列的清单"------ 它能显示多个条目,每个条目可以是纯文本,也可以是 "图标 + 文本";它支持用户选中条目、点击条目、双击条目;它支持在末尾添加条目、在任意位置插入条目、删除指定位置的条目;它支持自动排序、条目换行、自定义条目间距和对齐方式。

而 QListWidget 中的每一个条目,都是由 QListWidgetItem(列表项类) 来表示的 ------QListWidgetItem 是 QListWidget 的最小组成单元,核心由 "文本 + 图标" 构成,你可以单独设置每个条目的字体、图标、显示状态、尺寸、选中状态、文本对齐方式。

很多新手刚接触 QListWidget 和 QListWidgetItem 时,会觉得它们很简单 ------ 不就是一个列表吗?拖上去,addItem 几个字符串,连接信号,就完事了。但用起来才发现,这里面有很多实用的细节和坑:比如 QListWidgetItem 必须用 new 创建,不能是栈上的对象,否则界面上看不到条目;比如 takeItem 只是把条目从列表里移除,不会自动释放内存,必须手动 delete;比如 currentItem 可能返回 nullptr,必须先判空再操作,否则程序会崩溃;比如行号是从 0 开始计数的,不是从 1 开始;比如开启 sortingEnabled 后,新增条目会自动排序,原有的行号会失效。

别担心!这篇文章我会先讲 QListWidgetItem 类的核心方法 (setText、setFont、setIcon、setHidden、setSizeHint、setSelected、setTextAlignment),再讲 QListWidget 的核心属性 (currentRow、count、itemAlignment、selectRectVisible、spacing、sortingEnabled、isWrapping),接着讲 QListWidget 的核心方法 (addItem、currentItem、setCurrentItem、setCurrentRow、insertItem、item、takeItem),最后讲 QListWidget 的核心交互信号 (currentItemChanged、currentRowChanged、itemClicked、itemDoubleClicked、itemEntered、itemPressed、itemSelectionChanged、currentTextChanged)。

话不多说,我们正式开始!


第一章 先搞懂基础:QListWidget 和 QListWidgetItem 是什么?

在讲具体内容之前,我们必须先搞懂两个最基础、最重要的问题:QListWidget 是用来做什么的?QListWidgetItem 是用来做什么的?以及,它们和 QListView 的关系是什么?

1.1 QListWidget 的核心定位

QListWidget 是 Qt Widgets 模块中用于纵向展示和管理多个条目的核心通用控件 ------ 它继承自 QListView(列表视图),但比 QListView 更简单、更易用,因为它内置了 "条目管理" 的功能,不需要你手动实现数据模型(Model)和视图(View)的分离。

通俗理解:QListWidget 就像 "我们平时写的购物清单""手机上的联系人列表""音乐播放器的播放列表"------ 它是一个纵向排列的列表,每个条目占一行;你可以在清单里添加新的一行,也可以删掉某一行;你可以点击某一行选中它,也可以双击某一行执行操作;它支持自动排序,也支持条目多列显示。

QListWidget 内置了非常多的功能,不需要你手动实现:

  • 它支持在列表末尾 添加条目(addItem),也支持在任意位置 插入条目(insertItem);
  • 它支持删除指定位置 的条目(takeItem);
  • 它支持获取当前选中 的条目(currentItem)或选中的行号 (currentRow);
  • 它支持通过行号 获取对应的条目(item);
  • 它支持统计列表中总共有多少行 (count);
  • 它支持设置条目之间的间距 (spacing)、条目的整体对齐方式 (itemAlignment);
  • 它支持自动排序 (sortingEnabled)、条目换行 (isWrapping);
  • 它支持丰富的交互信号:选中变更、点击、双击、鼠标悬浮等;
  • 它的样式可以通过 QSS(Qt 样式表)完全自定义。

总之,QListWidget 是桌面端 "纵向展示和管理多个条目" 场景的通用首选组件------ 只要是想展示一个列表,用 QListWidget 就对了。

1.2 QListWidgetItem 的核心定位

QListWidgetItem 是 Qt 中表示 QListWidget 中单个条目的核心类------ 它是 QListWidget 的最小组成单元,每个 QListWidgetItem 对应列表中的一行。

通俗理解:QListWidgetItem 就像 "购物清单里的每一行纸"------ 这张纸上可以写文字(setText),可以贴图标(setIcon),可以设置字体(setFont),可以设置对齐方式(setTextAlignment);你可以把这张纸藏起来(setHidden),也可以把它标记为 "已选中"(setSelected);你还可以设置这张纸的大小(setSizeHint)。

QListWidgetItem 的核心特征非常简单:

  • 它本质上是一个 "文本 + 图标" 的组合体 ------ 这是它最核心的视觉内容;
  • 每个条目可以独立设置样式和状态------ 你可以让第一个条目是红色字体,第二个条目是蓝色字体,第三个条目带图标,第四个条目隐藏;
  • 它的内存由 QListWidget 管理(通过 addItem 添加后)------ 但通过 takeItem 移除后,需要你手动释放。

1.3 QListWidget 和 QListView 的关系(必知!)

  • QListWidget 是 QListView 的子类 ------ 它在 QListView 的基础上,内置了一个简单的数据模型(QStandardItemModel),让你可以直接操作条目,而不需要手动实现 Model/View 架构;
  • QListWidget 比 QListView 更简单、更易用------ 如果你只是想展示一个简单的列表,不需要复杂的数据模型,用 QListWidget 就够了;如果你需要展示大量数据(比如成千上万条),或者需要自定义数据模型,再考虑用 QListView + 自定义 Model。

1.4 一个超级重要的注意事项

在正式开始之前,有一个超级重要、新手最容易踩坑、一踩就崩溃的注意事项,必须开篇就讲,刻在脑子里:

严格注意!我们创建的 QListWidgetItem 对象,不能是栈上的对象,必须要用 new 出来的 QListWidgetItem!

否则代码结束后,这些局部对象会被自动销毁,QListWidget 里保存的指针就变成了无效地址,所以界面上看不到这些条目!

通俗理解:你不能把一张 "临时的纸"(栈对象)交给清单保管,因为清单还没保存好,这张纸就被你扔了(自动销毁);你必须把一张 "动态分配的纸"(new 出来的堆对象)交给清单,清单会一直保管它,直到你把它抽走(takeItem)。

错误示例(栈对象,界面上看不到!):

复制代码
// 错误!栈上创建的 item,函数结束后自动销毁
QListWidgetItem item("错误示例");
ui->listWidget->addItem(&item); // 界面上看不到!

正确示例(堆对象,界面上正常显示!):

复制代码
// 正确!new 出来的 item,交给 QListWidget 管理
QListWidgetItem* item = new QListWidgetItem("正确示例");
ui->listWidget->addItem(item); // 界面上正常显示!

这个注意事项超级重要,后面讲 addItem 和 insertItem 时我还会再强调,但现在必须先记住!


第二章 QListWidgetItem 类核心方法详解

好,我们正式开始!按照你提供的顺序,我们首先讲 QListWidgetItem 类的核心方法------ 因为要往 QListWidget 里添加条目,首先得搞懂条目本身怎么设置。QListWidgetItem 的方法不多,但都很实用,核心围绕 "文本、图标、字体、状态、尺寸、对齐" 展开。


2.1 方法一:setText () & text ()------ 设置 / 获取条目文本

2.1.1 方法的核心定义

setText() 是 QListWidgetItem 最基础、最常用、最高频 的方法 ------ 它用于设置列表项的核心显示文本;text() 是对应的获取方法,用于获取当前条目显示的文本。

通俗理解:setText() 就像 "在清单的这一行纸上写字"------ 你想让这一行显示什么,就写什么;text() 就像 "读这一行纸上写的是什么字"。

这里有几个超级重要的规则,必须牢记:

  1. 文本是条目的核心标识------ 未设置时条目为空,显示为空白行;
  2. 支持普通字符串和富文本(HTML 格式) ------ 你可以写普通的文字,也可以写简单的 HTML 标签(如 <b> 加粗、<i> 斜体、<font> 改颜色);
  3. 支持 UTF-8 编码------ 可以包含中文、特殊字符,不会乱码(只要你的源文件编码是 UTF-8,Qt 默认支持);
  4. 文本过长时会自动截断 ------ 如果文本太长,列表项会自动截断并显示省略号(...),你可以通过 setSizeHint() 扩大条目尺寸来避免。
2.1.2 关联 API 详解(逐词逐句,零模糊)

setText() 和 text() 是一对配套的方法,我们逐个来讲:

1. 设置条目显示文本:void setText (const QString &text)

函数原型:

复制代码
void QListWidgetItem::setText(const QString &text);

逐词逐句底层解析:

  • void:函数没有返回值,只是执行 "设置文本" 的操作;
  • QListWidgetItem:::说明这个函数是 QListWidgetItem 类的成员函数,只能用 QListWidgetItem 对象调用;
  • setText():函数名,很直观,就是 "设置文本" 的意思;
  • const QString &text:入参,text 是你要显示的文本内容,QString 是 Qt 中的字符串类,const & 是常量引用,避免拷贝。

参数说明:

  • text:要显示的文本内容,QString 类型;
  • 支持普通字符串,也支持简单的 HTML 富文本标签;
  • 可以是空字符串(显示为空白行)。
2. 获取条目显示文本:QString text () const

函数原型:

复制代码
QString QListWidgetItem::text() const;

逐词逐句底层解析:

  • QString:返回值类型,返回当前条目显示的文本;
  • QListWidgetItem:::成员函数;
  • text():函数名,"获取文本" 的意思;
  • const:常成员函数,不会修改条目状态。

返回值说明:

  • 返回 QString 类型的字符串;
  • 就是你之前通过 setText() 设置的内容。
2.1.3 使用示例
复制代码
#include <QListWidgetItem>

// 示例1:设置普通文本
QListWidgetItem* item1 = new QListWidgetItem();
item1->setText("普通文本条目");
ui->listWidget->addItem(item1);

// 示例2:设置富文本(带颜色、加粗)
QListWidgetItem* item2 = new QListWidgetItem();
item2->setText("<font color='red'><b>富文本条目(红色加粗)</b></font>");
ui->listWidget->addItem(item2);

// 示例3:获取条目的文本并打印
QString text = item1->text();
qDebug() << "条目1的文本:" << text; // 输出"普通文本条目"
2.1.4 关键注意事项(必知!)
  1. 富文本支持(超级重要!) :仅支持基础 HTML 标签(<b>/<i>/<font> 等),复杂标签(如 <table>、<img>)可能无法渲染;
  2. 文本截断(超级重要!) :文本过长时会自动截断并显示省略号,可通过 setSizeHint() 扩大尺寸避免;
  3. 编码适配(超级重要!):确保源文件编码为 UTF-8,避免中文乱码(Qt Creator 默认是 UTF-8,没问题);
  4. 空字符串:可以设置为空字符串,条目显示为空白行。

2.2 方法二:setFont () & font ()------ 设置 / 获取条目字体

2.2.1 方法的核心定义

setFont() 是 QListWidgetItem 用于自定义单个条目字体样式 的方法 ------ 你可以设置字体的家族(如微软雅黑、Arial)、大小(如 12 号、14 号)、粗细(如粗体、正常)、是否斜体、是否下划线等;font() 是对应的获取方法。

通俗理解:setFont() 就像 "给这一行纸上的字换字体"------ 你可以让这一行的字更大、更粗、换一种字体;font() 就像 "看看这一行用的是什么字体"。

这里有几个超级重要的规则,必须牢记:

  1. 优先级高于全局字体------ 单个条目的字体优先级高于 QListWidget 的全局字体,更高于应用程序的默认字体;
  2. 未单独设置时继承父控件字体------ 如果你没给这个条目单独设置字体,它会自动用 QListWidget 的字体;
  3. QFont 仅控制字体样式,不控制颜色 ------ 注意!字体颜色不是通过 QFont 设置的,而是通过 setForeground() 设置的(比如 item->setForeground(Qt::red) 把文本设为红色);
  4. 设置后立即生效 ------ 调用 setFont() 后,列表项的视觉效果会立即刷新,无需额外刷新控件。
2.2.2 关联 API 详解(逐词逐句,零模糊)
1. 设置条目字体样式:void setFont (const QFont &font)

函数原型:

复制代码
void QListWidgetItem::setFont(const QFont &font);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidgetItem:::成员函数;
  • setFont():函数名,"设置字体" 的意思;
  • const QFont &font:入参,font 是 QFont 类型的对象,包含字体的所有样式信息。

参数说明:

  • font:QFont 类型,包含字体家族、大小、粗细、斜体、下划线等样式;
  • 你可以通过 QFont 的构造函数或 setFamily()、setPointSize()、setBold() 等方法来设置。
2. 获取条目字体样式:QFont font () const

函数原型:

复制代码
QFont QListWidgetItem::font() const;

逐词逐句底层解析:

  • QFont:返回值类型,返回当前条目的字体样式;
  • QListWidgetItem:::成员函数;
  • font():函数名,"获取字体" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 QFont 类型的对象;
  • 就是你之前通过 setFont() 设置的内容,未设置则返回父控件的字体。
2.2.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QFont>

// 创建条目
QListWidgetItem* item = new QListWidgetItem("自定义字体条目");

// 创建 QFont 对象并设置样式
QFont font;
font.setFamily("微软雅黑");       // 字体家族:微软雅黑
font.setPointSize(14);            // 字体大小:14 号
font.setBold(true);                // 字体粗细:粗体
font.setItalic(true);              // 是否斜体:是

// 给条目设置字体
item->setFont(font);

// 添加到列表
ui->listWidget->addItem(item);

// 获取并打印字体信息
QFont currentFont = item->font();
qDebug() << "字体家族:" << currentFont.family();
qDebug() << "字体大小:" << currentFont.pointSize();
2.2.4 关键注意事项(必知!)
  1. 优先级(超级重要!):单个条目字体 > QListWidget 全局字体 > 应用程序默认字体;
  2. 颜色设置(超级重要!) :QFont 仅控制字体样式,文本颜色需通过 setForeground() 设置,不是 setFont()!
  3. 动态生效:设置后立即刷新视觉效果,无需额外操作;
  4. 未设置则继承:未单独设置字体时,继承 QListWidget 的全局字体。

2.3 方法三:setIcon () & icon ()------ 设置 / 获取条目图标

2.3.1 方法的核心定义

setIcon() 是 QListWidgetItem 用于为条目添加 / 修改显示图标 的方法 ------ 图标会显示在文本的左侧(默认布局),是实现 "图标 + 文本" 列表项的核心方法;icon() 是对应的获取方法。

通俗理解:setIcon() 就像 "在清单这一行纸的左边贴一张小图片"------ 比如文件列表里的文件夹图标、音乐列表里的音符图标;icon() 就像 "看看这一行贴的是什么图片"。

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 图标显示在文本左侧(默认布局)------ 这是 QListWidget 的默认布局,图标在左,文本在右;
  2. 未设置时仅显示文本------ 如果你没给条目设置图标,它就只显示文本,左边是空的;
  3. 图标显示尺寸由 QListWidget 全局控制!(超级重要!说三遍!) :
    • 这点非常容易误解!单个条目无法单独设置图标的显示尺寸!
    • 所有条目的图标显示尺寸由 QListWidget 的 setIconSize() 方法全局统一控制;
    • 比如你调用 ui->listWidget->setIconSize(QSize(24, 24)),所有条目的图标都会显示为 24x24 像素;
  4. 支持多种图标来源 ------ 你可以用资源文件(:/" 开头)、本地图片(完整路径)、系统图标(QStyle::standardIcon()`);
  5. QIcon 自动适配不同显示状态 ------QIcon 会自动适配条目的 "选中 / 未选中" 状态,显示不同的图标(如果你通过 QIcon::addPixmap() 自定义了状态图标);如果没自定义,就显示同一个图标。
2.3.2 关联 API 详解(逐词逐句,零模糊)
1. 设置条目显示图标:void setIcon (const QIcon &icon)

函数原型:

复制代码
void QListWidgetItem::setIcon(const QIcon &icon);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidgetItem:::成员函数;
  • setIcon():函数名,"设置图标" 的意思;
  • const QIcon &icon:入参,icon 是 QIcon 类型的对象。

参数说明:

  • icon:QIcon 类型,支持资源文件、本地图片、系统图标等多种来源。
2. 获取条目显示图标:QIcon icon () const

函数原型:

复制代码
QIcon QListWidgetItem::icon() const;

逐词逐句底层解析:

  • QIcon:返回值类型,返回当前条目的图标;
  • QListWidgetItem:::成员函数;
  • icon():函数名,"获取图标" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 QIcon 类型的对象;
  • 未设置图标则返回空的 QIcon。
2.3.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QIcon>
#include <QApplication>
#include <QStyle>

// 先设置 QListWidget 的全局图标尺寸(超级重要!所有条目共用!)
ui->listWidget->setIconSize(QSize(32, 32)); // 图标显示为 32x32 像素

// 示例1:使用资源文件图标(路径以 :/ 开头,需先在 .qrc 文件中配置)
QListWidgetItem* item1 = new QListWidgetItem("资源图标条目");
item1->setIcon(QIcon(":/images/folder.png")); // 假设资源文件里有 folder.png
ui->listWidget->addItem(item1);

// 示例2:使用本地图片(传入完整路径)
QListWidgetItem* item2 = new QListWidgetItem("本地图片条目");
item2->setIcon(QIcon("C:/Users/Win/Desktop/icon.jpg")); // 本地图片完整路径
ui->listWidget->addItem(item2);

// 示例3:使用系统图标(通过 QStyle 获取,无需额外图片文件)
QListWidgetItem* item3 = new QListWidgetItem("系统图标条目");
// 获取系统标准文件图标
QIcon systemIcon = QApplication::style()->standardIcon(QStyle::SP_FileIcon);
item3->setIcon(systemIcon);
ui->listWidget->addItem(item3);
2.3.4 关键注意事项(必知!)
  1. 图标显示尺寸由 QListWidget 全局控制!(超级重要!说三遍!) :单个条目无法单独设置,必须用 ui->listWidget->setIconSize() 全局设置!
  2. 图标来源(超级重要!) :资源文件路径以 :/ 开头,本地图片需传入完整路径,系统图标通过 QStyle::standardIcon() 获取;
  3. 默认布局:图标显示在文本左侧;
  4. QIcon 自动适配状态 :可通过 QIcon::addPixmap() 自定义选中 / 未选中状态的不同图标。

2.4 方法四:setHidden () & isHidden ()------ 设置 / 获取条目是否隐藏

2.4.1 方法的核心定义

setHidden() 是 QListWidgetItem 用于控制单个条目显示 / 隐藏状态 的方法 ------ 隐藏的条目不会在列表中显示,也不参与列表布局计算;isHidden() 是对应的获取方法,用于判断条目是否处于隐藏状态。

通俗理解:setHidden(true) 就像 "把这一行纸从清单里藏起来"------ 别人看不到这一行,清单里的其他行会自动往上挪,填补这一行的位置;setHidden(false) 就像 "把这一行纸又放回清单里";isHidden() 就像 "看看这一行纸是不是藏起来了"。

这里有几个超级重要的规则,必须牢记:

  1. 隐藏的条目不占用布局空间 ------ 和 setDisabled()(禁用)不一样,禁用只是让条目变灰、不能点击,但它还在原来的位置,占用空间;隐藏是完全移除视觉展示,不占空间,其他条目会自动重新排列;
  2. 仅影响显示,数据完全保留------ 隐藏只是让别人看不到,条目的文本、图标、选中状态等所有数据都完全保留,没有丢失;
  3. 交互屏蔽------ 隐藏的条目无法被选中、点击、双击,也不会响应任何交互事件;
  4. 区别于删除 ------ 隐藏不是删除!删除是把条目从列表里彻底移除(takeItem),隐藏只是暂时藏起来,随时可以再显示。
2.4.2 关联 API 详解(逐词逐句,零模糊)
1. 设置条目是否隐藏:void setHidden (bool hidden)

函数原型:

复制代码
void QListWidgetItem::setHidden(bool hidden);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidgetItem:::成员函数;
  • setHidden():函数名,"设置是否隐藏" 的意思;
  • bool hidden:入参,hidden 是 true 隐藏,false 显示(默认)。

参数说明:

  • hidden:true 隐藏条目,false 显示条目(默认状态是显示)。
2. 判断条目是否隐藏:bool isHidden () const

函数原型:

复制代码
bool QListWidgetItem::isHidden() const;

逐词逐句底层解析:

  • bool:返回值类型,返回 true 或 false;
  • QListWidgetItem:::成员函数;
  • isHidden():函数名,"是不是隐藏了" 的意思;
  • const:常成员函数。

返回值说明:

  • true 表示条目处于隐藏状态;
  • false 表示条目处于显示状态(默认)。
2.4.3 使用示例
复制代码
#include <QListWidgetItem>

// 先添加几个条目
ui->listWidget->addItem("条目1");
ui->listWidget->addItem("条目2");
ui->listWidget->addItem("条目3");

// 获取第 0 个条目(第一行)
QListWidgetItem* item = ui->listWidget->item(0);

// 示例1:隐藏这个条目
item->setHidden(true);
// 此时界面上看不到"条目1","条目2"和"条目3"会自动往上挪

// 示例2:判断条目是否隐藏
if (item->isHidden()) {
    qDebug() << "条目1 被隐藏了";
}

// 示例3:重新显示这个条目
item->setHidden(false);
// 此时"条目1"又会出现在第一行,其他条目自动往下挪
2.4.4 关键注意事项(必知!)
  1. 布局影响(超级重要!):隐藏的条目不占用布局空间,其他条目会自动重新排列;
  2. 与 setDisabled () 的区别(超级重要!) :
    • setHidden(true):隐藏,不占空间,不响应交互;
    • setDisabled(true):禁用,仍占空间,显示为灰色,不响应交互;
  3. 数据保留(超级重要!):隐藏仅影响显示,所有数据完全保留;
  4. 区别于删除:隐藏不是删除,随时可以重新显示。

2.5 方法五:setSizeHint () & sizeHint ()------ 设置 / 获取条目尺寸提示

2.5.1 方法的核心定义

setSizeHint() 是 QListWidgetItem 用于为单个条目设置固定尺寸提示 的方法 ------ 你可以设置条目的宽度和高度(单位:像素),优先级高于 QListWidget 的默认条目尺寸;sizeHint() 是对应的获取方法。

通俗理解:setSizeHint() 就像 "给这一行纸设定固定的大小"------ 比如你想让这一行更宽、更高,就可以用这个方法;"尺寸提示" 的意思是,Qt 会尽量按照你设定的尺寸来显示,但如果内容太大,还是会自动适配。

这里有几个超级重要的规则,必须牢记:

  1. 优先级高于默认尺寸 ------ 如果你给条目设置了 sizeHint,Qt 会优先用你设定的尺寸;未设置时,条目尺寸由内容(文本 + 图标)和控件样式自动计算;
  2. 宽度可能被拉伸 ------ 如果 QListWidget 的 resizeMode 是 AdjustToContents,或者 QListWidget 本身是固定宽度,条目的宽度可能被内容拉伸,需结合控件固定宽度使用;
  3. 统一尺寸的影响 ------ 如果 QListWidget 设置了 setUniformItemSizes(true)(所有条目使用统一尺寸),那么只有第一个条目的 sizeHint 会生效,其他条目的单独设置无效;
  4. 最小尺寸限制------ 如果你设置的尺寸小于内容的最小显示尺寸,Qt 会自动适配为内容的最小尺寸,不会让内容显示不全;
  5. 配合文本对齐效果更明显 ------ 如果你想让 setTextAlignment()(文本对齐)的效果更明显,通常需要先给条目设置一个较大的 sizeHint,否则条目尺寸刚好包裹内容,对齐效果看不出来。
2.5.2 关联 API 详解(逐词逐句,零模糊)
1. 设置条目尺寸提示:void setSizeHint (const QSize &size)

函数原型:

复制代码
void QListWidgetItem::setSizeHint(const QSize &size);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidgetItem:::成员函数;
  • setSizeHint():函数名,"设置尺寸提示" 的意思;
  • const QSize &size:入参,size 是 QSize 类型,包含宽度和高度。

参数说明:

  • size:QSize 类型,width 为条目宽度,height 为条目高度(单位:像素);
  • 比如 QSize(200, 50) 表示宽 200 像素,高 50 像素。
2. 获取条目尺寸提示:QSize sizeHint () const

函数原型:

复制代码
QSize QListWidgetItem::sizeHint() const;

逐词逐句底层解析:

  • QSize:返回值类型,返回当前条目的尺寸提示;
  • QListWidgetItem:::成员函数;
  • sizeHint():函数名,"获取尺寸提示" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 QSize 类型的对象;
  • 未设置则返回 Qt 自动计算的尺寸。
2.5.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QSize>

// 创建条目
QListWidgetItem* item = new QListWidgetItem("自定义尺寸条目");

// 设置条目尺寸:宽 200 像素,高 50 像素
item->setSizeHint(QSize(200, 50));

// 添加到列表
ui->listWidget->addItem(item);

// 获取并打印尺寸
QSize size = item->sizeHint();
qDebug() << "条目宽度:" << size.width();
qDebug() << "条目高度:" << size.height();
2.5.4 关键注意事项(必知!)
  1. 宽度生效(超级重要!):若 QListWidget 宽度自适应,条目的宽度可能被拉伸,需结合控件固定宽度使用;
  2. 统一尺寸(超级重要!) :若设置 setUniformItemSizes(true),仅第一个条目的 sizeHint 生效;
  3. 最小尺寸限制:设置的尺寸小于内容最小显示尺寸时,会自动适配;
  4. 配合文本对齐 :想让文本对齐效果更明显,需先设置较大的 sizeHint。

2.6 方法六:setSelected () & isSelected ()------ 设置 / 获取条目是否选中

2.6.1 方法的核心定义

setSelected() 是 QListWidgetItem 用于控制单个条目选中状态 的方法 ------ 选中的条目会按照系统或自定义样式高亮显示;isSelected() 是对应的获取方法,用于判断条目是否被选中。

通俗理解:setSelected(true) 就像 "在清单这一行纸上打个勾,或者用荧光笔标亮"------ 别人一眼就能看到这一行被选中了;setSelected(false) 就像 "把勾擦掉,或者把荧光笔的颜色去掉";isSelected() 就像 "看看这一行有没有被标亮"。

这里有几个超级重要的规则,必须牢记:

  1. 仅在非 "NoSelection" 模式下生效 ------QListWidget 的选择模式由 setSelectionMode() 控制,默认是 SingleSelection(单选);如果设为 NoSelection(无选择),setSelected() 无效;
  2. 支持单选 / 多选模式 :
    • 单选模式(SingleSelection):选中一个条目时,之前选中的条目会自动取消选中;
    • 多选模式(MultiSelection、ExtendedSelection):可以同时选中多个条目;
  3. 调用 setSelected () 会触发信号 ------ 调用 setSelected(true) 或 setSelected(false) 会触发 QListWidget 的 itemSelectionChanged() 信号;
  4. 视觉样式可自定义 ------ 选中条目的高亮样式可以通过 QSS 自定义(比如 QListWidget::item:selected { background-color: blue; })。
2.6.2 关联 API 详解(逐词逐句,零模糊)
1. 设置条目是否选中:void setSelected (bool selected)

函数原型:

复制代码
void QListWidgetItem::setSelected(bool selected);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidgetItem:::成员函数;
  • setSelected():函数名,"设置是否选中" 的意思;
  • bool selected:入参,selected 是 true 选中,false 取消选中(默认)。

参数说明:

  • selected:true 选中条目,false 取消选中。
2. 判断条目是否选中:bool isSelected () const

函数原型:

复制代码
bool QListWidgetItem::isSelected() const;

逐词逐句底层解析:

  • bool:返回值类型,返回 true 或 false;
  • QListWidgetItem:::成员函数;
  • isSelected():函数名,"是不是被选中了" 的意思;
  • const:常成员函数。

返回值说明:

  • true 表示条目被选中;
  • false 表示条目未被选中(默认)。
2.6.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QAbstractItemView>

// 先设置选择模式为单选(默认也是单选,这里显式设置)
ui->listWidget->setSelectionMode(QAbstractItemView::SingleSelection);

// 添加几个条目
QListWidgetItem* item1 = new QListWidgetItem("条目1");
QListWidgetItem* item2 = new QListWidgetItem("条目2");
ui->listWidget->addItem(item1);
ui->listWidget->addItem(item2);

// 示例1:选中第一个条目
item1->setSelected(true);
// 此时条目1 会高亮显示

// 示例2:判断条目是否选中
if (item1->isSelected()) {
    qDebug() << "条目1 被选中了";
}

// 示例3:取消选中
item1->setSelected(false);
// 此时条目1 取消高亮

// 示例4:多选模式下选中多个条目
ui->listWidget->setSelectionMode(QAbstractItemView::MultiSelection); // 切换到多选
item1->setSelected(true);
item2->setSelected(true);
// 此时两个条目都被选中
2.6.4 关键注意事项(必知!)
  1. 选择模式(超级重要!) :仅在非 NoSelection 模式下生效;
  2. 单选 / 多选(超级重要!):单选模式下选中一个会自动取消另一个;
  3. 信号触发(超级重要!) :调用 setSelected() 会触发 itemSelectionChanged() 信号;
  4. 视觉样式可自定义:通过 QSS 自定义选中高亮样式。

2.7 方法七:setTextAlignment () & textAlignment ()------ 设置 / 获取文本对齐方式

2.7.1 方法的核心定义

setTextAlignment() 是 QListWidgetItem 用于控制文本在条目内部对齐位置 的方法 ------ 你可以设置水平对齐(左对齐、居中、右对齐)和垂直对齐(顶部、居中、底部);textAlignment() 是对应的获取方法。

通俗理解:setTextAlignment() 就像 "把这一行纸上的字摆到什么位置"------ 比如摆到中间、摆到右边、摆到右下角;默认是左对齐 + 垂直居中。

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 默认对齐方式 ------ 默认是 Qt::AlignLeft | Qt::AlignVCenter(左对齐 + 垂直居中);

  2. 核心枚举值(Qt::Alignment)(超级重要!) :

    枚举值 功能说明
    Qt::AlignLeft 水平左对齐(默认);
    Qt::AlignRight 水平右对齐;
    Qt::AlignHCenter 水平居中;
    Qt::AlignCenter 水平 + 垂直居中(等价于 `AlignHCenter AlignVCenter`);
    Qt::AlignTop 垂直顶部对齐;
    Qt::AlignBottom 垂直底部对齐;
    Qt::AlignVCenter 垂直居中(默认);
  3. 可组合使用 ------ 你可以通过 |(按位或)组合水平和垂直对齐方式,比如 Qt::AlignRight | Qt::AlignBottom(右对齐 + 底部对齐);

  4. 需配合 setSizeHint () 效果才明显!(超级重要!说三遍!) :

    • 如果条目尺寸刚好包裹内容,文本对齐的效果看不出来;
    • 你需要先通过 setSizeHint() 给条目设置一个较大的尺寸,让条目内部有多余的空间,对齐效果才会明显;
  5. 仅针对文本部分------ 文本对齐仅针对文本部分,图标始终显示在文本左侧,不受对齐方式影响。

2.7.2 关联 API 详解(逐词逐句,零模糊)
1. 设置文本对齐方式:void setTextAlignment (int alignment)

函数原型:

复制代码
void QListWidgetItem::setTextAlignment(int alignment);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidgetItem:::成员函数;
  • setTextAlignment():函数名,"设置文本对齐方式" 的意思;
  • int alignment:入参,alignment 是 Qt::Alignment 枚举值的组合(用 int 接收是因为枚举值本质是整数)。

参数说明:

  • alignment:对齐方式,可组合多个 Qt::Alignment 枚举值(用 | 连接)。
2. 获取文本对齐方式:int textAlignment () const

函数原型:

复制代码
int QListWidgetItem::textAlignment() const;

逐词逐句底层解析:

  • int:返回值类型,返回对齐方式的组合(整数形式);
  • QListWidgetItem:::成员函数;
  • textAlignment():函数名,"获取文本对齐方式" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 int 类型的整数,对应 Qt::Alignment 枚举值的组合;
  • 未设置则返回默认值 Qt::AlignLeft | Qt::AlignVCenter。
2.7.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QSize>
#include <Qt> // 包含 Qt::Alignment 枚举

// 示例1:文本水平居中 + 垂直居中
QListWidgetItem* item1 = new QListWidgetItem("居中对齐");
item1->setSizeHint(QSize(200, 50)); // 先设置较大尺寸,对齐效果才明显!
item1->setTextAlignment(Qt::AlignCenter); // 等价于 AlignHCenter | AlignVCenter
ui->listWidget->addItem(item1);

// 示例2:文本右对齐 + 垂直底部对齐
QListWidgetItem* item2 = new QListWidgetItem("右底对齐");
item2->setSizeHint(QSize(200, 50)); // 先设置较大尺寸!
item2->setTextAlignment(Qt::AlignRight | Qt::AlignBottom); // 组合使用
ui->listWidget->addItem(item2);
2.7.4 关键注意事项(必知!)
  1. 需配合 setSizeHint () 效果才明显!(超级重要!说三遍!):条目尺寸太小的话,对齐效果看不出来;
  2. 可组合使用(超级重要!) :通过 | 组合水平和垂直对齐方式;
  3. 仅针对文本部分:图标始终在文本左侧,不受影响;
  4. 默认对齐方式:左对齐 + 垂直居中。

示例代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QListWidgetItem>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //OK,大家,接下来我们来学习多元素控件,即一个控件中包含多个元素
    //那么我们先学习QListWidget控件,这个控件其实就像是一个列表一样,把要显示的条目都显示出来
    //然后支持添加删除等等,说白了其实就像是一个一维数组一样~~~

    //那么由于我们去向QListWidget控件添加或者查找或者删除条目的时候,需要设置QListWidget控件的条目类
    //所以本文件我们就先来血洗QListWidgetItem类,其实它是很简单的,和我们之前学习的单元素控件算是差不多的哦~~

    /**
     * @class QListWidgetItem
     * @brief Qt中QListWidget控件的核心元素类,表征列表中的单个条目
     * @details QListWidgetItem是QListWidget的最小组成单元,核心由**文本+图标**构成,支持字体、显示状态、尺寸、选中状态、文本对齐方式等个性化配置;
     *          每个条目可独立设置样式和状态,是实现列表项自定义展示与交互的基础。
     *
     * 【核心特征】
     * 1. 基础展示:支持文本、图标双元素展示,是列表项的核心视觉内容;
     * 2. 样式定制:可单独设置字体(大小/粗细/颜色)、文本对齐方式;
     * 3. 状态控制:支持隐藏/显示、选中/未选中状态切换;
     * 4. 尺寸适配:可自定义条目尺寸,适配不同视觉需求。
     */

    // ============================== 核心方法详解 ==============================

    /**
     * @fn void QListWidgetItem::setFont(const QFont &font)
     * @brief 设置列表项的字体样式
     * @details 该方法用于自定义单个列表项的字体(大小、粗细、颜色、字体家族等),优先级高于QListWidget的全局字体设置;
     *          未单独设置时,继承父控件QListWidget的字体样式。
     *
     * @参数说明:
     * @param font - QFont类型,包含字体家族、大小、粗细、下划线等样式属性。
     *
     * 【关联API】
     * 1. QFont font() const → 获取当前列表项的字体样式;
     * 2. QFont QListWidget::font() const → 获取列表控件的全局字体(未单独设置时继承)。
     *
     * @使用示例:
     * // 创建列表项并设置字体(微软雅黑、14号、粗体)
     * QListWidgetItem* item = new QListWidgetItem("自定义字体条目");
     * QFont font("Microsoft YaHei", 14, QFont::Bold);
     * item->setFont(font);
     * ui->listWidget->addItem(item);
     *
     * 【关键注意事项】
     * 1. 优先级:单个条目字体 > QListWidget全局字体 > 应用程序默认字体;
     * 2. 颜色设置:QFont仅控制字体样式,文本颜色需通过setForeground()设置(如item->setForeground(Qt::red));
     * 3. 动态生效:设置后立即刷新列表项视觉效果,无需额外刷新控件。
     */

    /**
     * @fn void QListWidgetItem::setIcon(const QIcon &icon)
     * @brief 设置列表项的显示图标
     * @details 该方法为列表项添加/修改图标,图标会显示在文本左侧(默认布局),是实现"图标+文本"列表项的核心方法;
     *          未设置时列表项仅显示文本,无图标。
     *
     * @参数说明:
     * @param icon - QIcon类型,支持本地图片、资源文件、系统图标等多种图标来源。
     *
     * 【关联API】
     * 1. QIcon icon() const → 获取当前列表项的图标;
     * 2. void QListWidget::setIconSize(const QSize &size) → 设置列表控件中所有图标的统一显示尺寸。
     *
     * @使用示例:
     * // 方式1:使用资源文件图标
     * QListWidgetItem* item1 = new QListWidgetItem("资源图标");
     * item1->setIcon(QIcon(":/images/icon.png"));
     * ui->listWidget->addItem(item1);
     *
     * // 方式2:使用系统图标
     * QListWidgetItem* item2 = new QListWidgetItem("系统图标");
     * item2->setIcon(QApplication::style()->standardIcon(QStyle::SP_FileIcon));
     * ui->listWidget->addItem(item2);
     *
     * // 设置图标显示尺寸(全局)
     * ui->listWidget->setIconSize(QSize(24, 24));
     *
     * 【关键注意事项】
     * 1. 尺寸控制:图标显示尺寸由QListWidget::setIconSize()全局控制,单个条目无法单独设置;
     * 2. 资源路径:使用资源文件时需确保路径正确(以:/开头),本地图片需传入完整路径;
     * 3. 透明适配:QIcon自动适配不同显示状态(选中/未选中),也可通过QIcon::addPixmap()自定义状态图标。
     */

    /**
     * @fn void QListWidgetItem::setHidden(bool hidden)
     * @brief 设置列表项是否隐藏
     * @details 该方法控制单个列表项的显示/隐藏状态,隐藏的条目不会在列表中显示,也不参与列表布局计算;
     *          区别于setDisabled()(禁用仅灰显,仍占用布局空间),隐藏会完全移除视觉展示。
     *
     * @参数说明:
     * @param hidden - bool类型,true=隐藏条目,false=显示条目(默认)。
     *
     * 【关联API】
     * 1. bool isHidden() const → 判断当前列表项是否处于隐藏状态;
     * 2. void QListWidgetItem::setDisabled(bool disabled) → 设置条目禁用(灰显,仍显示)。
     *
     * @使用示例:
     * // 隐藏指定条目
     * QListWidgetItem* item = ui->listWidget->item(0); // 获取第0个条目
     * item->setHidden(true); // 隐藏
     *
     * // 显示条目
     * item->setHidden(false); // 显示
     *
     * 【关键注意事项】
     * 1. 布局影响:隐藏的条目不占用列表控件的布局空间,列表会自动重新排列剩余条目;
     * 2. 状态保留:隐藏仅影响显示,条目的文本、图标、选中状态等数据完全保留;
     * 3. 交互屏蔽:隐藏的条目无法被选中、点击,也不会响应任何交互事件。
     */

    /**
     * @fn void QListWidgetItem::setSizeHint(const QSize &size)
     * @brief 设置列表项的尺寸提示(自定义条目大小)
     * @details 该方法为单个列表项设置固定尺寸,优先级高于QListWidget的默认条目尺寸;
     *          未设置时,条目尺寸由内容(文本+图标)和控件样式自动计算。
     *
     * @参数说明:
     * @param size - QSize类型,width为条目宽度,height为条目高度(单位:像素)。
     *
     * 【关联API】
     * 1. QSize sizeHint() const → 获取当前列表项的尺寸提示;
     * 2. void QListWidget::setUniformItemSizes(bool uniform) → 设置所有条目是否使用统一尺寸(true时仅第一个条目的sizeHint生效)。
     *
     * @使用示例:
     * // 创建条目并设置固定尺寸(宽200px,高50px)
     * QListWidgetItem* item = new QListWidgetItem("自定义尺寸条目");
     * item->setSizeHint(QSize(200, 50));
     * ui->listWidget->addItem(item);
     *
     * 【关键注意事项】
     * 1. 宽度生效:若QListWidget的resizeMode为AdjustToContents,宽度可能被内容拉伸,需结合控件固定宽度使用;
     * 2. 统一尺寸:若设置setUniformItemSizes(true),所有条目会使用第一个条目的sizeHint,单独设置无效;
     * 3. 最小尺寸:设置的尺寸小于内容最小显示尺寸时,会自动适配为内容最小尺寸。
     */

    /**
     * @fn void QListWidgetItem::setSelected(bool selected)
     * @brief 设置列表项是否被选中
     * @details 该方法控制单个列表项的选中状态,选中的条目会按照系统/自定义样式高亮显示;
     *          支持单选/多选模式(由QListWidget::setSelectionMode()控制)。
     *
     * @参数说明:
     * @param selected - bool类型,true=选中条目,false=取消选中(默认)。
     *
     * 【关联API】
     * 1. bool isSelected() const → 判断当前列表项是否被选中;
     * 2. void QListWidget::setSelectionMode(QAbstractItemView::SelectionMode mode) → 设置列表选择模式(单选/多选/无选择);
     * 3. QListWidgetItem* QListWidget::currentItem() const → 获取列表当前选中的条目(单选模式)。
     *
     * @使用示例:
     * // 1. 设置单选模式并选中第一个条目
     * ui->listWidget->setSelectionMode(QAbstractItemView::SingleSelection);
     * QListWidgetItem* item1 = new QListWidgetItem("选中条目");
     * ui->listWidget->addItem(item1);
     * item1->setSelected(true);
     *
     * // 2. 多选模式下选中多个条目
     * ui->listWidget->setSelectionMode(QAbstractItemView::MultiSelection);
     * QListWidgetItem* item2 = new QListWidgetItem("多选条目1");
     * QListWidgetItem* item3 = new QListWidgetItem("多选条目2");
     * ui->listWidget->addItem(item2);
     * ui->listWidget->addItem(item3);
     * item2->setSelected(true);
     * item3->setSelected(true);
     *
     * 【关键注意事项】
     * 1. 选择模式:仅在非"NoSelection"模式下,选中状态才会生效;
     * 2. 信号触发:调用setSelected()会触发QListWidget::itemSelectionChanged()信号;
     * 3. 视觉样式:选中高亮样式可通过QSS自定义(如QListWidget::item:selected)。
     */

    /**
     * @fn void QListWidgetItem::setText(const QString &text)
     * @brief 设置列表项的显示文本
     * @details 该方法是列表项最基础的配置,设置条目核心显示文本,支持普通字符串、富文本(HTML格式);
     *          文本是列表项的核心标识,未设置时条目为空。
     *
     * @参数说明:
     * @param text - QString类型,列表项要显示的文本内容(支持UTF-8编码,可包含中文、特殊字符)。
     *
     * 【关联API】
     * 1. QString text() const → 获取当前列表项的显示文本;
     * 2. void QListWidgetItem::setToolTip(const QString &tip) → 设置文本提示(鼠标悬浮时显示)。
     *
     * @使用示例:
     * // 1. 设置普通文本
     * QListWidgetItem* item1 = new QListWidgetItem("普通文本条目");
     * ui->listWidget->addItem(item1);
     *
     * // 2. 设置富文本(带颜色、加粗)
     * QListWidgetItem* item2 = new QListWidgetItem();
     * item2->setText("<font color='red'><b>富文本条目</b></font>");
     * ui->listWidget->addItem(item2);
     *
     * 【关键注意事项】
     * 1. 富文本支持:仅基础HTML标签(<b>/<i>/<font>等),复杂标签可能无法渲染;
     * 2. 文本截断:文本过长时,列表项会自动截断并显示省略号(可通过setSizeHint扩大尺寸避免);
     * 3. 编码适配:确保文本为UTF-8编码,避免中文乱码(Qt默认支持,需注意文件编码)。
     */

    /**
     * @fn void QListWidgetItem::setTextAlignment(int alignment)
     * @brief 设置列表项文本的对齐方式
     * @details 该方法控制文本在列表项内部的对齐位置(水平+垂直),默认对齐方式为Qt::AlignLeft | Qt::AlignVCenter(左对齐+垂直居中);
     *          对齐效果受条目尺寸(sizeHint)影响,需配合尺寸设置达到预期效果。
     *
     * 【核心枚举值(Qt::Alignment)】
     * | 枚举值                | 功能说明                                                                 |
     * |-----------------------|--------------------------------------------------------------------------|
     * | Qt::AlignLeft         | 水平左对齐(默认);                                                     |
     * | Qt::AlignRight        | 水平右对齐;                                                             |
     * | Qt::AlignHCenter      | 水平居中;                                                               |
     * | Qt::AlignCenter       | 水平+垂直居中(等价于AlignHCenter | AlignVCenter);                     |
     * | Qt::AlignTop          | 垂直顶部对齐;                                                           |
     * | Qt::AlignBottom       | 垂直底部对齐;                                                           |
     * | Qt::AlignVCenter      | 垂直居中(默认);                                                       |
     *
     * @参数说明:
     * @param alignment - int类型,可组合多个Qt::Alignment枚举值(用|连接)。
     *
     * 【关联API】
     * 1. int textAlignment() const → 获取当前列表项的文本对齐方式。
     *
     * @使用示例:
     * // 1. 文本水平居中+垂直居中
     * QListWidgetItem* item1 = new QListWidgetItem("居中对齐");
     * item1->setTextAlignment(Qt::AlignCenter);
     * item1->setSizeHint(QSize(200, 50)); // 扩大尺寸,对齐效果更明显
     * ui->listWidget->addItem(item1);
     *
     * // 2. 文本右对齐+垂直底部对齐
     * QListWidgetItem* item2 = new QListWidgetItem("右底对齐");
     * item2->setTextAlignment(Qt::AlignRight | Qt::AlignBottom);
     * item2->setSizeHint(QSize(200, 50));
     * ui->listWidget->addItem(item2);
     *
     * 【关键注意事项】
     * 1. 组合使用:对齐方式可通过|组合(如Qt::AlignHCenter | Qt::AlignTop);
     * 2. 尺寸影响:条目尺寸过小时,对齐效果不明显,需配合setSizeHint扩大尺寸;
     * 3. 图标兼容:文本对齐仅针对文本部分,图标始终显示在文本左侧(不受对齐方式影响)。
     */

    QListWidgetItem* item=new QListWidgetItem();
    item->setText("this is a item");

    QFont font;
    font.setFamily("黑体");
    font.setBold(true);

    item->setFont(font);

    item->setIcon(QIcon("C:\\Users\\Win\\Desktop\\b_17576d8be766c15b868aa7e1da548e34.jpg"));

    item->setTextAlignment(Qt::AlignLeft);
}

Widget::~Widget()
{
    delete ui;
}

第三章 QListWidget 核心属性详解(一)

讲完了 QListWidgetItem 类,我们接下来讲 QListWidget 的核心属性 。我们首先讲第一部分:currentRow(当前选中行号)、count(总行数)、itemAlignment(条目整体对齐)、selectRectVisible(选中矩形可见)、spacing(条目间距)。


3.1 属性一:currentRow------ 当前选中的是第几行?

3.1.1 属性的核心定义

currentRow 是 QListWidget 用于表征当前激活选中条目的行号的属性 ------ 行号从 0 开始计数(第一行是 0,第二行是 1,以此类推),无选中条目时值为 -1。

通俗理解:currentRow 就像 "清单上当前被标亮的是第几行"------ 注意是从 0 开始数的,不是从 1 开始!如果没有任何一行被标亮,它就是 -1。

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 行号从 0 开始计数!(超级重要!说三遍!) :
    • 第一行的行号是 0,第二行是 1,第三行是 2,...,第 N 行是 N-1;
    • 用户视角的 "第 1 行" 对应代码里的 row=0,这点新手非常容易搞错!
  2. 无选中条目时值为 -1 :如果列表为空,或者没有任何条目被选中,currentRow 返回 -1;
  3. 超出范围设置会取消选中 :如果你调用 setCurrentRow(row) 时,row 不在有效范围 [0, count()-1] 内,会取消所有选中,currentRow 变为 -1;
  4. 联动 currentItem :currentRow 和 currentItem 是一一对应的 ------currentItem() 对应的行号就是 currentRow(),修改其中一个,另一个会自动更新;
  5. 修改会触发信号 :设置有效行号时会触发 currentRowChanged() 和 currentItemChanged() 信号。
3.1.2 关联 API 详解(逐词逐句,零模糊)

currentRow 属性有两个关联的 API:

1. 获取当前选中行号:int currentRow () const

函数原型:

复制代码
int QListWidget::currentRow() const;

逐词逐句底层解析:

  • int:返回值类型,返回当前选中的行号;
  • QListWidget:::成员函数;
  • currentRow():函数名,"获取当前行号" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 int 类型的整数;
  • 有效范围:0 ≤ row < count();
  • 无选中时返回 -1。
2. 设置当前选中行号:void setCurrentRow (int row)

函数原型:

复制代码
void QListWidget::setCurrentRow(int row);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • setCurrentRow():函数名,"设置当前行号" 的意思;
  • int row:入参,目标行号。

参数说明:

  • row:目标行号,int 类型;
  • 有效范围:0 ≤ row < count();
  • 超出范围则取消所有选中,currentRow 变为 -1。
3.1.3 使用示例
复制代码
#include <QDebug>

// 先添加几个条目
ui->listWidget->addItem("条目1"); // 行号 0
ui->listWidget->addItem("条目2"); // 行号 1
ui->listWidget->addItem("条目3"); // 行号 2

// 示例1:设置选中第 2 行(用户视角),对应代码行号 1
ui->listWidget->setCurrentRow(1);

// 示例2:获取当前选中行号并打印
int selectedRow = ui->listWidget->currentRow();
if (selectedRow == -1) {
    qDebug() << "当前无选中项";
} else {
    qDebug() << "当前选中行号(代码):" << selectedRow;
    qDebug() << "当前选中行号(用户):" << selectedRow + 1; // 行号+1 适配用户习惯
}

// 示例3:设置超出范围的行号(取消选中)
ui->listWidget->setCurrentRow(100); // 超出范围
qDebug() << "当前选中行号:" << ui->listWidget->currentRow(); // 输出 -1
3.1.4 关键注意事项(必知!)
  1. 行号从 0 开始!(超级重要!说三遍!):用户视角的第 1 行对应代码的 0;
  2. 无选中返回 -1(超级重要!):使用前需判断是否为 -1;
  3. 超出范围取消选中:设置无效行号会取消所有选中;
  4. 联动 currentItem:二者一一对应;
  5. 修改触发信号 :设置有效行号会触发 currentRowChanged() 和 currentItemChanged()。

3.2 属性二:count------ 一共有多少行?(只读)

3.2.1 属性的核心定义

count 是 QListWidget 的只读属性------ 它实时统计列表中 QListWidgetItem 的总数,默认值为 0(空列表)。

通俗理解:count 就像 "数一数清单里一共有多少行纸"------ 你加一行,它就加 1;你删一行,它就减 1;它是实时更新的,不用你手动数。

这里有几个超级重要的规则,必须牢记:

  1. 只读特性!(超级重要!) :你无法直接通过赋值修改 count(比如 ui->listWidget->count = 10 是错误的),只能通过 addItem、insertItem、takeItem 等方法间接变更;
  2. 实时更新:增删条目后立即生效,无需手动刷新;
  3. 有效行号上限 :有效行号的范围是 [0, count()-1]------ 遍历列表时常用 for(int i=0; i<count(); i++);
  4. 快速判断是否为空 :可以用 count() == 0 判断列表是否为空,也可以用更便捷的 isEmpty() 方法(等价于 count() == 0)。
3.2.2 关联 API 详解(逐词逐句,零模糊)

count 属性有两个关联的 API:

1. 获取列表总行数:int count () const

函数原型:

复制代码
int QListWidget::count() const;

逐词逐句底层解析:

  • int:返回值类型,返回总行数;
  • QListWidget:::成员函数;
  • count():函数名,"获取总数" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 int 类型的整数;
  • 空列表返回 0。
2. 【便捷】快速判断列表是否为空:bool isEmpty () const

函数原型:

复制代码
bool QListWidget::isEmpty() const;

逐词逐句底层解析:

  • bool:返回值类型,返回 true 或 false;
  • QListWidget:::成员函数;
  • isEmpty():函数名,"是不是空的" 的意思;
  • const:常成员函数。

返回值说明:

  • true 表示列表为空(count() == 0);
  • false 表示列表不为空。
3.2.3 使用示例
复制代码
#include <QDebug>

// 先添加几个条目
ui->listWidget->addItem("条目1");
ui->listWidget->addItem("条目2");
ui->listWidget->addItem("条目3");

// 示例1:统计总行数并打印
int total = ui->listWidget->count();
qDebug() << "列表总行数:" << total; // 输出 3

// 示例2:判断列表是否为空(两种方式)
// 方式1:用 count()
if (ui->listWidget->count() == 0) {
    qDebug() << "列表为空";
} else {
    qDebug() << "列表不为空";
}
// 方式2:用 isEmpty()(更便捷!推荐!)
if (ui->listWidget->isEmpty()) {
    qDebug() << "列表为空";
} else {
    qDebug() << "列表不为空";
}

// 示例3:遍历所有条目(常用!)
for (int i = 0; i < ui->listWidget->count(); ++i) {
    QListWidgetItem* item = ui->listWidget->item(i);
    if (item) {
        qDebug() << "第" << i+1 << "行:" << item->text();
    }
}
3.2.4 关键注意事项(必知!)
  1. 只读特性!(超级重要!):无法直接赋值修改,只能通过增删条目间接变更;
  2. 实时更新:增删条目后立即生效;
  3. 有效行号上限 :[0, count()-1];
  4. 推荐用 isEmpty () :比 count() == 0 更便捷、更直观。

3.3 属性三:itemAlignment------ 条目整体在控件中怎么对齐?

3.3.1 属性的核心定义

itemAlignment 是 QListWidget 用于控制所有条目在列表控件内整体对齐位置 的属性 ------ 注意!它是 "条目在控件中对齐",不是"文本在条目中对齐"(那是 QListWidgetItem::setTextAlignment ())!

通俗理解:itemAlignment 就像 "把清单里的所有行纸作为一个整体,摆到清单本的什么位置"------ 比如摆到中间、摆到右边;而 setTextAlignment() 是 "把某一行纸上的字摆到这一行的什么位置"------ 这两个是不同层级的对齐,一定要区分开!

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 层级区别!(超级重要!说三遍!) :
    • QListWidget::itemAlignment:条目在控件中的整体对齐;
    • QListWidgetItem::setTextAlignment():文本在条目中的对齐;
    • 这两个是完全不同的,不要搞混!
  2. 默认对齐方式 ------ 默认是 Qt::AlignLeft | Qt::AlignTop(左对齐 + 顶部对齐);
  3. 核心枚举值和之前一样 ------ 用的还是 Qt::Alignment 枚举,和 setTextAlignment() 的枚举值一样;
  4. 需控件尺寸大于条目总尺寸效果才明显!(超级重要!) :
    • 如果 QListWidget 的尺寸刚好包裹所有条目,整体对齐的效果看不出来;
    • 你需要先给 QListWidget 设置一个较大的固定尺寸,让控件内部有多余的空间,对齐效果才会明显;
  5. 可组合使用 ------ 同样通过 | 组合水平和垂直对齐方式。
3.3.2 关联 API 详解(逐词逐句,零模糊)
1. 获取条目整体对齐方式:Qt::Alignment itemAlignment () const

函数原型:

复制代码
Qt::Alignment QListWidget::itemAlignment() const;

逐词逐句底层解析:

  • Qt::Alignment:返回值类型,返回对齐方式;
  • QListWidget:::成员函数;
  • itemAlignment():函数名,"获取条目整体对齐方式" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 Qt::Alignment 枚举值的组合;
  • 默认返回 Qt::AlignLeft | Qt::AlignTop。
2. 设置条目整体对齐方式:void setItemAlignment (Qt::Alignment alignment)

函数原型:

复制代码
void QListWidget::setItemAlignment(Qt::Alignment alignment);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • setItemAlignment():函数名,"设置条目整体对齐方式" 的意思;
  • Qt::Alignment alignment:入参,对齐方式。

参数说明:

  • alignment:对齐方式,Qt::Alignment 枚举值的组合。
3.3.3 使用示例
复制代码
#include <Qt>

// 先给 QListWidget 设置一个较大的固定尺寸(对齐效果才明显!)
ui->listWidget->setFixedSize(400, 300); // 宽 400,高 300

// 添加几个条目
ui->listWidget->addItem("条目1");
ui->listWidget->addItem("条目2");
ui->listWidget->addItem("条目3");

// 设置所有条目在控件中水平+垂直居中
ui->listWidget->setItemAlignment(Qt::AlignCenter);
3.3.4 关键注意事项(必知!)
  1. 层级区别!(超级重要!说三遍!) :和 QListWidgetItem::setTextAlignment() 是不同层级的对齐!
  2. 需控件尺寸大于条目总尺寸效果才明显!(超级重要!);
  3. 默认对齐方式:左对齐 + 顶部对齐;
  4. 可组合使用 :通过 | 组合水平和垂直对齐方式。

3.4 属性四:selectRectVisible------ 选中条目的矩形框要不要显示?

3.4.1 属性的核心定义

selectRectVisible 是 QListWidget 用于控制选中条目周围的高亮矩形框显隐 的属性 ------ 默认值为 true(可见);设为 false 时,选中条目仍会触发选中信号,但无视觉矩形框高亮,可配合 QSS 自定义选中样式。

通俗理解:selectRectVisible 就像 "要不要显示选中条目的那个虚线框 / 高亮框"------ 如果设为 false,就不显示那个框,但条目还是被选中的,你可以通过 QSS 自定义其他选中样式(比如只改变文本颜色)。

这里有几个超级重要的规则,必须牢记:

  1. 默认值为 true(可见)------ 刚创建 QListWidget 时,选中条目周围会有系统默认的高亮矩形框;
  2. 仅视觉影响,不改变选中逻辑!(超级重要!) :
    • 隐藏矩形框不改变选中逻辑、行号 / 条目对象关联,也不影响选中信号触发;
    • 条目还是被选中的,只是看不到那个框而已;
  3. 样式覆盖(超级重要!) :
    • 若通过 QSS 自定义了 QListWidget::item:selected 样式,该属性可能被覆盖,以 QSS 样式为准;
    • 比如你用 QSS 设置了选中条目的背景色,哪怕 selectRectVisible=false,背景色还是会显示;
  4. 交互兼容------ 即使隐藏矩形框,条目仍可被点击 / 选中 / 双击,所有交互功能正常。
3.4.2 关联 API 详解(逐词逐句,零模糊)
1. 判断选中矩形框是否可见:bool isSelectRectVisible () const

函数原型:

复制代码
bool QListWidget::isSelectRectVisible() const;

逐词逐句底层解析:

  • bool:返回值类型,返回 true 或 false;
  • QListWidget:::成员函数;
  • isSelectRectVisible():函数名,"选中矩形框是不是可见" 的意思;
  • const:常成员函数。

返回值说明:

  • true 表示选中矩形框可见(默认);
  • false 表示选中矩形框隐藏。
2. 设置选中矩形框显隐:void setSelectRectVisible (bool visible)

函数原型:

复制代码
void QListWidget::setSelectRectVisible(bool visible);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • setSelectRectVisible():函数名,"设置选中矩形框显隐" 的意思;
  • bool visible:入参,visible 是 true 可见,false 隐藏。

参数说明:

  • visible:true 显示选中矩形框,false 隐藏。
3.4.3 使用示例
复制代码
#include <QListWidgetItem>

// 添加条目
ui->listWidget->addItem("条目1");

// 隐藏默认选中矩形框
ui->listWidget->setSelectRectVisible(false);

// 选中第一个条目
ui->listWidget->setCurrentRow(0);
// 此时条目被选中,但没有系统默认的矩形框高亮
// 你可以通过 QSS 自定义选中样式,比如只改变文本颜色
3.4.4 关键注意事项(必知!)
  1. 仅视觉影响(超级重要!):不改变选中逻辑和信号触发;
  2. 样式覆盖(超级重要!):QSS 自定义样式可能覆盖该属性;
  3. 交互兼容:隐藏后所有交互功能正常;
  4. 默认值为 true。

3.5 属性五:spacing------ 条目之间的间距是多少?

3.5.1 属性的核心定义

spacing 是 QListWidget 用于控制相邻条目间间距的属性 ------ 单位是像素,默认值为 0(无间距)。

通俗理解:spacing 就像 "清单里每一行纸之间的空隙"------ 你设置 5 像素,每两行之间就空 5 像素;设置 10 像素,就空 10 像素;空隙大一点,看起来更舒服。

这里有几个超级重要的规则,必须牢记:

  1. 单位是像素------ 间距的单位是像素,数值越大,条目间的空隙越大;
  2. 默认值为 0(无间距)------ 刚创建 QListWidget 时,条目之间是紧挨着的,没有空隙;
  3. 开启换行(isWrapping=true)时同时控制水平和垂直间距 :
    • 未开启换行时(默认,纵向单列),仅控制垂直间距(上下条目之间的空隙);
    • 开启换行后(多列流式布局),同时控制水平间距 (左右条目之间的空隙)和垂直间距;
  4. 负值自动修正为 0------ 如果你设置的间距是负数,Qt 会自动修正为 0,不会出现条目重叠;
  5. 布局影响------ 间距会增加列表的整体尺寸,需结合控件大小适配,避免出现滚动条或显示不全。
3.5.2 关联 API 详解(逐词逐句,零模糊)
1. 获取条目间距:int spacing () const

函数原型:

复制代码
int QListWidget::spacing() const;

逐词逐句底层解析:

  • int:返回值类型,返回间距(像素);
  • QListWidget:::成员函数;
  • spacing():函数名,"获取间距" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 int 类型的整数;
  • 单位是像素;
  • 默认返回 0。
2. 设置条目间距:void setSpacing (int space)

函数原型:

复制代码
void QListWidget::setSpacing(int space);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • setSpacing():函数名,"设置间距" 的意思;
  • int space:入参,space 是间距(像素)。

参数说明:

  • space:间距,int 类型,单位是像素;
  • 建议设置为 ≥ 0 的整数;
  • 负值自动修正为 0。
3.5.3 使用示例
复制代码
// 添加几个条目
ui->listWidget->addItem("条目1");
ui->listWidget->addItem("条目2");
ui->listWidget->addItem("条目3");

// 设置条目间距为 8 像素(提升视觉舒适度)
ui->listWidget->setSpacing(8);
// 此时每两个条目之间空 8 像素,看起来更舒服
3.5.4 关键注意事项(必知!)
  1. 单位是像素;
  2. 开启换行时同时控制水平和垂直间距(超级重要!);
  3. 负值自动修正为 0;
  4. 布局影响:间距会增加列表整体尺寸;
  5. 默认值为 0。

示例代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QListWidget>
#include <QListWidgetItem>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //OK,本文件我们就来学习QListWidget控件的currentRow、count、spacing、itemAlignment属性
    //那么count属性很简单,是获取到QListWidget控件中有多少个条目~~
    //而currentRow属性呢,则是获取到用户选择的是哪一行条目
    //spacing属性,则是设置说QListWidget控件里的每个条目之间的距离
    //最后的itemAlignment属性,我们也很属性了,就是设置QListWidget控件中的条目的是要居哪边呢??

    /**
     * @class QListWidget
     * @brief Qt中纵向列表展示控件的核心属性(行选中/行数/对齐/选中矩形/间距)
     * @details 以下属性聚焦QListWidget的基础状态管理与视觉布局,currentRow/count控制列表选中状态和数量统计,itemAlignment/selectRectVisible/spacing定制列表视觉展示效果,是列表控件最常用的核心属性。
     */

    // ============================== 核心属性详解 ==============================

    /**
     * @property QListWidget::currentRow
     * @brief QListWidget当前被选中条目的行号属性
     * @details 表征列表中当前激活选中条目的行号,行号从0开始计数(第一行=0),无选中条目时值为-1;修改该属性会触发currentRowChanged()信号,是控制/获取选中行的核心属性。
     *
     * 【关联API详解】
     * 1. int currentRow() const → 获取当前选中行号(无选中返回-1);
     * 2. void setCurrentRow(int row) → 设置指定行号为选中行(行号超出范围则取消选中)。
     *
     * @使用示例:
     * // 获取当前选中行号并打印
     * int selectedRow = ui->listWidget->currentRow();
     * qDebug() << "当前选中行:" << (selectedRow == -1 ? "无" : QString::number(selectedRow + 1)); // 行号+1适配用户习惯
     *
     * // 设置选中第2行(索引1)
     * ui->listWidget->setCurrentRow(1);
     *
     * 【关键注意事项】
     * 1. 行号规则:有效行号范围为[0, count()-1],超出范围设置会取消所有选中,currentRow变为-1;
     * 2. 联动选中:修改currentRow会同步更新currentItem(选中条目对象),反之修改currentItem也会更新currentRow;
     * 3. 信号触发:设置有效行号时会触发currentRowChanged()和currentItemChanged()信号。
     */

    /**
     * @property QListWidget::count
     * @brief QListWidget列表中条目总行数属性(只读)
     * @details 只读属性,实时统计列表中QListWidgetItem的总数,默认值为0(空列表);增删条目时自动更新,是判断列表是否为空、遍历列表的核心依据。
     *
     * 【关联API详解】
     * 1. int count() const → 获取列表总行数;
     * 2. bool isEmpty() const → 快速判断列表是否为空(等价于count() == 0)。
     *
     * @使用示例:
     * // 统计总行数并判断是否为空
     * int total = ui->listWidget->count();
     * if (ui->listWidget->isEmpty()) {
     *     qDebug() << "列表为空";
     * } else {
     *     qDebug() << "列表总行数:" << total;
     * }
     *
     * 【关键注意事项】
     * 1. 只读特性:无法直接赋值修改,仅通过addItem/insertItem/takeItem等方法间接变更;
     * 2. 实时更新:增删条目后立即生效,无需手动刷新;
     * 3. 行号关联:有效行号上限为count()-1,遍历列表时常用for(int i=0; i<count(); i++)。
     */

    /**
     * @property QListWidget::itemAlignment
     * @brief QListWidget列表条目整体的对齐方式属性
     * @details 控制所有条目在列表控件内的整体对齐位置(水平+垂直),区别于单个条目内文本的对齐(setTextAlignment),默认值为Qt::AlignLeft | Qt::AlignTop。
     *
     * 【核心对齐枚举值】
     * | 枚举值         | 说明                 |
     * |----------------|----------------------|
     * | Qt::AlignLeft  | 水平左对齐(默认)|
     * | Qt::AlignHCenter| 水平居中             |
     * | Qt::AlignRight | 水平右对齐           |
     * | Qt::AlignTop   | 垂直顶部对齐(默认)|
     * | Qt::AlignVCenter| 垂直居中             |
     * | Qt::AlignCenter| 水平+垂直居中        |
     *
     * 【关联API详解】
     * 1. Qt::Alignment itemAlignment() const → 获取条目整体对齐方式;
     * 2. void setItemAlignment(Qt::Alignment alignment) → 设置条目整体对齐方式。
     *
     * @使用示例:
     * // 设置所有条目在列表中水平+垂直居中
     * ui->listWidget->setItemAlignment(Qt::AlignCenter);
     * ui->listWidget->setFixedSize(300, 200); // 固定控件尺寸,对齐效果更明显
     *
     * 【关键注意事项】
     * 1. 层级区别:该属性是"条目在控件中对齐",而非"文本在条目中对齐";
     * 2. 视觉适配:控件尺寸需大于条目总尺寸,才能体现明显的对齐效果;
     * 3. 组合使用:可通过|组合对齐方式(如Qt::AlignHCenter | Qt::AlignBottom)。
     */

    /**
     * @property QListWidget::selectRectVisible
     * @brief QListWidget选中条目矩形框是否可见的属性
     * @details 控制选中条目周围的高亮矩形框显隐,默认值为true(可见);设为false时,选中条目仍会触发选中信号,但无视觉矩形框高亮,可配合QSS自定义选中样式。
     *
     * 【关联API详解】
     * 1. bool isSelectRectVisible() const → 判断选中矩形框是否可见;
     * 2. void setSelectRectVisible(bool visible) → 设置选中矩形框显隐。
     *
     * @使用示例:
     * // 隐藏选中矩形框,仅通过文本颜色区分选中状态
     * ui->listWidget->setSelectRectVisible(false);
     * // 自定义选中条目文本颜色
     * QListWidgetItem* item = ui->listWidget->item(0);
     * if (item) item->setForeground(Qt::red);
     *
     * 【关键注意事项】
     * 1. 仅视觉影响:隐藏矩形框不改变选中逻辑和信号触发;
     * 2. 样式覆盖:若通过QSS自定义了QListWidget::item:selected样式,该属性可能被覆盖;
     * 3. 交互兼容:隐藏后条目仍可被选中/点击,不影响交互功能。
     */

    /**
     * @property QListWidget::spacing
     * @brief QListWidget列表条目之间的间距属性(像素)
     * @details 控制相邻条目间的水平/垂直间距,默认值为0(无间距);未开启换行时仅控制垂直间距,开启换行(isWrapping=true)时同时控制水平和垂直间距。
     *
     * 【关联API详解】
     * 1. int spacing() const → 获取条目间距(像素);
     * 2. void setSpacing(int space) → 设置条目间距(负值自动修正为0)。
     *
     * @使用示例:
     * // 设置条目间距为8像素,提升视觉舒适度
     * ui->listWidget->setSpacing(8);
     *
     * 【关键注意事项】
     * 1. 单位:间距单位为像素,数值越大条目间空隙越大;
     * 2. 换行适配:开启wrapping时,spacing同时控制行内水平间距和行间垂直间距;
     * 3. 布局影响:间距会增加列表整体尺寸,需结合控件大小适配。
     */

    QListWidget* lw=new QListWidget(this);

    lw->setGeometry(100,100,300,300);

    //注意,严格注意,我们创建的QListWidgetItem对象,不能是栈上的对象,必须要用new出来的QListWidgetItem
    //否则代码结束后,这些局部对象会被自动销毁,QListWidget 里保存的指针就变成了无效地址,所以界面上看不到这些条目。
    QListWidgetItem* item1=new QListWidgetItem("1");
    lw->addItem(item1);

    QListWidgetItem* item2=new QListWidgetItem("2");
    lw->addItem(item2);

    QListWidgetItem* item3=new QListWidgetItem("3");
    lw->addItem(item3);

    //我们也可以直接使用addItem方法,直接传入字符串,没有什么特殊要求的话,直接传入字符串还是最方便的
    lw->addItem("4");

    int count=lw->count();

    lw->setSpacing(5);

    lw->setItemAlignment(Qt::AlignLeft);
}

Widget::~Widget()
{
    delete ui;
}

第四章 QListWidget 核心属性详解(二)

讲完了第一部分属性,我们接下来讲第二部分:sortingEnabled(是否允许自动排序)、isWrapping(是否允许换行)。


4.1 属性六:sortingEnabled------ 要不要自动排序?

4.1.1 属性的核心定义

sortingEnabled 是 QListWidget 用于控制列表是否按条目文本内容自动升序排序 的属性 ------ 默认值为 false(不排序);设为 true 时,新增 / 修改条目文本、插入条目都会触发自动排序,条目行号会重新分配。

通俗理解:sortingEnabled 就像 "清单的自动排序开关"------ 如果开关打开,你每加一行、每改一行的字,清单都会自动按文字顺序重新排列;如果开关关闭,条目就按你添加的顺序排列,不会动。

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 默认值为 false(不排序)------ 刚创建 QListWidget 时,条目按添加顺序排列;
  2. 排序规则(超级重要!) :
    • 默认按文本的 Unicode 编码升序排列;
    • 顺序大致是:数字 < 字母 < 中文;
    • 中文按拼音或 Unicode 编码排序(取决于系统和 Qt 版本);
  3. 开启后新增 / 修改 / 插入都会触发自动排序 :
    • 设为 true 后,调用 addItem()、insertItem()、修改条目文本(item->setText())都会触发自动排序;
    • 条目行号会重新分配,原有的行号会失效!
  4. 行号变化(超级重要!) :
    • 排序后原行号失效,条目行号重新分配;
    • 如果你之前保存了某个行号,排序后可能对应的不是同一个条目了!
  5. 性能影响(超级重要!) :
    • 大量条目(如 1000+)开启自动排序会轻微影响增删效率;
    • 建议批量增删条目后再开启自动排序,或者批量增删时先关闭,增删完再开启并手动排序;
  6. 手动排序(超级重要!) :
    • 你可以通过 sortItems() 方法手动触发排序,无需开启 sortingEnabled;
    • sortItems() 可以指定升序(Qt::AscendingOrder)或降序(Qt::DescendingOrder)。
4.1.2 关联 API 详解(逐词逐句,零模糊)
1. 判断是否开启自动排序:bool isSortingEnabled () const

函数原型:

复制代码
bool QListWidget::isSortingEnabled() const;

逐词逐句底层解析:

  • bool:返回值类型,返回 true 或 false;
  • QListWidget:::成员函数;
  • isSortingEnabled():函数名,"是不是开启了自动排序" 的意思;
  • const:常成员函数。

返回值说明:

  • true 表示开启自动排序;
  • false 表示不排序(默认)。
2. 设置是否开启自动排序:void setSortingEnabled (bool enable)

函数原型:

复制代码
void QListWidget::setSortingEnabled(bool enable);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • setSortingEnabled():函数名,"设置是否开启自动排序" 的意思;
  • bool enable:入参,enable 是 true 开启,false 关闭。

参数说明:

  • enable:true 开启自动排序,false 关闭。
3. 【重要】手动触发排序:void sortItems (Qt::SortOrder order = Qt::AscendingOrder)

函数原型:

复制代码
void QListWidget::sortItems(Qt::SortOrder order = Qt::AscendingOrder);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • sortItems():函数名,"排序条目" 的意思;
  • Qt::SortOrder order:入参,排序顺序,默认是升序;
  • Qt::SortOrder 是枚举类型,有两个值:
    • Qt::AscendingOrder:升序(默认);
    • Qt::DescendingOrder:降序。

参数说明:

  • order:排序顺序,Qt::AscendingOrder 升序,Qt::DescendingOrder 降序;
  • 默认是升序。

关键注意事项:

  • sortItems() 可独立使用,无需依赖 sortingEnabled 状态 ------ 哪怕 sortingEnabled=false,调用 sortItems() 也会立即排序!
4.1.3 使用示例
复制代码
#include <Qt>

// 先关闭自动排序(批量添加时推荐)
ui->listWidget->setSortingEnabled(false);

// 批量添加条目(乱序添加)
ui->listWidget->addItem("Python");
ui->listWidget->addItem("C++");
ui->listWidget->addItem("Java");
ui->listWidget->addItem("Go");

// 示例1:开启自动排序(按文本升序排列)
ui->listWidget->setSortingEnabled(true);
// 此时条目会自动排序:C++ → Go → Java → Python

// 示例2:手动触发降序排序(无需开启 sortingEnabled)
ui->listWidget->sortItems(Qt::DescendingOrder);
// 此时条目会降序排列:Python → Java → Go → C++
4.1.4 关键注意事项(必知!)
  1. 排序规则(超级重要!):默认按 Unicode 编码升序,数字 < 字母 < 中文;
  2. 行号变化(超级重要!):排序后原行号失效,重新分配;
  3. 性能影响(超级重要!):大量条目批量增删时建议先关闭自动排序;
  4. 手动排序(超级重要!) :sortItems() 可独立使用,无需开启 sortingEnabled;
  5. 默认值为 false。

4.2 属性七:isWrapping------ 条目要不要换行显示?

4.2.1 属性的核心定义

isWrapping 是 QListWidget 用于控制列表条目在控件宽度不足时是否自动换行 的属性 ------ 默认值为 false(不换行,仅纵向单列展示);设为 true 时,条目从左到右排列,一行放不下则换行,形成多列流式布局。

通俗理解:isWrapping 就像 "清单的换行开关"------ 如果开关关闭,所有条目排成一列,从上到下;如果开关打开,条目先从左到右排,一行排不下了就换到下一行,形成多列,像网格一样。

这里有几个超级重要的规则,必须牢记:

  1. 默认值为 false(不换行,纵向单列)------ 刚创建 QListWidget 时,条目是纵向单列排列的;
  2. 设为 true 时变为多列流式布局 :
    • 条目从左到右排列,一行放不下则换行;
    • 布局依赖列表视图模式(默认是 IconMode,适合换行;如果是 ListMode,换行效果可能不同);
  3. 行号计算(超级重要!) :
    • count() 仍统计总条目数,不受换行影响;
    • currentRow() 按视觉行号计算(而非原始添加顺序);
  4. spacing 同时控制水平和垂直间距(超级重要!) :
    • 开启换行后,spacing 属性同时控制条目间的水平间距 (左右)和垂直间距(上下);
  5. 视觉适配(超级重要!) :
    • 换行适合展示短文本、小图标类条目;
    • 长文本条目换行后可读性降低,不建议用换行布局;
  6. 需配合固定宽度触发换行 :
    • 你需要给 QListWidget 设置一个固定宽度,当一行放不下所有条目时才会触发换行;
    • 如果 QListWidget 宽度自适应,可能会一直变宽,不会换行。
4.2.2 关联 API 详解(逐词逐句,零模糊)
1. 判断是否允许换行:bool isWrapping () const

函数原型:

复制代码
bool QListWidget::isWrapping() const;

逐词逐句底层解析:

  • bool:返回值类型,返回 true 或 false;
  • QListWidget:::成员函数;
  • isWrapping():函数名,"是不是允许换行" 的意思;
  • const:常成员函数。

返回值说明:

  • true 表示允许换行;
  • false 表示不换行(默认)。
2. 设置是否允许换行:void setWrapping (bool wrap)

函数原型:

复制代码
void QListWidget::setWrapping(bool wrap);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • setWrapping():函数名,"设置是否允许换行" 的意思;
  • bool wrap:入参,wrap 是 true 允许换行,false 不换行。

参数说明:

  • wrap:true 允许换行,false 不换行。
4.2.3 使用示例
复制代码
// 先给 QListWidget 设置固定宽度(触发换行!)
ui->listWidget->setFixedWidth(300);

// 开启换行
ui->listWidget->setWrapping(true);

// 设置条目间距(同时控制水平和垂直!)
ui->listWidget->setSpacing(10);

// 添加多个短文本条目
for (int i = 1; i <= 20; ++i) {
    ui->listWidget->addItem(QString("条目%1").arg(i));
}
// 此时条目会从左到右排列,一行放不下则换行,形成多列流式布局
4.2.4 关键注意事项(必知!)
  1. 设为 true 时变为多列流式布局(超级重要!);
  2. spacing 同时控制水平和垂直间距(超级重要!);
  3. 需配合固定宽度触发换行(超级重要!);
  4. 视觉适配:适合短文本、小图标条目;
  5. 默认值为 false。

示例代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //OK,本文件我们来学习QListWidget的剩下几个属性,也是比较简单的,一般使用默认的就行~~~
    //sortingEnabled、isWrapping、selectRectVisible属性,具体的看下面解析

    /**
    * @class QListWidget
    * @brief Qt中纵向列表展示控件的排序/换行/选中视觉属性
    * @details 以下属性聚焦QListWidget的功能开关与选中视觉定制,sortingEnabled控制列表自动排序,isWrapping控制条目换行布局,selectRectVisible控制选中条目的矩形高亮显隐,是定制列表交互与视觉风格的核心配置。
    */

   // ============================== 核心属性详解 ==============================

   /**
    * @property QListWidget::sortingEnabled
    * @brief QListWidget是否允许列表条目自动排序的属性
    * @details 控制列表是否按条目文本内容自动升序排序,默认值为false(不排序);设为true时,新增/修改条目文本、插入条目都会触发自动排序,条目行号会重新分配。
    *
    * 【关联API详解】
    * 1. bool isSortingEnabled() const → 判断是否开启自动排序;
    * 2. void setSortingEnabled(bool enable) → 设置是否开启自动排序;
    * 3. void sortItems(Qt::SortOrder order = Qt::AscendingOrder) → 手动触发排序(可指定升序/降序,无需开启sortingEnabled)。
    *
    * @使用示例:
    * // 开启自动排序(按文本升序排列)
    * ui->listWidget->setSortingEnabled(true);
    * // 手动触发降序排序(即使未开启自动排序也生效)
    * ui->listWidget->sortItems(Qt::DescendingOrder);
    *
    * 【关键注意事项】
    * 1. 排序规则:默认按文本的Unicode编码升序排列(数字<字母<中文),中文按拼音/Unicode排序;
    * 2. 行号变化:排序后原行号失效,条目行号重新分配,currentRow/count等属性仍正常生效;
    * 3. 性能影响:大量条目(如1000+)开启自动排序会轻微影响增删效率,建议批量增删后再开启;
    * 4. 手动排序:sortItems()可独立使用,无需依赖sortingEnabled状态。
    */

   /**
    * @property QListWidget::isWrapping
    * @brief QListWidget是否允许条目换行显示的属性
    * @details 控制列表条目在控件宽度不足时是否自动换行,默认值为false(不换行,仅纵向单列展示);设为true时,条目从左到右排列,一行放不下则换行,形成多列流式布局。
    *
    * 【关联API详解】
    * 1. bool isWrapping() const → 判断是否允许换行;
    * 2. void setWrapping(bool wrap) → 设置是否允许换行。
    *
    * @使用示例:
    * // 开启换行,固定列表宽度触发流式布局
    * ui->listWidget->setWrapping(true);
    * ui->listWidget->setFixedWidth(200); // 宽度不足时条目自动换行
    *
    * 【关键注意事项】
    * 1. 布局依赖:换行效果需配合列表视图模式(默认IconMode),纵向列表开启后变为流式多列布局;
    * 2. 行号计算:count()仍统计总条目数,currentRow按视觉行号计算(而非原始添加顺序);
    * 3. 间距配合:换行后spacing属性同时控制条目间的水平和垂直间距,可通过setSpacing()调整;
    * 4. 视觉适配:换行适合展示短文本、小图标类条目,长文本条目换行后可读性降低。
    */

   /**
    * @property QListWidget::selectRectVisible
    * @brief QListWidget选中条目对应的高亮矩形框是否可见的属性
    * @details 控制选中条目周围是否显示系统默认的高亮矩形框,默认值为true(可见);设为false时,选中状态仍生效(触发选中信号),但视觉上无矩形框高亮,可通过QSS自定义选中样式替代。
    *
    * 【关联API详解】
    * 1. bool isSelectRectVisible() const → 判断选中矩形框是否可见;
    * 2. void setSelectRectVisible(bool visible) → 设置选中矩形框显隐。
    *
    * @使用示例:
    * // 隐藏默认选中矩形框,自定义选中条目背景色
    * ui->listWidget->setSelectRectVisible(false);
    * // 给选中条目设置红色背景(需结合QSS或条目属性)
    * QListWidgetItem* item = ui->listWidget->currentItem();
    * if (item) item->setBackground(Qt::lightGray);
    *
    * 【关键注意事项】
    * 1. 仅视觉影响:隐藏矩形框不改变选中逻辑、行号/条目对象关联,也不影响选中信号触发;
    * 2. 样式覆盖:若通过QSS设置了`QListWidget::item:selected`样式,该属性可能被覆盖,以QSS样式为准;
    * 3. 交互兼容:即使隐藏矩形框,条目仍可被点击/选中/双击,所有交互功能正常。
    */

    //比较简单,所以我就不演示了
}

Widget::~Widget()
{
    delete ui;
}

第五章 QListWidget 核心方法详解

讲完了所有核心属性,我们接下来讲 QListWidget 的核心方法 ------ 这是操作列表条目最核心的接口,覆盖添加、插入、删除、选中、查询全生命周期。我们讲:addItem(两种重载)、currentItem、setCurrentItem、setCurrentRow、insertItem(两种重载)、item、takeItem。


5.1 方法一:addItem ()------ 向列表末尾添加条目(两种重载)

5.1.1 方法的核心定义

addItem() 是 QListWidget 最基础、最常用、最高频 的方法 ------ 它用于向列表末尾添加条目,有两种重载形式:

  1. 重载 1:通过文本快速创建默认样式条目;
  2. 重载 2:添加自定义配置(图标 / 字体 / 尺寸)的条目。

通俗理解:addItem() 就像 "在清单的最后面加一行纸"------ 重载 1 是 "直接拿一张空白纸,写上字加进去";重载 2 是 "拿一张你已经写好字、贴好图、设置好字体的纸加进去"。

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 内存管理!(超级重要!说三遍!) :
    • 重载 2 的 item 参数(自定义条目指针)无需手动 delete------ 列表接管所有权,条目会随 QListWidget 一起销毁;
    • 删除条目需用 takeItem(),不要直接 delete 列表里的条目!
  2. 排序影响(超级重要!) :
    • 若开启 sortingEnabled=true,添加的条目会自动排序,不一定在列表末尾!
    • 排序后条目位置由文本决定,不是添加顺序!
  3. 空值处理 :
    • 重载 1 的 label 为空字符串也可添加,显示为空行;
    • 重载 2 的 item 为 nullptr 时无操作,不会添加任何东西;
  4. 开篇的注意事项再强调一遍!(超级重要!) :
    • 重载 2 的 item 必须是 new 出来的堆对象,不能是栈上的对象!
    • 否则代码结束后局部对象被销毁,界面上看不到条目!
5.1.2 关联 API 详解(逐词逐句,零模糊)

addItem() 有两种重载形式,我们逐个来讲:

1. 重载 1:通过文本快速添加条目

函数原型:

复制代码
void QListWidget::addItem(const QString &label);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • addItem():函数名,"添加条目" 的意思;
  • const QString &label:入参,label 是条目显示的文本。

参数说明:

  • label:条目显示的文本,QString 类型;
  • 可以是空字符串(显示为空行)。

特点:

  • 快速、便捷,无需手动 new QListWidgetItem;
  • 条目是默认样式,无图标、默认字体。
2. 重载 2:添加自定义配置的条目

函数原型:

复制代码
void QListWidget::addItem(QListWidgetItem *item);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • addItem():函数名,"添加条目" 的意思;
  • QListWidgetItem *item:入参,item 是自定义的 QListWidgetItem 对象指针。

参数说明:

  • item:自定义的 QListWidgetItem 对象指针;
  • 必须是 new 出来的堆对象!不能是栈对象!
  • 不能是 nullptr(否则无操作)。

特点:

  • 灵活,可自定义图标、字体、尺寸、对齐方式等;
  • 列表接管所有权,无需手动 delete。
5.1.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QIcon>

// 示例1:重载 1------快速添加文本条目(最常用!)
ui->listWidget->addItem("C++");
ui->listWidget->addItem("Java");
ui->listWidget->addItem("Python");

// 示例2:重载 2------添加自定义图标+字体的条目
// 1. new 一个堆对象(必须!)
QListWidgetItem* customItem = new QListWidgetItem("自定义条目");
// 2. 自定义配置
customItem->setIcon(QIcon(":/images/icon.png")); // 设置图标
QFont font("微软雅黑", 12, QFont::Bold);
customItem->setFont(font); // 设置字体
// 3. 添加到列表
ui->listWidget->addItem(customItem);
// 注意:不需要手动 delete customItem!列表接管了!
5.1.4 关键注意事项(必知!)
  1. 内存管理!(超级重要!说三遍!):重载 2 的 item 无需手动 delete,列表接管所有权;
  2. 必须是 new 出来的堆对象!(超级重要!开篇就讲!):重载 2 的 item 不能是栈对象!
  3. 排序影响(超级重要!):开启 sortingEnabled 后,添加的条目会自动排序,不一定在末尾!
  4. 空值处理:重载 2 的 item 为 nullptr 时无操作。

5.2 方法二:currentItem ()------ 获取当前选中的条目对象

5.2.1 方法的核心定义

currentItem() 是 QListWidget 用于获取当前选中条目对象指针 的核心方法 ------ 无选中条目 / 列表为空时返回 nullptr,是操作选中条目属性(文本 / 图标)的核心入口。

通俗理解:currentItem() 就像 "拿到清单上当前被标亮的那一行纸"------ 拿到这张纸后,你就可以读它上面的字、改它上面的字、换它的图标;如果没有任何一行被标亮,或者清单是空的,你就拿不到纸(返回 nullptr)。

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 判空强制!(超级重要!说三遍!) :
    • 列表为空 / 无选中时返回 nullptr;
    • 必须先判空再操作! 直接操作 nullptr 会导致程序崩溃!
    • 这是新手最容易踩的坑之一!
  2. 联动 currentRow :currentItem() 对应的行号就是 currentRow(),二者一一对应;
  3. 修改其中一个,另一个自动更新 :修改 currentItem 会自动更新 currentRow,反之亦然。
5.2.2 关联 API 详解(逐词逐句,零模糊)
1. 获取当前选中条目对象:QListWidgetItem* currentItem () const

函数原型:

复制代码
QListWidgetItem* QListWidget::currentItem() const;

逐词逐句底层解析:

  • QListWidgetItem*:返回值类型,返回当前选中条目的指针;
  • QListWidget:::成员函数;
  • currentItem():函数名,"获取当前条目" 的意思;
  • const:常成员函数。

返回值说明:

  • 返回 QListWidgetItem* 类型的指针;
  • 有选中时返回对应条目的指针;
  • 无选中 / 列表为空时返回 nullptr;
  • 必须先判空再操作!
5.2.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QDebug>

// 添加条目并选中第一个
ui->listWidget->addItem("条目1");
ui->listWidget->setCurrentRow(0);

// 获取当前选中条目并操作(必须先判空!)
QListWidgetItem* selectedItem = ui->listWidget->currentItem();
if (selectedItem != nullptr) { // 判空!判空!判空!
    // 读取文本
    qDebug() << "当前选中条目文本:" << selectedItem->text();
    // 修改文本
    selectedItem->setText("已修改的条目");
} else {
    qDebug() << "当前无选中项";
}
5.2.4 关键注意事项(必知!)
  1. 判空强制!(超级重要!说三遍!):必须先判空再操作,否则程序崩溃!
  2. 联动 currentRow:二者一一对应;
  3. 无选中返回 nullptr。

5.3 方法三:setCurrentItem ()------ 设置指定条目为当前选中项

5.3.1 方法的核心定义

setCurrentItem() 是 QListWidget 用于精准选中指定条目 的方法 ------item 需是当前列表内的条目,设置后触发 currentItemChanged/currentRowChanged 信号。

通俗理解:setCurrentItem() 就像 "指定清单上的某一行纸,把它标亮"------ 你要指定的这一行纸必须已经在清单里了,否则标亮不了。

这里有几个超级重要的规则,必须牢记:

  1. 有效性(超级重要!) :
    • item 必须是已添加到列表的条目;
    • 如果 item 是刚 new 出来还没添加的,或者是其他列表的条目,设置无效;
  2. 信号触发(超级重要!) :
    • 设置有效条目会依次触发 currentItemChanged、currentRowChanged 信号;
  3. 取消选中(超级重要!) :
    • 传入 nullptr 可清空所有选中状态,currentRow() 变为 -1;
  4. 等价操作 :setCurrentItem(item) 等价于 setCurrentRow(row_of_item)。
5.3.2 关联 API 详解(逐词逐句,零模糊)
1. 设置指定条目为当前选中项:void setCurrentItem (QListWidgetItem* item)

函数原型:

复制代码
void QListWidget::setCurrentItem(QListWidgetItem* item);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • setCurrentItem():函数名,"设置当前条目" 的意思;
  • QListWidgetItem* item:入参,要选中的条目指针。

参数说明:

  • item:要选中的条目指针;
  • 必须是已添加到列表的条目;
  • 传入 nullptr 可取消所有选中。
5.3.3 使用示例
复制代码
#include <QListWidgetItem>

// 添加几个条目并保存指针
QListWidgetItem* item1 = new QListWidgetItem("条目1");
QListWidgetItem* item2 = new QListWidgetItem("条目2");
ui->listWidget->addItem(item1);
ui->listWidget->addItem(item2);

// 示例1:选中 item2
ui->listWidget->setCurrentItem(item2);

// 示例2:取消所有选中
ui->listWidget->setCurrentItem(nullptr);
5.3.4 关键注意事项(必知!)
  1. 有效性(超级重要!):item 必须是已添加到列表的条目;
  2. 信号触发(超级重要!):设置有效条目会触发信号;
  3. 传入 nullptr 取消选中;
  4. 等价于 setCurrentRow。

5.4 方法四:setCurrentRow ()------ 通过行号设置当前选中项

这个方法我们在讲 currentRow 属性时已经详细讲过了,这里简单回顾一下:

  • 行号从 0 开始;
  • 超出范围取消选中;
  • 设置有效行号触发 currentRowChanged 和 currentItemChanged 信号。

5.5 方法五:insertItem ()------ 在指定位置插入条目(两种重载)

5.5.1 方法的核心定义

insertItem() 是 QListWidget 用于在指定行号位置插入条目 的方法 ------ 区别于 addItem()(仅追加末尾),它支持在任意位置插入,有两种重载形式:

  1. 重载 1:通过文本快速插入默认样式条目;
  2. 重载 2:插入自定义配置的条目。

通俗理解:insertItem() 就像 "在清单的指定位置插一行纸"------ 比如在第 2 行(行号 1)前面插一行,原来的第 2 行及后面的行都会自动往后挪一位。

这里有几个超级重要的规则,必须牢记:

  1. 行号容错(超级重要!) :
    • row < 0 → 插在开头(行号 0);
    • row > count() → 插在末尾(等价于 addItem());
    • 不用担心行号超出范围,Qt 会自动适配!
  2. 行号偏移(超级重要!) :
    • 插入位置后的条目行号自动 +1;
    • 比如在索引 1 插入,原索引 1 的条目变为索引 2,原索引 2 变为索引 3,以此类推;
  3. 内存管理(超级重要!) :
    • 重载 2 的 item 必须是 new 出来的堆对象;
    • 列表接管所有权,无需手动 delete;
  4. 排序影响(超级重要!) :
    • 若开启 sortingEnabled=true,插入的条目会自动排序,不一定在你指定的位置!
5.5.2 关联 API 详解(逐词逐句,零模糊)
1. 重载 1:通过文本快速插入条目

函数原型:

复制代码
void QListWidget::insertItem(int row, const QString &label);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • insertItem():函数名,"插入条目" 的意思;
  • int row:入参,插入位置的行号;
  • const QString &label:入参,条目显示的文本。

参数说明:

  • row:插入位置的行号,从 0 开始;
    • row < 0 → 插开头;
    • row > count() → 插末尾;
  • label:条目显示的文本。
2. 重载 2:插入自定义配置的条目

函数原型:

复制代码
void QListWidget::insertItem(int row, QListWidgetItem *item);

逐词逐句底层解析:

  • void:无返回值;
  • QListWidget:::成员函数;
  • insertItem():函数名,"插入条目" 的意思;
  • int row:入参,插入位置的行号;
  • QListWidgetItem *item:入参,自定义的条目指针。

参数说明:

  • row:插入位置的行号;
  • item:自定义的条目指针;
    • 必须是 new 出来的堆对象!
    • 不能是 nullptr。
5.5.3 使用示例
复制代码
#include <QListWidgetItem>

// 先添加几个条目
ui->listWidget->addItem("条目1"); // 行号 0
ui->listWidget->addItem("条目3"); // 行号 1

// 示例1:重载 1------在第 2 行(行号 1)前面插入"条目2"
ui->listWidget->insertItem(1, "条目2");
// 此时列表顺序:条目1(0)→ 条目2(1)→ 条目3(2)

// 示例2:重载 2------在开头插入自定义条目
QListWidgetItem* customItem = new QListWidgetItem("自定义插入条目");
ui->listWidget->insertItem(0, customItem); // row=0 插开头
// 此时列表顺序:自定义插入条目(0)→ 条目1(1)→ 条目2(2)→ 条目3(3)
5.5.4 关键注意事项(必知!)
  1. 行号容错(超级重要!):row<0 插开头,row>count () 插末尾;
  2. 行号偏移(超级重要!):插入位置后的条目行号自动 +1;
  3. 内存管理(超级重要!):重载 2 的 item 必须是 new 出来的堆对象;
  4. 排序影响(超级重要!):开启 sortingEnabled 后,插入的条目会自动排序。

5.6 方法六:item ()------ 通过行号获取对应条目对象

5.6.1 方法的核心定义

item() 是 QListWidget 用于通过行号获取对应条目对象指针 的方法 ------ 行号超出范围时返回 nullptr,是遍历 / 修改指定行条目的核心方法。

通俗理解:item() 就像 "拿到清单上指定行号的那一行纸"------ 比如你要拿第 2 行(行号 1)的纸,就调用 item(1);如果行号不对,就拿不到(返回 nullptr)。

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 判空必须!(超级重要!) :
    • 行号无效(row < 0 或 row >= count())时返回 nullptr;
    • 必须先判空再操作! 直接操作会崩溃!
  2. 实时性(超级重要!) :
    • 行号随增删 / 排序动态变化;
    • 如果你保存了某个行号,过了一段时间(比如增删了条目、排序了),这个行号对应的条目可能变了!
  3. 遍历常用 :遍历列表时常用 for(int i=0; i<count(); i++) 配合 item(i)。
5.6.2 关联 API 详解(逐词逐句,零模糊)
1. 通过行号获取对应条目对象:QListWidgetItem* item (int row) const

函数原型:

复制代码
QListWidgetItem* QListWidget::item(int row) const;

逐词逐句底层解析:

  • QListWidgetItem*:返回值类型,返回条目指针;
  • QListWidget:::成员函数;
  • item():函数名,"获取条目" 的意思;
  • int row:入参,行号。

参数说明:

  • row:行号,从 0 开始;
  • 有效范围:0 ≤ row < count()。

返回值说明:

  • 返回 QListWidgetItem* 类型的指针;
  • 行号有效返回对应条目指针;
  • 行号无效返回 nullptr;
  • 必须先判空再操作!
5.6.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QDebug>

// 添加几个条目
ui->listWidget->addItem("条目1");
ui->listWidget->addItem("条目2");
ui->listWidget->addItem("条目3");

// 示例1:获取第 2 行(行号 1)的条目并操作(必须判空!)
QListWidgetItem* item = ui->listWidget->item(1);
if (item != nullptr) { // 判空!
    qDebug() << "第 2 行的文本:" << item->text();
    item->setText("已修改的条目2");
}

// 示例2:遍历所有条目(常用!)
for (int i = 0; i < ui->listWidget->count(); ++i) {
    QListWidgetItem* loopItem = ui->listWidget->item(i);
    if (loopItem != nullptr) { // 判空!
        qDebug() << "第" << i+1 << "行:" << loopItem->text();
    }
}
5.6.4 关键注意事项(必知!)
  1. 判空必须!(超级重要!):行号无效返回 nullptr,必须先判空再操作!
  2. 实时性(超级重要!):行号随增删 / 排序动态变化;
  3. 遍历常用:配合 for 循环遍历所有条目。

5.7 方法七:takeItem ()------ 删除指定行的条目,并返回被删除的条目

5.7.1 方法的核心定义

takeItem() 是 QListWidget 用于删除指定行号条目 的核心方法 ------ 注意!它仅将条目从列表中移除,不自动释放内存 ,需手动 delete 返回的指针避免内存泄漏!

通俗理解:takeItem() 就像 "把清单上指定行的那一行纸抽出来"------ 抽出来后,这张纸就不在清单里了,其他行会自动往前挪填补位置;但这张纸还在你手里,你要自己处理掉(delete),否则它会一直占着内存(内存泄漏)!

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 内存管理!(超级重要!说三遍!) :
    • takeItem() 仅将条目从列表中移除,不自动释放内存!
    • 必须手动 delete 返回的指针! 否则会内存泄漏!
    • 这是新手最容易踩的坑之一!
  2. 行号偏移(超级重要!) :
    • 删除后后续条目行号自动 -1;
    • 比如删除索引 1,原索引 2 的条目变为索引 1,原索引 3 变为索引 2,以此类推;
  3. 选中状态(超级重要!) :
    • 若删除的是选中条目,currentRow() 变为 -1,取消选中;
  4. 返回值(超级重要!) :
    • 返回被删除的条目指针;
    • 行号无效返回 nullptr;
    • 拿到返回的指针后,要么 delete 它,要么把它添加到其他列表,不要让它泄漏!
5.7.2 关联 API 详解(逐词逐句,零模糊)
1. 删除指定行的条目:QListWidgetItem* takeItem (int row)

函数原型:

复制代码
QListWidgetItem* QListWidget::takeItem(int row);

逐词逐句底层解析:

  • QListWidgetItem*:返回值类型,返回被删除的条目指针;
  • QListWidget:::成员函数;
  • takeItem():函数名,"拿走条目" 的意思;
  • int row:入参,要删除的行号。

参数说明:

  • row:要删除的行号,从 0 开始;
  • 有效范围:0 ≤ row < count()。

返回值说明:

  • 返回 QListWidgetItem* 类型的指针;
  • 行号有效返回被删除的条目指针;
  • 行号无效返回 nullptr;
  • 必须手动 delete 返回的指针!
5.7.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QDebug>

// 添加几个条目
ui->listWidget->addItem("条目1"); // 行号 0
ui->listWidget->addItem("条目2"); // 行号 1
ui->listWidget->addItem("条目3"); // 行号 2

// 示例:删除第 2 行(行号 1)的条目,并释放内存(必须!)
QListWidgetItem* deletedItem = ui->listWidget->takeItem(1);
if (deletedItem != nullptr) { // 判空
    qDebug() << "被删除的条目文本:" << deletedItem->text();
    delete deletedItem; // 必须手动 delete!否则内存泄漏!
    deletedItem = nullptr; // 置空,避免野指针
}
// 此时列表顺序:条目1(0)→ 条目3(1),条目2 已被删除并释放
5.7.4 关键注意事项(必知!)
  1. 内存管理!(超级重要!说三遍!):必须手动 delete 返回的指针!否则内存泄漏!
  2. 行号偏移(超级重要!):删除后后续条目行号自动 -1;
  3. 选中状态(超级重要!):删除选中条目会取消选中;
  4. 返回值判空:行号无效返回 nullptr。

示例代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //OK,那么本文件我们就来学习一下QListWidget的核心方法,但是其实也是比较简单的
    //最关键的也就是addItem方法,剩下的倒是都没什么
    //还有一个currentItem也还行,获取到用户选择的条目~~~
    //还有一个删除指定位置条目的方法,名字是takeItem,也得稍微注意一下~~~

    /**
     * @class QListWidget
     * @brief Qt中纵向列表展示控件的核心条目操作方法
     * @details 以下方法覆盖QListWidget条目全生命周期管理(添加/插入/删除/选中/查询),是操作列表条目最核心的接口,支持通过文本快速创建条目、精准选中/查询指定行条目、灵活增删条目,适配各类列表交互场景。
     */

    // ============================== 核心方法详解 ==============================

    /**
     * @fn void QListWidget::addItem(const QString& label)
     * @fn void QListWidget::addItem(QListWidgetItem *item)
     * @brief 向列表**末尾**添加条目(两种重载形式)
     * @details 基础条目添加接口,重载1通过文本快速创建默认样式条目,重载2添加自定义配置(图标/字体/尺寸)的条目,添加后条目所有权移交至列表。
     *
     * @参数说明:
     * @param label - 重载1参数,条目显示的文本内容(空字符串也可添加,显示为空行);
     * @param item  - 重载2参数,自定义的QListWidgetItem对象指针(不可为nullptr)。
     *
     * @使用示例:
     * // 重载1:快速添加文本条目
     * ui->listWidget->addItem("基础文本条目");
     *
     * // 重载2:添加自定义图标+字体的条目
     * QListWidgetItem* customItem = new QListWidgetItem("自定义条目");
     * customItem->setIcon(QIcon(":/icon.png"));
     * customItem->setFont(QFont("微软雅黑", 12));
     * ui->listWidget->addItem(customItem);
     *
     * 【关键注意事项】
     * 1. 内存管理:重载2的item无需手动delete(列表接管所有权),删除条目需用takeItem;
     * 2. 排序影响:若开启sortingEnabled=true,添加的条目会自动排序,不一定在列表末尾;
     * 3. 空值处理:item为nullptr时重载2无操作,label为空时重载1添加空行条目。
     */

    /**
     * @fn QListWidgetItem* QListWidget::currentItem() const
     * @brief 获取当前**选中**的条目对象指针
     * @details 核心查询接口,返回当前激活选中的条目指针,无选中条目/列表为空时返回nullptr,是操作选中条目属性(文本/图标)的核心入口。
     *
     * @返回值:QListWidgetItem* - 当前选中条目指针(无选中返回nullptr)。
     *
     * @使用示例:
     * // 获取选中条目并修改其文本
     * QListWidgetItem* selectedItem = ui->listWidget->currentItem();
     * if (selectedItem != nullptr) { // 必须判空,避免空指针崩溃
     *     selectedItem->setText("已选中:" + selectedItem->text());
     * }
     *
     * 【关键注意事项】
     * 1. 判空强制:列表为空/无选中时返回nullptr,直接操作会导致程序崩溃;
     * 2. 联动关系:currentItem()对应的行号 = currentRow(),二者一一对应。
     */

    /**
     * @fn void QListWidget::setCurrentItem(QListWidgetItem* item)
     * @brief 设置指定条目为当前**选中**项
     * @details 精准选中条目接口,item需是当前列表内的条目,设置后触发currentItemChanged/currentRowChanged信号。
     *
     * @参数说明:
     * @param item - 要选中的条目指针(nullptr则取消所有选中)。
     *
     * @使用示例:
     * // 选中列表中第一个条目
     * QListWidgetItem* targetItem = ui->listWidget->item(0);
     * if (targetItem) ui->listWidget->setCurrentItem(targetItem);
     *
     * 【关键注意事项】
     * 1. 有效性:item必须是已添加到列表的条目,否则设置无效;
     * 2. 信号触发:设置有效条目会依次触发currentItemChanged、currentRowChanged信号;
     * 3. 取消选中:传入nullptr可清空所有选中状态,currentRow()变为-1。
     */

    /**
     * @fn void QListWidget::setCurrentRow(int row)
     * @brief 通过**行号**设置当前选中项
     * @details 行号版选中接口,等价于setCurrentItem(item(row)),行号从0开始计数,超出有效范围则取消选中。
     *
     * @参数说明:
     * @param row - 要选中的行号(有效范围:0 ≤ row < count())。
     *
     * @使用示例:
     * // 选中第2行(索引1)的条目
     * ui->listWidget->setCurrentRow(1);
     *
     * 【关键注意事项】
     * 1. 行号规则:行号从0开始,count()为总行数,超出范围则取消选中;
     * 2. 等价操作:setCurrentRow(row) ≡ setCurrentItem(item(row));
     * 3. 信号触发:设置有效行号会触发currentRowChanged/currentItemChanged信号。
     */

    /**
     * @fn void QListWidget::insertItem(int row, const QString& label)
     * @fn void QListWidget::insertItem(int row, QListWidgetItem *item)
     * @brief 在指定**行号位置**插入条目(两种重载形式)
     * @details 区别于addItem(仅追加末尾),支持在任意位置插入条目,行号超出范围时自动适配(<0插开头,>count()插末尾)。
     *
     * @参数说明:
     * @param row   - 插入位置的行号(从0开始);
     * @param label - 重载1参数,条目显示文本;
     * @param item  - 重载2参数,自定义条目指针(不可为nullptr)。
     *
     * @使用示例:
     * // 重载1:在第1行(索引0)插入文本条目
     * ui->listWidget->insertItem(0, "插入到开头的条目");
     *
     * // 重载2:在第3行(索引2)插入自定义条目
     * QListWidgetItem* insertItem = new QListWidgetItem("插入条目");
     * insertItem->setForeground(Qt::blue); // 设置文本颜色
     * ui->listWidget->insertItem(2, insertItem);
     *
     * 【关键注意事项】
     * 1. 行号容错:row<0 → 插开头;row>count() → 插末尾;
     * 2. 行号偏移:插入位置后的条目行号自动+1(如索引1插入,原索引1条目变为索引2);
     * 3. 内存管理:重载2的item所有权移交列表,无需手动delete。
     */

    /**
     * @fn QListWidgetItem* QListWidget::item(int row) const
     * @brief 通过**行号**获取对应条目指针
     * @details 行号→条目映射接口,返回指定行的条目指针,行号超出范围时返回nullptr,是遍历/修改指定行条目的核心方法。
     *
     * @参数说明:
     * @param row - 要查询的行号(从0开始)。
     *
     * @返回值:QListWidgetItem* - 指定行条目指针(行号无效返回nullptr)。
     *
     * @使用示例:
     * // 遍历所有条目并打印文本
     * for (int i = 0; i < ui->listWidget->count(); ++i) {
     *     QListWidgetItem* item = ui->listWidget->item(i);
     *     if (item) qDebug() << "第" << i+1 << "行:" << item->text();
     * }
     *
     * 【关键注意事项】
     * 1. 判空必须:行号无效时返回nullptr,直接操作会崩溃;
     * 2. 实时性:行号随增删/排序动态变化,需注意操作时机。
     */

    /**
     * @fn QListWidgetItem* QListWidget::takeItem(int row)
     * @brief 删除指定**行号**的条目,并返回被删除的条目指针
     * @details 核心删除接口,仅将条目从列表中移除(不自动释放内存),需手动delete返回的指针避免内存泄漏。
     *
     * @参数说明:
     * @param row - 要删除的行号(从0开始)。
     *
     * @返回值:QListWidgetItem* - 被删除的条目指针(行号无效返回nullptr)。
     *
     * @使用示例:
     * // 删除第1行(索引0)的条目并释放内存
     * QListWidgetItem* deletedItem = ui->listWidget->takeItem(0);
     * if (deletedItem) {
     *     delete deletedItem; // 必须手动释放,否则内存泄漏
     *     deletedItem = nullptr;
     * }
     *
     * 【关键注意事项】
     * 1. 内存管理:takeItem仅移除条目,需手动delete返回指针;
     * 2. 行号偏移:删除后后续条目行号自动-1;
     * 3. 选中状态:若删除的是选中条目,currentRow()变为-1,取消选中。
     */
}

Widget::~Widget()
{
    delete ui;
}

第六章 QListWidget 核心交互信号详解

讲完了所有核心方法,我们最后来讲 QListWidget 的核心交互信号 ------ 这是列表与业务逻辑联动的核心桥梁,覆盖选中变更、点击、双击、鼠标悬浮等场景。按照你提供的顺序,我们讲:currentItemChanged、currentRowChanged、itemClicked、itemDoubleClicked、itemEntered,还会补充你资料里提到的 itemPressed、itemSelectionChanged、currentTextChanged。


6.1 信号一:currentItemChanged------ 选中不同条目时触发(条目对象版)

6.1.1 信号的核心定义

currentItemChanged 是 QListWidget 最核心、最常用 的选中变更信号 ------ 它在选中不同条目时触发(选中同一条目不触发),可同时获取 "当前选中条目" 和 "上一个选中条目",便于对比处理选中状态的变更逻辑。

通俗理解:currentItemChanged 就像 "清单上标亮的行变了时通知你"------ 它会告诉你 "之前标亮的是哪一行,现在标亮的是哪一行";如果你重复点击同一行,它不会通知你,因为标亮的行没变。

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 判空强制!(超级重要!说三遍!) :
    • current(当前选中条目)和 old(上一个选中条目)都可能为 nullptr!
    • 首次选中时,old 是 nullptr;
    • 取消选中时,current 是 nullptr;
    • 必须先判空再操作! 直接操作会崩溃!
  2. 触发规则(超级重要!) :
    • 仅选中不同条目时触发;
    • 重复点击同一条目不触发;
  3. 触发场景(超级重要!) :
    • 用户点击不同条目;
    • 代码调用 setCurrentItem() / setCurrentRow();
    • 删除选中条目;
  4. 信号联动(超级重要!) :
    • 与 currentRowChanged() 同步触发;
    • 先触发 currentItemChanged,再触发 currentRowChanged;
  5. 代码触发 :调用 setCurrentItem() / setCurrentRow() 也会触发此信号。
6.1.2 信号参数详解

信号原型:

复制代码
void QListWidget::currentItemChanged(QListWidgetItem* current, QListWidgetItem* old);

参数说明:

  • current:QListWidgetItem* 类型,当前选中的条目指针;
    • 无选中时为 nullptr;
    • 必须先判空!
  • old:QListWidgetItem* 类型,上一个选中的条目指针;
    • 首次选中时为 nullptr;
    • 必须先判空!
6.1.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QDebug>

// 绑定信号(用 Lambda 表达式)
connect(ui->listWidget, &QListWidget::currentItemChanged,
        this, [=](QListWidgetItem* cur, QListWidgetItem* prev){
    // 判空!判空!判空!
    QString prevText = prev ? prev->text() : "无";
    QString curText = cur ? cur->text() : "无";
    qDebug() << "选中项变更:" << prevText << " → " << curText;

    // 典型用法:根据选中的条目更新右侧详情面板
    if (cur != nullptr) {
        // ui->detailLabel->setText(cur->text());
        // ui->btnDelete->setEnabled(true);
    } else {
        // ui->detailLabel->setText("无选中项");
        // ui->btnDelete->setEnabled(false);
    }
});
6.1.4 关键注意事项(必知!)
  1. 判空强制!(超级重要!说三遍!):current 和 old 都可能为 nullptr,必须先判空!
  2. 仅选中不同条目时触发(超级重要!):重复点击同一条目不触发!
  3. 信号联动(超级重要!):与 currentRowChanged 同步触发!
  4. 代码也会触发。

6.2 信号二:currentRowChanged------ 选中不同条目时触发(行号版)

6.2.1 信号的核心定义

currentRowChanged 是 currentItemChanged 的简化版信号------ 它仅返回当前选中条目的行号,无需处理条目指针判空,适配仅需行号的场景(如行号统计、索引关联)。

通俗理解:currentRowChanged 就像 "清单上标亮的行变了时通知你行号"------ 它只告诉你 "现在标亮的是第几行(代码行号)",不告诉你之前是第几行;如果你只需要行号,用这个信号更轻量。

这里有几个超级重要的规则,必须牢记:

  1. 行号规则(超级重要!) :
    • 行号从 0 开始;
    • 无选中时参数为 -1;
    • 用户视角需 +1 展示;
  2. 触发场景:所有导致选中项变更的操作均触发(点击 / 代码设置 / 删除选中项);
  3. 简洁性:仅需行号时优先使用此信号,无需处理条目指针。
6.2.2 信号参数详解

信号原型:

复制代码
void QListWidget::currentRowChanged(int currentRow);

参数说明:

  • currentRow:int 类型,当前选中条目的行号;
    • 从 0 开始;
    • 无选中时为 -1。
6.2.3 使用示例
复制代码
#include <QDebug>

// 绑定信号(用 Lambda 表达式)
connect(ui->listWidget, &QListWidget::currentRowChanged,
        this, [=](int row){
    if (row == -1) {
        qDebug() << "当前无选中项";
        ui->label->setText("当前无选中项");
    } else {
        qDebug() << "当前选中行号(代码):" << row;
        ui->label->setText(QString("当前选中第%1行").arg(row + 1)); // 行号+1 适配用户
    }
});
6.2.4 关键注意事项(必知!)
  1. 行号从 0 开始!(超级重要!);
  2. 无选中时为 -1;
  3. 简洁性:仅需行号时优先使用。

6.3 信号三:itemClicked------ 用户鼠标单击条目时触发

6.3.1 信号的核心定义

itemClicked 是 QListWidget 纯交互触发 的信号 ------ 它仅响应用户鼠标单击 操作,代码选中不触发,参数为被点击的条目指针(非 nullptr),是 "点击条目执行操作" 的核心入口。

通俗理解:itemClicked 就像 "用户用鼠标点了清单上某一行时通知你"------ 它只响应用户的点击,你用代码选中条目它不会通知你;而且点击的肯定是某一行,所以参数不会是 nullptr。

这里有几个超级重要的规则,必须牢记:

  1. 触发条件(超级重要!) :
    • 仅用户单击触发;
    • 代码调用 setCurrentItem() / setCurrentRow() 不触发;
    • 这点和 currentItemChanged 不一样!
  2. 参数有效性(超级重要!) :
    • item 始终为有效条目指针(无需判空);
    • 点击列表空白处(无条目区域)不触发此信号;
  3. 选中联动(超级重要!) :
    • 单击条目会自动将其设为选中项;
    • 因此会先触发 itemClicked(),再触发 currentItemChanged() / currentRowChanged();
  4. 重复点击同一条目也触发(超级重要!) :
    • 这点和 currentItemChanged 不一样!
    • 哪怕条目已经是选中项,再次点击也会触发 itemClicked()!
6.3.2 信号参数详解

信号原型:

复制代码
void QListWidget::itemClicked(QListWidgetItem* item);

参数说明:

  • item:QListWidgetItem* 类型,被单击的条目指针;
    • 始终有效(无需判空);
    • 点击空白处不触发。
6.3.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QMessageBox>

// 绑定信号(用 Lambda 表达式)
connect(ui->listWidget, &QListWidget::itemClicked,
        this, [=](QListWidgetItem* clickedItem){
    // 无需判空!
    QMessageBox::information(this, "点击提示",
                             QString("你点击了:%1").arg(clickedItem->text()));
});
6.3.4 关键注意事项(必知!)
  1. 仅用户单击触发(超级重要!):代码选中不触发!
  2. 参数有效性(超级重要!):无需判空!
  3. 选中联动(超级重要!):先触发 itemClicked,再触发 currentItemChanged!
  4. 重复点击同一条目也触发(超级重要!)!

6.4 信号四:itemDoubleClicked------ 用户鼠标双击条目时触发

6.4.1 信号的核心定义

itemDoubleClicked 是 QListWidget 适配 "双击条目执行核心操作" 场景的信号 ------ 它仅响应用户鼠标双击 操作,代码操作不触发,参数为被双击的条目指针(非 nullptr)。

通俗理解:itemDoubleClicked 就像 "用户用鼠标快速双击了清单上某一行时通知你"------ 它适合做 "打开文件""编辑条目""进入下一级" 这种需要双击确认的操作。

这里有几个超级重要的规则,必须牢记:

  1. 触发顺序(超级重要!) :
    • 双击会先触发 itemClicked()(第一次单击),再触发此信号;
    • 如果你同时绑定了这两个信号,要注意逻辑冲突!
  2. 触发条件(超级重要!) :
    • 仅用户双击触发;
    • 代码操作 / 单击均不触发;
  3. 参数有效性 :item 始终为有效条目指针(无需判空);
  4. 交互场景:适合 "编辑 / 打开 / 查看详情" 等需要双击确认的操作。
6.4.2 信号参数详解

信号原型:

复制代码
void QListWidget::itemDoubleClicked(QListWidgetItem* item);

参数说明:

  • item:QListWidgetItem* 类型,被双击的条目指针;
    • 始终有效(无需判空)。
6.4.3 使用示例
复制代码
#include <QListWidgetItem>
#include <QInputDialog>

// 绑定信号(用 Lambda 表达式)
connect(ui->listWidget, &QListWidget::itemDoubleClicked,
        this, [=](QListWidgetItem* doubleItem){
    // 双击条目编辑文本
    QString newText = QInputDialog::getText(this, "编辑条目",
                                             "修改文本:",
                                             QLineEdit::Normal,
                                             doubleItem->text());
    if (!newText.isEmpty()) {
        doubleItem->setText(newText);
    }
});
6.4.4 关键注意事项(必知!)
  1. 触发顺序(超级重要!):先触发 itemClicked(第一次单击),再触发此信号!
  2. 仅用户双击触发;
  3. 参数有效性:无需判空。

6.5 信号五:itemEntered------ 鼠标光标进入条目区域时触发

6.5.1 信号的核心定义

itemEntered 是 QListWidget 用于鼠标悬浮交互 的信号 ------ 它在鼠标光标进入条目区域时触发,需开启鼠标跟踪才会触发!

通俗理解:itemEntered 就像 "鼠标移到清单上某一行时通知你"------ 你可以用它做 "鼠标悬浮高亮""显示 Tooltip 提示" 等效果;但注意,你必须先开启鼠标跟踪,否则它不会通知你!

这里有几个超级重要的规则,必须牢记,刻在脑子里:

  1. 前置条件!(超级重要!说三遍!) :
    • 必须调用 setMouseTracking(true)!
    • 否则永不触发!
    • 这是新手最容易忽略的!
  2. 触发频率(超级重要!) :
    • 鼠标在条目间移动时高频触发;
    • 避免在信号槽内执行耗时操作!
  3. 仅进不出(超级重要!) :
    • 此信号仅响应 "进入" 条目;
    • 鼠标离开条目需结合 QMouseEvent 手动处理(没有 itemLeft 信号);
  4. 参数有效性 :item 始终为有效条目指针(无需判空)。
6.5.2 信号参数详解

信号原型:

复制代码
void QListWidget::itemEntered(QListWidgetItem* item);

参数说明:

  • item:QListWidgetItem* 类型,鼠标进入的条目指针;
    • 始终有效(无需判空)。
6.5.3 使用示例
复制代码
#include <QListWidgetItem>

// 第一步:必须开启鼠标跟踪!(超级重要!)
ui->listWidget->setMouseTracking(true);

// 第二步:绑定信号(用 Lambda 表达式)
connect(ui->listWidget, &QListWidget::itemEntered,
        this, [=](QListWidgetItem* enterItem){
    // 鼠标进入时设置浅灰背景
    enterItem->setBackground(Qt::lightGray);
    // 注意:鼠标离开时恢复背景需结合鼠标事件手动处理
});
6.5.4 关键注意事项(必知!)
  1. 前置条件!(超级重要!说三遍!):必须调用 setMouseTracking (true)!
  2. 触发频率(超级重要!):避免在信号槽内执行耗时操作!
  3. 仅进不出(超级重要!):离开需手动处理!
  4. 参数有效性:无需判空。

6.6 补充信号:itemPressed、itemSelectionChanged、currentTextChanged

我们简单补充一下:

6.6.1 itemPressed------ 鼠标按键在条目上按下时触发
  • 触发时机:鼠标按键在条目上按下(尚未释放)时触发;
  • 典型用法:自定义拖拽操作(Drag & Drop)的起始判断;
  • 注意:此时还未产生 "点击" 或 "选中" 的最终结果。
6.6.2 itemSelectionChanged------ 选中状态改变时触发(多选模式专用!)
  • 触发时机:列表中被选中的条目集合发生变化时触发;
  • 关键点 :
    • 单选模式下,行为类似 currentItemChanged;
    • 多选模式下最重要! ------currentItemChanged 只追踪 "当前焦点项",而这个信号追踪 "所有被选中的项";
  • 典型用法:批量操作按钮的状态更新(如选中多项时才启用 "批量删除")、统计选中数量。
6.6.3 currentTextChanged------ 当前选中项的文本改变时触发
  • 触发时机:当前选中项变化导致显示的文本变化,或当前项被编辑后文本变化时触发;
  • 典型用法:联动另一个只显示文本的标签、根据文本内容过滤其他列表。

示例代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QListWidgetItem>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //OK,本文件我们就来学习一下QListWidget的核心信号
    //其实也没几个难的信号

    /*
        currentItemChanged(QListWidgetItem*current, QListWidgetItem* old)
        选中不同元素时会触发. 参数是当前选中的元素和之前选中的元素.

        currentRowChanged(int) 选中不同元素时会触发. 参数是当前选中元素的行数.

        itemClicked(QListWidgetItem* item) 点击某个元素时触发

        itemDoubleClicked(QListWidgetItem*item)双击某个元素时触发

        itemEntered(QListWidgetItem* item) 鼠标进入元素时触发
    */

    /**
     * @class QListWidget
     * @brief Qt中纵向列表展示控件的核心交互信号
     * @details 以下信号覆盖QListWidget最核心的交互场景(选中变更、点击、双击、鼠标悬浮),是列表与业务逻辑联动的核心桥梁;不同信号适配不同交互需求,可精准响应用户操作并获取关键交互信息(选中条目/行号/点击对象)。
     */

    // ============================== 核心信号详解 ==============================

    /**
     * @signal void QListWidget::currentItemChanged(QListWidgetItem* current, QListWidgetItem* old)
     * @brief 选中**不同**条目时触发的信号(选中同一条目不触发)
     * @details 核心选中变更信号,可同时获取"当前选中条目"和"上一个选中条目",便于对比处理选中状态的变更逻辑;触发场景包括用户点击不同条目、代码设置选中项、删除选中条目等。
     *
     * @参数说明:
     * @param current - 当前选中的条目指针(无选中时为nullptr,如取消选中);
     * @param old     - 上一个选中的条目指针(无之前选中项时为nullptr,如首次选中)。
     *
     * @使用示例:
     * // 绑定信号,打印选中条目变更记录
     * connect(ui->listWidget, &QListWidget::currentItemChanged, this, [=](QListWidgetItem* cur, QListWidgetItem* prev){
     *     QString prevText = prev ? prev->text() : "无"; // 判空避免崩溃
     *     QString curText = cur ? cur->text() : "无";
     *     qDebug() << "选中项变更:" << prevText << " → " << curText;
     * });
     *
     * 【关键注意事项】
     * 1. 判空强制:current/old可能为nullptr(首次选中/取消选中),必须先判空再操作;
     * 2. 触发规则:仅选中**不同**条目时触发(重复点击同一条目不触发);
     * 3. 信号联动:与currentRowChanged()同步触发,先触发此信号,再触发currentRowChanged();
     * 4. 代码触发:调用setCurrentItem/setCurrentRow也会触发此信号。
     */

    /**
     * @signal void QListWidget::currentRowChanged(int currentRow)
     * @brief 选中**不同**条目时触发的信号(行号版)
     * @details currentItemChanged()的简化版信号,仅返回当前选中条目的行号,无需处理条目指针判空,适配仅需行号的场景(如行号统计、索引关联)。
     *
     * @参数说明:
     * @param currentRow - 当前选中条目的行号(从0开始计数;无选中时为-1)。
     *
     * @使用示例:
     * // 绑定信号,更新UI显示选中行号
     * connect(ui->listWidget, &QListWidget::currentRowChanged, this, [=](int row){
     *     if (row == -1) {
     *         ui->label->setText("当前无选中项");
     *     } else {
     *         ui->label->setText(QString("当前选中第%1行").arg(row + 1)); // 行号+1适配用户习惯
     *     }
     * });
     *
     * 【关键注意事项】
     * 1. 行号规则:行号从0开始,用户视角需+1展示;无选中时参数为-1;
     * 2. 触发场景:所有导致选中项变更的操作均触发(点击/代码设置/删除选中项);
     * 3. 简洁性:仅需行号时优先使用此信号,无需处理条目指针。
     */

    /**
     * @signal void QListWidget::itemClicked(QListWidgetItem* item)
     * @brief **用户鼠标单击**列表条目时触发的信号(代码选中不触发)
     * @details 纯交互触发信号,仅响应用户单击操作,参数为被点击的条目指针(非nullptr),是"点击条目执行操作"的核心入口。
     *
     * @参数说明:
     * @param item - 被单击的条目指针(不会为nullptr,点击列表空白处不触发此信号)。
     *
     * @使用示例:
     * // 绑定信号,单击条目弹出详情提示
     * connect(ui->listWidget, &QListWidget::itemClicked, this, [=](QListWidgetItem* clickedItem){
     *     QMessageBox::information(this, "点击提示", "你点击了:" + clickedItem->text());
     * });
     *
     * 【关键注意事项】
     * 1. 触发条件:仅用户**单击**触发,代码调用setCurrentItem/setCurrentRow不触发;
     * 2. 参数有效性:item始终为有效条目指针(无需判空);
     * 3. 选中联动:单击条目会自动将其设为选中项,因此会先触发itemClicked(),再触发currentItemChanged/currentRowChanged;
     * 4. 空白区:点击列表空白处(无条目区域)不触发此信号。
     */

    /**
     * @signal void QListWidget::itemDoubleClicked(QListWidgetItem* item)
     * @brief **用户鼠标双击**列表条目时触发的信号(代码操作不触发)
     * @details 适配"双击条目执行核心操作"的场景(如打开文件、编辑条目),参数为被双击的条目指针(非nullptr)。
     *
     * @参数说明:
     * @param item - 被双击的条目指针(不会为nullptr,双击空白处不触发)。
     *
     * @使用示例:
     * // 绑定信号,双击条目编辑文本
     * connect(ui->listWidget, &QListWidget::itemDoubleClicked, this, [=](QListWidgetItem* doubleItem){
     *     QString newText = QInputDialog::getText(this, "编辑条目", "修改文本:",
     *                                             QLineEdit::Normal, doubleItem->text());
     *     if (!newText.isEmpty()) {
     *         doubleItem->setText(newText); // 修改双击条目的文本
     *     }
     * });
     *
     * 【关键注意事项】
     * 1. 触发顺序:双击会先触发itemClicked()(第一次单击),再触发此信号;
     * 2. 触发条件:仅用户**双击**触发,代码操作/单击均不触发;
     * 3. 交互场景:适合"编辑/打开/查看详情"等需要双击确认的操作。
     */

    /**
     * @signal void QListWidget::itemEntered(QListWidgetItem* item)
     * @brief **鼠标光标进入**列表条目区域时触发的信号(需开启鼠标跟踪)
     * @details 悬浮交互信号,用于实现"鼠标悬浮高亮/显示提示"等效果;默认关闭鼠标跟踪,需手动调用setMouseTracking(true)才会触发。
     *
     * @参数说明:
     * @param item - 鼠标进入的条目指针(不会为nullptr)。
     *
     * @使用示例:
     * // 第一步:开启鼠标跟踪
     * ui->listWidget->setMouseTracking(true);
     * // 第二步:绑定信号,悬浮时高亮条目背景
     * connect(ui->listWidget, &QListWidget::itemEntered, this, [=](QListWidgetItem* enterItem){
     *     enterItem->setBackground(Qt::lightGray); // 悬浮时设浅灰背景
     *     // 鼠标离开时恢复背景需结合鼠标事件实现
     * });
     *
     * 【关键注意事项】
     * 1. 前置条件:必须调用setMouseTracking(true),否则永不触发;
     * 2. 触发频率:鼠标在条目间移动时高频触发,避免在信号槽内执行耗时操作;
     * 3. 仅进不出:此信号仅响应"进入",鼠标离开条目需结合QMouseEvent手动处理;
     * 4. 参数有效性:item始终为有效条目指针(无需判空)。
     */

    lw=new QListWidget(this);

    ui->lw->setGeometry(100,100,300,300);

    //注意,严格注意,我们创建的QListWidgetItem对象,不能是栈上的对象,必须要用new出来的QListWidgetItem
    //否则代码结束后,这些局部对象会被自动销毁,QListWidget 里保存的指针就变成了无效地址,所以界面上看不到这些条目。
    QListWidgetItem* item1=new QListWidgetItem("1");
    ui->lw->addItem(item1);

    QListWidgetItem* item2=new QListWidgetItem("2");
    ui->lw->addItem(item2);

    QListWidgetItem* item3=new QListWidgetItem("3");
    ui->lw->addItem(item3);

    //我们也可以直接使用addItem方法,直接传入字符串,没有什么特殊要求的话,直接传入字符串还是最方便的
    ui->lw->addItem("4");

    ui->lw->setSpacing(5);

    ui->lw->setItemAlignment(Qt::AlignLeft);
}

Widget::~Widget()
{
    delete ui;
}


// 1. 当前选中项改变 (最常用)
void Widget::on_lw_currentItemChanged(QListWidgetItem *current, QListWidgetItem *previous)
{
    // 触发时机:当列表的"当前选中项"发生变化时触发。
    // 参数说明:
    //   current: 新选中的条目指针 (如果取消全选,则为 nullptr)
    //   previous: 原来选中的条目指针 (如果是首次选中,则为 nullptr)

    if (current) {
        qDebug() << "[Current Item Changed] 新选中:" << current->text();
        // 典型用法:根据选中的条目更新右侧详情面板、启用/禁用按钮
        // ui->btnDelete->setEnabled(true);
        // showDetails(current->data(Qt::UserRole));
    } else {
        qDebug() << "[Current Item Changed] 已取消选中";
        // ui->btnDelete->setEnabled(false);
    }
}

// 2. 当前选中行号改变
void Widget::on_lw_currentRowChanged(int currentRow)
{
    // 触发时机:当选中行的索引号发生变化时触发。
    // 参数说明:currentRow 是新选中的行号 (从0开始),若取消选中则为 -1。
    // 区别:这个信号比 currentItemChanged 更轻量,如果你只需要行号而不需要条目对象,用这个。

    qDebug() << "[Current Row Changed] 新行号:" << currentRow;

    // 典型用法:记录用户浏览到了第几项,或者用于分页逻辑
    // if (currentRow >= 0) {
    //     int totalCount = ui->lw->count();
    //     ui->labelStatus->setText(QString("第 %1 / %2 项").arg(currentRow + 1).arg(totalCount));
    // }
}

// 3. 条目被单击
void Widget::on_lw_itemClicked(QListWidgetItem *item)
{
    // 触发时机:用户鼠标左键单击某个条目时触发(即使该条目已经是当前选中项,再次点击也会触发)。
    // 注意:这与 currentItemChanged 不同,如果点击的是已经选中的项,currentItemChanged 不会触发,但 itemClicked 会触发。

    qDebug() << "[Item Clicked] 点击了:" << item->text();

    // 典型用法:
    // 1. 实现"点击已选中项取消选中"的逻辑。
    // 2. 播放轻微的点击音效。
    // 3. 在触摸屏设备上作为主要交互反馈。
}

// 4. 条目被双击
void Widget::on_lw_itemDoubleClicked(QListWidgetItem *item)
{
    // 触发时机:用户快速双击某个条目时触发。

    qDebug() << "[Item Double Clicked] 双击了:" << item->text();

    // 典型用法:
    // 1. 打开详情窗口 / 编辑对话框。
    // 2. 启动/运行选中的程序或文件。
    // 3. 进入下一级目录(如果是文件浏览器)。
    // QDialog dialog; dialog.exec();
}

// 5. 鼠标进入条目区域
void Widget::on_lw_itemEntered(QListWidgetItem *item)
{
    // 触发时机:鼠标光标移入某个条目的矩形区域时触发。
    // 前提:通常需要确保 viewport()->setMouseTracking(true) 或者直接依赖 Qt 默认行为(QListWidget 通常默认支持)。

    qDebug() << "[Item Entered] 鼠标悬停:" << item->text();

    // 典型用法:
    // 1. 显示 Tooltip 提示详细信息(如果文本被截断)。
    // 2. 高亮显示该行(自定义 hover 效果)。
    // 3. 动态加载预览图。
    // ui->lw->setToolTip(item->data(Qt::UserRole).toString());
}

// 6. 鼠标按下条目
void Widget::on_lw_itemPressed(QListWidgetItem *item)
{
    // 触发时机:鼠标按键在条目上按下(尚未释放)时触发。
    // 注意:此时还未产生"点击"或"选中"的最终结果,适合做拖拽开始的检测。

    qDebug() << "[Item Pressed] 按下了:" << item->text();

    // 典型用法:
    // 1. 自定义拖拽操作 (Drag & Drop) 的起始判断。
    // 2. 右键菜单的预处理(虽然通常用 customContextMenuRequested 信号更好)。
}

// 7. 选中状态改变 (多选模式专用)
void Widget::on_lw_itemSelectionChanged()
{
    // 触发时机:当列表中被选中的条目集合发生变化时触发。
    // 关键点:
    //   - 如果 SelectionMode 是 SingleSelection (单选),它 behaves 类似 currentItemChanged。
    //   - 如果 SelectionMode 是 MultiSelection / ExtendedSelection (多选),这个信号最重要!
    //     因为 currentItemChanged 只追踪"当前焦点项",而这个信号追踪"所有被勾选/高亮的项"。

    QList<QListWidgetItem*> selectedItems = ui->lw->selectedItems();
    qDebug() << "[Selection Changed] 当前共选中" << selectedItems.count() << "项";

    // 典型用法:
    // 1. 批量操作按钮的状态更新(如:选中多项时才启用"批量删除")。
    // 2. 统计选中的数量。
    // bool canBatchDelete = (selectedItems.count() > 1);
    // ui->btnBatchDelete->setEnabled(canBatchDelete);
}

// 8. 当前条目的文本改变
void Widget::on_lw_currentTextChanged(const QString &currentText)
{
    // 触发时机:当"当前选中项"的文本内容发生改变时触发。
    // 注意:这通常发生在条目处于"可编辑"(Editable) 状态,且用户修改完文本失去焦点或按下回车后。
    // 如果仅仅是切换了选中项,而新项的文本和旧项一样,可能不会触发(取决于具体实现,通常指内容变更)。
    // 修正:在 Qt 标准信号中,这个信号通常是指 **当前选中项变化导致显示的文本变化**,或者 **当前项被编辑后文本变化**。
    // 对于 QListWidget,最准确的理解是:当 currentItem 改变,且新旧 currentItem 的 text() 不同时,或者当前项被编辑完成时。
    // *注:实际上 QListWidget 的 currentTextChanged 信号主要是响应 currentItem 变化带来的文本变化,类似于 QComboBox。
    // 如果是编辑导致的文本变化,通常使用 itemChanged 信号。

    qDebug() << "[Current Text Changed] 当前显示文本变为:" << currentText;

    // 典型用法:
    // 1. 联动另一个只显示文本的标签。
    // 2. 根据文本内容过滤其他列表。
}

第七章 综合示例:新增、选中、删除条目

讲完了所有内容,我们最后来做一个综合示例,实现 "通过 QLineEdit 输入文本,点击按钮新增条目;选中条目,点击按钮删除条目;选中变更时打印日志" 的功能 ------ 这是 QListWidget 最经典的应用场景之一。

7.1 场景描述

界面上有:

  1. 一个 QListWidget(objectName 为 listWidget);
  2. 一个 QLineEdit(objectName 为 lineEdit),用于输入新条目文本;
  3. 一个 QPushButton(objectName 为 pushButton_add),用于新增条目;
  4. 一个 QPushButton(objectName 为 pushButton_delete),用于删除选中条目。

功能:

  • 点击 "新增" 按钮,将 LineEdit 中的文本添加到 ListWidget 末尾;
  • 点击 "删除" 按钮,删除 ListWidget 中当前选中的条目;
  • 选中变更时,打印日志;
  • LineEdit 为空时不新增。

7.2 代码实现

复制代码
#include "widget.h"
#include "ui_widget.h"
#include <QListWidgetItem>
#include <QDebug>

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    // 初始化:添加几个初始条目
    ui->listWidget->addItem("C++");
    ui->listWidget->addItem("Java");
    ui->listWidget->addItem("Python");

    // 设置条目间距,提升视觉舒适度
    ui->listWidget->setSpacing(5);

    // 绑定选中变更信号
    connect(ui->listWidget, &QListWidget::currentItemChanged,
            this, [=](QListWidgetItem* cur, QListWidgetItem* prev){
        QString prevText = prev ? prev->text() : "无";
        QString curText = cur ? cur->text() : "无";
        qDebug() << "选中项变更:" << prevText << " → " << curText;
    });
}

Widget::~Widget()
{
    delete ui;
}

// 新增按钮槽函数
void Widget::on_pushButton_add_clicked()
{
    // 获取 LineEdit 的文本
    const QString& text = ui->lineEdit->text();
    // 判空:为空则不新增
    if (text.isEmpty()) {
        return;
    }
    // 添加到 ListWidget 末尾
    ui->listWidget->addItem(text);
    // 清空 LineEdit
    ui->lineEdit->clear();
}

// 删除按钮槽函数
void Widget::on_pushButton_delete_clicked()
{
    // 获取当前选中行号
    int row = ui->listWidget->currentRow();
    // 判空:无选中则不删除
    if (row == -1) {
        return;
    }
    // 删除指定行的条目
    QListWidgetItem* deletedItem = ui->listWidget->takeItem(row);
    if (deletedItem != nullptr) {
        qDebug() << "删除条目:" << deletedItem->text();
        delete deletedItem; // 必须手动 delete!
        deletedItem = nullptr;
    }
}

完整示例代码:

cpp 复制代码
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);

    //OK,那么本文件我们就来正式的学习QListWidget的核心属性,其实也不多
    //也不难,大部分我们之前都有接触过·~~·

    /**
     * @class QListWidget
     * @brief Qt中用于展示纵向列表的可视化控件,基于项(QListWidgetItem)管理列表内容
     * @details QListWidget以行式布局展示多个条目(QListWidgetItem),支持条目选中、排序、换行、对齐方式定制、间距调整等功能;
     *          每个条目可独立配置文本/图标/样式,提供丰富的增删改查方法和交互信号,是Qt中最常用的列表展示控件之一。
     *
     * 【核心特征】
     * 1. 条目管理:支持添加、插入、删除、选中条目,可通过行号/条目对象精准操作;
     * 2. 视觉定制:支持条目对齐、间距、选中矩形显隐、换行等视觉配置;
     * 3. 交互反馈:提供选中变更、点击、双击、鼠标进入等核心交互信号;
     * 4. 功能扩展:支持列表排序、行数统计、当前选中项快速获取。
     */

    // ============================== 核心属性详解 ==============================

    /**
     * @property QListWidget::currentRow
     * @brief QListWidget当前被选中条目的行号属性
     * @details 该属性表征列表中当前激活选中的条目行号,默认值为-1(无选中条目);
     *          行号从0开始计数(第一行=0,第二行=1...),修改该属性会触发currentRowChanged()信号。
     *
     * 【关联API详解】
     * 1. int currentRow() const → 获取当前选中条目的行号(无选中返回-1);
     * 2. void setCurrentRow(int row) → 设置指定行号的条目为当前选中项(行号超出范围则取消选中)。
     *
     * @使用示例:
     * // 获取当前选中行号
     * int selectedRow = ui->listWidget->currentRow();
     * qDebug() << "当前选中行:" << selectedRow;
     *
     * // 设置选中第2行(索引1)
     * ui->listWidget->setCurrentRow(1);
     *
     * 【关键注意事项】
     * 1. 行号规则:行号从0开始,若列表为空或无选中项,返回-1;
     * 2. 联动currentItem:修改currentRow会同步更新currentItem,反之亦然;
     * 3. 范围约束:设置行号超出[0, count-1]时,会取消所有选中,currentRow变为-1。
     */

    /**
     * @property QListWidget::count
     * @brief QListWidget列表中条目总行数属性
     * @details 该属性只读,表征列表中当前包含的QListWidgetItem总数,默认值为0(空列表);
     *          增删条目时会自动更新,是统计列表条目数量的核心属性。
     *
     * 【关联API详解】
     * 1. int count() const → 获取列表条目总行数;
     * 2. bool isEmpty() const → 等价于count() == 0,快速判断列表是否为空。
     *
     * @使用示例:
     * // 统计列表总行数
     * int totalRows = ui->listWidget->count();
     * qDebug() << "列表总行数:" << totalRows;
     *
     * // 判断列表是否为空
     * if (ui->listWidget->isEmpty()) {
     *     qDebug() << "列表为空";
     * }
     *
     * 【关键注意事项】
     * 1. 只读属性:无法直接修改,仅通过addItem/insertItem/takeItem等方法间接变更;
     * 2. 实时更新:增删条目后立即生效,无需手动刷新;
     * 3. 行号关联:有效行号范围为[0, count()-1],超出该范围的行号操作无效。
     */

    /**
     * @property QListWidget::sortingEnabled
     * @brief QListWidget是否允许列表自动排序的属性
     * @details 该属性控制列表条目是否按文本内容自动排序,默认值为false(不排序);
     *          设为true时,列表会按条目文本的字母/数字顺序升序排列,新增/修改条目文本时会自动重新排序。
     *
     * 【关联API详解】
     * 1. bool isSortingEnabled() const → 判断是否开启自动排序;
     * 2. void setSortingEnabled(bool enable) → 设置是否开启自动排序;
     * 3. void sortItems(Qt::SortOrder order = Qt::AscendingOrder) → 手动触发排序(可指定升序/降序)。
     *
     * @使用示例:
     * // 开启自动排序(升序)
     * ui->listWidget->setSortingEnabled(true);
     *
     * // 手动触发降序排序(即使sortingEnabled=false也生效)
     * ui->listWidget->sortItems(Qt::DescendingOrder);
     *
     * 【关键注意事项】
     * 1. 排序规则:默认按文本Unicode编码升序排列,中文按拼音/Unicode排序;
     * 2. 行号变化:排序后条目行号会重新分配,原行号失效;
     * 3. 性能影响:大量条目(如1000+)开启自动排序会轻微影响增删效率,建议批量增删后再开启。
     */

    /**
     * @property QListWidget::isWrapping
     * @brief QListWidget是否允许条目换行显示的属性
     * @details 该属性控制列表条目是否在控件宽度不足时自动换行,默认值为false(不换行);
     *          设为true时,条目会从左到右排列,一行放不下则自动换行,形成多列布局(类似流式布局)。
     *
     * 【关联API详解】
     * 1. bool isWrapping() const → 判断是否允许换行;
     * 2. void setWrapping(bool wrap) → 设置是否允许换行。
     *
     * @使用示例:
     * // 开启换行,条目超出宽度自动换行
     * ui->listWidget->setWrapping(true);
     * ui->listWidget->setFixedWidth(200); // 固定列表宽度,触发换行效果
     *
     * 【关键注意事项】
     * 1. 布局影响:换行仅在列表为水平流式布局时生效,默认纵向列表需配合setViewMode(QListView::IconMode)使用;
     * 2. 视觉适配:换行后条目按"行-列"排列,count()仍统计总条目数,currentRow()按视觉行号计算;
     * 3. 间距配合:换行后可通过spacing属性调整条目间的水平/垂直间距。
     */

    /**
     * @property QListWidget::itemAlignment
     * @brief QListWidget列表条目整体的对齐方式属性
     * @details 该属性控制所有条目在列表控件内的整体对齐位置(水平+垂直),默认值为Qt::AlignLeft | Qt::AlignTop;
     *          区别于QListWidgetItem::setTextAlignment(单个条目内文本的对齐),该属性是条目整体在控件中的对齐。
     *
     * 【核心枚举值(Qt::Alignment)】
     * | 枚举值                | 功能说明                                                                 |
     * |-----------------------|--------------------------------------------------------------------------|
     * | Qt::AlignLeft         | 水平左对齐(默认);                                                     |
     * | Qt::AlignRight        | 水平右对齐;                                                             |
     * | Qt::AlignHCenter      | 水平居中;                                                               |
     * | Qt::AlignCenter       | 水平+垂直居中;                                                           |
     * | Qt::AlignTop          | 垂直顶部对齐(默认);                                                   |
     * | Qt::AlignBottom       | 垂直底部对齐;                                                           |
     * | Qt::AlignVCenter      | 垂直居中;                                                               |
     *
     * 【关联API详解】
     * 1. Qt::Alignment itemAlignment() const → 获取条目整体对齐方式;
     * 2. void setItemAlignment(Qt::Alignment alignment) → 设置条目整体对齐方式。
     *
     * @使用示例:
     * // 设置所有条目在列表中水平居中+垂直居中
     * ui->listWidget->setItemAlignment(Qt::AlignCenter);
     * ui->listWidget->setFixedSize(300, 200); // 固定控件尺寸,对齐效果更明显
     *
     * 【关键注意事项】
     * 1. 层级区别:itemAlignment(条目整体在控件中对齐)≠ setTextAlignment(文本在条目内对齐);
     * 2. 换行适配:开启wrapping时,对齐方式控制每一行条目整体的对齐;
     * 3. 尺寸影响:控件尺寸需大于条目总尺寸,才能体现明显的对齐效果。
     */

    /**
     * @property QListWidget::selectRectVisible
     * @brief QListWidget选中条目对应的矩形框是否可见的属性
     * @details 该属性控制选中条目周围是否显示高亮矩形框,默认值为true(可见);
     *          设为false时,选中条目仍会触发选中信号,但视觉上无矩形框高亮(可通过QSS自定义选中样式替代)。
     *
     * 【关联API详解】
     * 1. bool isSelectRectVisible() const → 判断选中矩形框是否可见;
     * 2. void setSelectRectVisible(bool visible) → 设置选中矩形框是否可见。
     *
     * @使用示例:
     * // 隐藏选中矩形框(仅通过文本颜色区分选中状态)
     * ui->listWidget->setSelectRectVisible(false);
     * // 自定义选中条目文本颜色
     * QListWidgetItem* item = ui->listWidget->item(0);
     * item->setForeground(Qt::red); // 选中时手动修改颜色
     *
     * 【关键注意事项】
     * 1. 仅视觉影响:隐藏矩形框不影响选中逻辑和信号触发;
     * 2. 样式覆盖:若通过QSS自定义了QListWidget::item:selected样式,该属性可能被覆盖;
     * 3. 交互兼容:即使隐藏矩形框,条目仍可被选中/点击,不影响交互功能。
     */

    /**
     * @property QListWidget::spacing
     * @brief QListWidget列表条目之间的间距属性(像素)
     * @details 该属性控制相邻条目之间的水平/垂直间距,默认值为0(无间距);
     *          开启wrapping(换行)时,同时控制水平和垂直间距;未开启时仅控制垂直间距。
     *
     * 【关联API详解】
     * 1. int spacing() const → 获取条目之间的间距(像素);
     * 2. void setSpacing(int space) → 设置条目间距(建议值≥0,负值自动修正为0)。
     *
     * @使用示例:
     * // 设置条目间距为10像素(垂直/水平均为10)
     * ui->listWidget->setSpacing(10);
     *
     * 【关键注意事项】
     * 1. 单位:间距单位为像素,数值越大条目间空隙越大;
     * 2. 换行适配:开启wrapping时,spacing同时控制行内条目水平间距和行之间的垂直间距;
     * 3. 布局影响:间距会增加列表整体尺寸,需结合控件大小适配。
     */

    // ============================== 核心方法详解 ==============================

    /**
     * @fn void QListWidget::addItem(const QString& label)
     * @fn void QListWidget::addItem(QListWidgetItem *item)
     * @brief QListWidget向列表末尾添加条目(两种重载形式)
     * @details 该方法是添加条目的基础方式,直接将条目追加到列表最后一行;
     *          重载1通过文本快速创建默认条目,重载2添加自定义配置的QListWidgetItem对象。
     *
     * @参数说明:
     * @param label - QString类型,重载1的参数,条目显示的文本内容;
     * @param item - QListWidgetItem*类型,重载2的参数,自定义配置的条目对象(需手动创建)。
     *
     * @使用示例:
     * // 重载1:快速添加文本条目
     * ui->listWidget->addItem("条目1");
     * ui->listWidget->addItem("条目2");
     *
     * // 重载2:添加自定义配置的条目
     * QListWidgetItem* customItem = new QListWidgetItem("自定义条目");
     * customItem->setIcon(QIcon(":/images/icon.png")); // 设置图标
     * customItem->setFont(QFont("微软雅黑", 12));      // 设置字体
     * ui->listWidget->addItem(customItem);
     *
     * 【关键注意事项】
     * 1. 内存管理:通过重载2添加的item,所有权移交至QListWidget,无需手动delete(删除条目用takeItem);
     * 2. 排序影响:若开启sortingEnabled=true,添加的条目会自动排序,不一定在末尾;
     * 3. 空值处理:label为空字符串时,条目仍会添加(显示为空行),item为nullptr时无任何操作。
     */

    /**
     * @fn QListWidgetItem* QListWidget::currentItem() const
     * @brief QListWidget获取当前选中条目的对象指针
     * @details 该方法返回当前激活选中的QListWidgetItem对象,无选中条目时返回nullptr;
     *          是通过条目对象操作选中项的核心方法(如修改选中项文本/图标)。
     *
     * @返回值说明:
     * @return QListWidgetItem* - 当前选中条目指针(无选中返回nullptr)。
     *
     * @使用示例:
     * // 获取当前选中条目并修改其文本
     * QListWidgetItem* selectedItem = ui->listWidget->currentItem();
     * if (selectedItem != nullptr) { // 判空避免空指针
     *     selectedItem->setText("已选中:" + selectedItem->text());
     * }
     *
     * 【关键注意事项】
     * 1. 判空必须:列表为空或无选中项时返回nullptr,直接操作会导致程序崩溃;
     * 2. 联动currentRow:currentItem()和currentRow()一一对应(item行号=currentRow());
     * 3. 只读指针:返回的是条目对象指针,可修改条目属性,但不可手动delete(需用takeItem)。
     */

    /**
     * @fn void QListWidget::setCurrentItem(QListWidgetItem* item)
     * @brief QListWidget设置指定条目为当前选中项
     * @details 该方法通过条目对象精准选中指定项,item为nullptr时取消所有选中;
     *          选中后会触发currentItemChanged()和currentRowChanged()信号。
     *
     * @参数说明:
     * @param item - QListWidgetItem*类型,要选中的条目对象(nullptr取消选中)。
     *
     * @使用示例:
     * // 创建条目并设置为选中项
     * QListWidgetItem* targetItem = new QListWidgetItem("目标条目");
     * ui->listWidget->addItem(targetItem);
     * ui->listWidget->setCurrentItem(targetItem); // 选中该条目
     *
     * 【关键注意事项】
     * 1. 有效性检查:item必须是当前列表中的条目(已通过addItem/insertItem添加),否则无效果;
     * 2. 信号触发:设置后会依次触发currentItemChanged()和currentRowChanged();
     * 3. 空值处理:item为nullptr时,currentRow()变为-1,取消所有选中。
     */

    /**
     * @fn void QListWidget::setCurrentRow(int row)
     * @brief QListWidget设置指定行号的条目为当前选中项
     * @details 该方法通过行号快速选中条目,是setCurrentItem()的行号版封装;
     *          行号超出[0, count()-1]范围时,取消所有选中(currentRow()=-1)。
     *
     * @参数说明:
     * @param row - int类型,要选中的条目行号(从0开始)。
     *
     * @使用示例:
     * // 选中第3行(索引2)的条目
     * ui->listWidget->setCurrentRow(2);
     *
     * 【关键注意事项】
     * 1. 行号规则:行号从0开始,count()为总行数,有效行号范围[0, count()-1];
     * 2. 等价操作:setCurrentRow(row) 等价于 setCurrentItem(item(row));
     * 3. 信号触发:设置有效行号时触发currentRowChanged()和currentItemChanged()。
     */

    /**
     * @fn void QListWidget::insertItem(int row, const QString& label)
     * @fn void QListWidget::insertItem(int row, QListWidgetItem *item)
     * @brief QListWidget在指定行号位置插入条目(两种重载形式)
     * @details 该方法区别于addItem(仅追加末尾),可在任意行号位置插入条目;
     *          行号超出范围时,自动追加到末尾(row>count())或插入到开头(row<0)。
     *
     * @参数说明:
     * @param row - int类型,插入位置的行号(从0开始);
     * @param label - QString类型,重载1的参数,条目显示文本;
     * @param item - QListWidgetItem*类型,重载2的参数,自定义条目对象。
     *
     * @使用示例:
     * // 重载1:在第1行(索引0)插入文本条目
     * ui->listWidget->insertItem(0, "插入到开头的条目");
     *
     * // 重载2:在第2行(索引1)插入自定义条目
     * QListWidgetItem* insertItem = new QListWidgetItem("插入条目");
     * insertItem->setIcon(QIcon(":/images/insert.png"));
     * ui->listWidget->insertItem(1, insertItem);
     *
     * 【关键注意事项】
     * 1. 行号容错:row<0 → 插入到开头;row>count() → 追加到末尾;
     * 2. 内存管理:重载2的item所有权移交至列表,无需手动delete;
     * 3. 行号偏移:插入位置后的条目行号自动+1(如在索引1插入,原索引1的条目变为索引2)。
     */

    /**
     * @fn QListWidgetItem* QListWidget::item(int row) const
     * @brief QListWidget通过行号获取对应条目对象指针
     * @details 该方法是"行号→条目"的核心映射方法,可精准获取指定行的条目进行属性修改;
     *          行号超出范围时返回nullptr。
     *
     * @参数说明:
     * @param row - int类型,要获取的条目行号(从0开始)。
     *
     * @返回值说明:
     * @return QListWidgetItem* - 指定行的条目指针(行号无效返回nullptr)。
     *
     * @使用示例:
     * // 获取第2行(索引1)的条目并修改图标
     * QListWidgetItem* targetItem = ui->listWidget->item(1);
     * if (targetItem != nullptr) {
     *     targetItem->setIcon(QIcon(":/images/target.png"));
     * }
     *
     * 【关键注意事项】
     * 1. 判空必须:行号无效时返回nullptr,直接操作会导致崩溃;
     * 2. 实时性:行号随增删/排序动态变化,需注意操作时机;
     * 3. 只读指针:可修改条目属性,但不可手动delete。
     */

    /**
     * @fn QListWidgetItem* QListWidget::takeItem(int row)
     * @brief QListWidget删除指定行号的条目,并返回该条目指针
     * @details 该方法是删除条目的核心方法,区别于直接delete(会导致内存泄漏/崩溃);
     *          删除后该行后续条目行号自动-1,count()减1。
     *
     * @参数说明:
     * @param row - int类型,要删除的条目行号(从0开始)。
     *
     * @返回值说明:
     * @return QListWidgetItem* - 被删除的条目指针(行号无效返回nullptr)。
     *
     * @使用示例:
     * // 删除第1行(索引0)的条目,并释放其内存
     * QListWidgetItem* deletedItem = ui->listWidget->takeItem(0);
     * if (deletedItem != nullptr) {
     *     delete deletedItem; // 必须手动释放内存,否则内存泄漏
     *     deletedItem = nullptr;
     * }
     *
     * 【关键注意事项】
     * 1. 内存管理:takeItem仅将条目从列表中移除,需手动delete返回的指针释放内存;
     * 2. 行号偏移:删除条目后,后续条目行号自动-1(如删除索引1,原索引2变为索引1);
     * 3. 选中状态:若删除的是当前选中条目,currentRow()变为-1,取消选中。
     */

    // ============================== 核心信号详解 ==============================

    /**
     * @signal void QListWidget::currentItemChanged(QListWidgetItem* current, QListWidgetItem* old)
     * @brief QListWidget选中条目变更时触发的信号
     * @details 该信号反馈选中条目的变更,触发场景包括:用户点击不同条目、代码调用setCurrentItem/setCurrentRow、删除选中条目;
     *          可同时获取当前选中条目和上一个选中条目,便于对比处理。
     *
     * @参数说明:
     * @param current - QListWidgetItem*,变更后的当前选中条目(无选中则为nullptr);
     * @param old - QListWidgetItem*,变更前的上一个选中条目(无则为nullptr)。
     *
     * @使用示例:
     * // 绑定信号,打印选中条目变更
     * connect(ui->listWidget, &QListWidget::currentItemChanged, this, [=](QListWidgetItem* cur, QListWidgetItem* prev){
     *     QString prevText = prev ? prev->text() : "无";
     *     QString curText = cur ? cur->text() : "无";
     *     qDebug() << "选中项变更:" << prevText << " → " << curText;
     * });
     *
     * 【关键注意事项】
     * 1. 判空处理:current/old可能为nullptr(如首次选中/取消选中),需先判空再操作;
     * 2. 触发时机:与currentRowChanged()同步触发,先触发currentItemChanged()再触发currentRowChanged();
     * 3. 无重复触发:选中同一条目时(如重复点击),不会触发该信号。
     */

    /**
     * @signal void QListWidget::currentRowChanged(int currentRow)
     * @brief QListWidget选中条目行号变更时触发的信号
     * @details 该信号是currentItemChanged()的行号版封装,仅反馈行号变更,更适合仅需行号的场景;
     *          参数为新的选中行号(无选中则为-1)。
     *
     * @参数说明:
     * @param currentRow - int类型,变更后的选中行号(无选中返回-1)。
     *
     * @使用示例:
     * // 绑定信号,更新标签显示选中行号
     * connect(ui->listWidget, &QListWidget::currentRowChanged, this, [=](int row){
     *     if (row == -1) {
     *         ui->labSelected->setText("无选中项");
     *     } else {
     *         ui->labSelected->setText(QString("选中第%1行").arg(row+1)); // 行号+1适配用户习惯
     *     }
     * });
     *
     * 【关键注意事项】
     * 1. 行号规则:参数为程序内部行号(从0开始),展示给用户时建议+1;
     * 2. 触发场景:所有导致选中项变更的操作都会触发,包括删除选中条目(row=-1);
     * 3. 简洁性:仅需行号时优先使用该信号,无需处理条目对象判空。
     */

    /**
     * @signal void QListWidget::itemClicked(QListWidgetItem* item)
     * @brief QListWidget点击任意条目时触发的信号
     * @details 该信号仅在用户鼠标点击条目时触发(代码选中不会触发),参数为被点击的条目指针;
     *          是响应"点击条目"交互的核心信号。
     *
     * @参数说明:
     * @param item - QListWidgetItem*,被点击的条目指针(不会为nullptr)。
     *
     * @使用示例:
     * // 绑定信号,点击条目时弹出文本提示
     * connect(ui->listWidget, &QListWidget::itemClicked, this, [=](QListWidgetItem* clickedItem){
     *     QMessageBox::information(this, "点击提示", "你点击了:" + clickedItem->text());
     * });
     *
     * 【关键注意事项】
     * 1. 触发条件:仅用户鼠标点击触发,代码调用setCurrentItem/setCurrentRow不会触发;
     * 2. 参数有效性:item始终为有效条目指针(点击空白处不会触发该信号);
     * 3. 与选中联动:点击条目会自动将其设为当前选中项,因此会先触发itemClicked(),再触发currentItemChanged()/currentRowChanged()。
     */

    /**
     * @signal void QListWidget::itemDoubleClicked(QListWidgetItem* item)
     * @brief QListWidget双击任意条目时触发的信号
     * @details 该信号仅在用户鼠标双击条目时触发,参数为被双击的条目指针;
     *          常用于"双击条目执行操作"场景(如打开文件、编辑条目)。
     *
     * @参数说明:
     * @param item - QListWidgetItem*,被双击的条目指针(不会为nullptr)。
     *
     * @使用示例:
     * // 绑定信号,双击条目时编辑文本
     * connect(ui->listWidget, &QListWidget::itemDoubleClicked, this, [=](QListWidgetItem* doubleClickedItem){
     *     QString newText = QInputDialog::getText(this, "编辑条目", "修改文本:",
     *                                             QLineEdit::Normal, doubleClickedItem->text());
     *     if (!newText.isEmpty()) {
     *         doubleClickedItem->setText(newText);
     *     }
     * });
     *
     * 【关键注意事项】
     * 1. 触发条件:仅用户双击触发,单击/代码选中不会触发;
     * 2. 与单击兼容:双击会先触发itemClicked()(第一次单击),再触发itemDoubleClicked();
     * 3. 交互场景:适合"查看详情/编辑/打开"等需要双击确认的操作。
     */

    /**
     * @signal void QListWidget::itemEntered(QListWidgetItem* item)
     * @brief QListWidget鼠标光标进入条目区域时触发的信号
     * @details 该信号仅在鼠标光标移入条目范围内时触发,需先开启鼠标跟踪(setMouseTracking(true));
     *          常用于"鼠标悬浮提示/高亮"场景。
     *
     * @参数说明:
     * @param item - QListWidgetItem*,鼠标进入的条目指针(不会为nullptr)。
     *
     * @使用示例:
     * // 开启鼠标跟踪,绑定itemEntered信号实现悬浮高亮
     * ui->listWidget->setMouseTracking(true);
     * connect(ui->listWidget, &QListWidget::itemEntered, this, [=](QListWidgetItem* enteredItem){
     *     enteredItem->setBackground(Qt::lightGray); // 悬浮时背景变浅灰
     *     // 离开时恢复(需结合鼠标离开事件)
     * });
     *
     * 【关键注意事项】
     * 1. 前置条件:必须调用setMouseTracking(true),否则不会触发;
     * 2. 触发频率:鼠标在条目间移动时会高频触发,需避免耗时操作;
     * 3. 离开处理:该信号仅处理进入,离开条目需结合QMouseEvent手动实现。
     */
}

Widget::~Widget()
{
    delete ui;
}

第八章 全文总结与学习建议

恭喜你!终于看完了这篇QListWidget 与 QListWidgetItem 详细解析!

如果你跟着文章一步步敲了代码,做了练习,那么现在你已经完全掌握了它们的核心内容:

  • 你知道了 QListWidget 是纵向列表控件,QListWidgetItem 是列表中的单个条目;
  • 你会用 QListWidgetItem 的 setText、setFont、setIcon、setHidden、setSizeHint、setSelected、setTextAlignment 定制条目;
  • 你会用 QListWidget 的 currentRow、count、itemAlignment、spacing、sortingEnabled、isWrapping 配置列表;
  • 你会用 addItem、insertItem、takeItem、item、currentItem 操作条目;
  • 你会绑定 currentItemChanged、itemClicked、itemDoubleClicked、itemEntered 等信号实现交互;
  • 你知道了QListWidgetItem 必须用 new 创建! takeItem 后必须手动 delete! currentItem 必须先判空! 行号从 0 开始! 这些超级重要的注意事项。

毫不夸张地说,掌握了这些内容,你就掌握了 QListWidget 开发的 95% 以上的需求!

8.1 核心要点回顾

在结束之前,我们最后再回顾一下这篇文章的核心要点,特别是那些最容易踩坑的地方:

  1. QListWidgetItem 必须用 new 创建!(超级重要!开篇就讲!):不能是栈对象!
  2. takeItem 后必须手动 delete!(超级重要!):否则内存泄漏!
  3. currentItem、currentItemChanged 的参数必须先判空!(超级重要!):否则程序崩溃!
  4. 行号从 0 开始!(超级重要!说三遍!):用户视角需 +1!
  5. itemEntered 必须先调用 setMouseTracking (true)!(超级重要!);
  6. sortingEnabled 开启后原行号失效!(超级重要!);
  7. itemClicked 仅用户单击触发,代码选中不触发!(超级重要!);
  8. QListWidget::itemAlignment 和 QListWidgetItem::setTextAlignment 是不同层级的对齐!(超级重要!);
  9. addItem 的自定义条目无需手动 delete,列表接管所有权!(超级重要!);
  10. count 是只读的,isEmpty () 更便捷!。

8.2 最后的话

编程学习没有捷径,唯手熟尔。QListWidget 和 QListWidgetItem 的内容虽然不少,但只要你多敲代码、多做练习、多踩坑、多排查,很快就能熟练掌握。

这篇文章虽然很长,但我相信,如果你认真看完了,跟着敲了代码,你一定会对它们有一个极其深刻的理解,再也不会为列表开发发愁。

感谢你阅读这篇文章,希望它能帮到你。我们下一篇 Qt 教程再见

相关推荐
坤坤子吖24 分钟前
Linux网络编程:自定义应用层协议与 JSON 序列化
linux·服务器·网络·c++·笔记·json
吴名氏.28 分钟前
Java转AI Agent教程(第十二周)检索与切分
java·开发语言·人工智能·ai·ai agent
瑞雪兆丰年兮1 小时前
JavaWeb-day10-SpringBootWeb案例
java·开发语言·javaweb·web
Elastic 中国社区官方博客1 小时前
更少的位数,相同的召回率:DiskBBQ 更保守的自动校准扫描
大数据·运维·开发语言·人工智能·elasticsearch·搜索引擎
三雷科技2 小时前
第6章第4节:自定义分词器
开发语言·c#
沫璃染墨2 小时前
从零入门计算机网络系列(十八):TCP连接管理详解——从三次握手与四次挥手到TIME_WAIT机制
运维·服务器·网络·c++·网络协议·tcp/ip·tcp
Adellle2 小时前
设计模式指南 (Java 版) ㊁
java·开发语言·设计模式
Delightrs3 小时前
Rust LeetCode238 算法题解
开发语言·算法·rust
云上工程笔记3 小时前
SRT字幕一键转手绘动画:srt-whiteboard-animation的复刻实录
大数据·开发语言·javascript·人工智能·机器学习