You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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界面示例

替代方案(无需自定义委托)

如果不想使用自定义委托,也可以通过信号监听实现自动更新:

  • 给QListWidget绑定rowsInserted、rowsRemoved、rowsMoved、modelReset等条目变更信号
  • 信号触发时遍历所有条目,统一给条目文本加上行号前缀

缺点是会修改条目原生存储的文本,需要获取原始内容时要额外裁剪行号,性能也略低于委托方案。

内容的提问来源于stack exchange,提问作者Chris P

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.30 03:36:01