如何在QListWidget条目文本左侧自动添加从1开始的行号
QListWidget自动添加行号实现方案
推荐使用自定义委托方案,无需手动维护行号,条目增删、重排、筛选后行号会自动刷新,也不会修改原有条目存储的文本内容,是目前最优的实现方式。
实现原理
继承QStyledItemDelegate自定义条目绘制委托,绘制条目时自动通过index.row()获取当前条目的索引值,行号即为索引+1,将行号绘制在条目左侧,原有文本区域向右偏移预留出行号宽度即可。
C++ Qt 代码示例
自定义委托类
#include <QStyledItemDelegate> #include <QPainter> class LineNumberDelegate : public QStyledItemDelegate { Q_OBJECT public: explicit LineNumberDelegate(QObject *parent = nullptr) : QStyledItemDelegate(parent) {} void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override { painter->save(); // 计算并绘制行号 int lineNumber = index.row() + 1; QString lineNumStr = QString::number(lineNumber); // 行号区域宽度,可根据最大行数调整,如最大999行设为30即可 const int lineNumWidth = 30; QRect lineNumRect = option.rect.adjusted(2, 0, -option.rect.width() + lineNumWidth, 0); painter->drawText(lineNumRect, Qt::AlignLeft | Qt::AlignVCenter, lineNumStr); // 偏移原有文本绘制区域,避开左侧行号 QStyleOptionViewItem opt = option; opt.rect.adjust(lineNumWidth + 5, 0, 0, 0); QStyledItemDelegate::paint(painter, opt, index); painter->restore(); } QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override { // 原有尺寸增加行号区域宽度,保证内容显示完整 QSize originSize = QStyledItemDelegate::sizeHint(option, index); originSize.rwidth() += 35; return originSize; } };
调用方式
给你的QListWidget实例设置该委托即可生效:
// 假设你的QListWidget对象名为ui->listWidget ui->listWidget->setItemDelegate(new LineNumberDelegate(ui->listWidget));
PyQt/PySide 代码示例
from PyQt5.QtWidgets import QStyledItemDelegate from PyQt5.QtGui import QPainter from PyQt5.QtCore import Qt, QSize class LineNumberDelegate(QStyledItemDelegate): def paint(self, painter: QPainter, option, index): painter.save() # 绘制行号 line_num = index.row() + 1 line_num_width = 30 line_num_rect = option.rect.adjusted(2, 0, -option.rect.width() + line_num_width, 0) painter.drawText(line_num_rect, Qt.AlignLeft | Qt.AlignVCenter, str(line_num)) # 偏移原文本绘制区域 option.rect.adjust(line_num_width + 5, 0, 0, 0) super().paint(painter, option, index) painter.restore() def sizeHint(self, option, index) -> QSize: origin_size = super().sizeHint(option, index) origin_size.setWidth(origin_size.width() + 35) return origin_size
调用方式
# 假设你的QListWidget对象名为list_widget list_widget.setItemDelegate(LineNumberDelegate(list_widget))
注意事项
- 如果条目最大行数超过999,可自行调大
lineNumWidth的数值,避免行号显示不全 - 该方案不影响原有条目的文本读写逻辑,调用
item.text()返回的还是你原本设置的内容,不会包含行号 - 支持条目拖拽排序、过滤筛选、动态增删等场景,行号无需手动处理会自动同步
你当前使用的QListWidget界面参考:
替代方案(无需自定义委托)
如果不想使用自定义委托,也可以通过信号监听实现自动更新:
- 给QListWidget绑定
rowsInserted、rowsRemoved、rowsMoved、modelReset等条目变更信号 - 信号触发时遍历所有条目,统一给条目文本加上行号前缀
缺点是会修改条目原生存储的文本,需要获取原始内容时要额外裁剪行号,性能也略低于委托方案。
内容的提问来源于stack exchange,提问作者Chris P
相关产品推荐
相关产品推荐

