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

如何在PyQt5的QListView中为列表项添加富文本(QItemDelegate实现?)

QListView 富文本列表项实现方案

要实现带表情、格式、颜色的富文本列表项,用QStyledItemDelegate(比QItemDelegate更适配现代Qt样式)自定义绘制是最直接的方式,核心思路是利用QTextDocument解析HTML格式内容并渲染到列表项中。

一、自定义富文本Delegate

创建一个继承自QStyledItemDelegate的类,重写paint()和sizeHint()方法:

头文件(RichTextDelegate.h)

#ifndef RICHTEXTDELEGATE_H
#define RICHTEXTDELEGATE_H

#include <QStyledItemDelegate>
#include <QTextDocument>

class RichTextDelegate : public QStyledItemDelegate
{
    Q_OBJECT
public:
    explicit RichTextDelegate(QObject *parent = nullptr);

    void paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const override;
    QSize sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const override;

private:
    mutable QTextDocument m_doc; // 用于解析HTML,mutable允许在const方法中修改
};

#endif // RICHTEXTDELEGATE_H

实现文件(RichTextDelegate.cpp)

#include "RichTextDelegate.h"
#include <QPainter>
#include <QStyle>

RichTextDelegate::RichTextDelegate(QObject *parent)
    : QStyledItemDelegate(parent)
{
}

void RichTextDelegate::paint(QPainter *painter, const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QStyleOptionViewItem opt = option;
    initStyleOption(&opt, index);

    // 处理选中状态的背景
    if (opt.state & QStyle::State_Selected) {
        painter->fillRect(opt.rect, opt.palette.highlight());
    }

    // 获取HTML格式的文本
    QString htmlText = index.data(Qt::DisplayRole).toString();
    m_doc.setHtml(htmlText);

    // 调整绘制区域,留出边距
    QRect textRect = opt.rect.adjusted(4, 4, -4, -4);

    // 保存画家状态,避免影响其他绘制
    painter->save();

    // 平移坐标系,因为QTextDocument绘制从(0,0)开始
    painter->translate(textRect.topLeft());
    m_doc.setTextWidth(textRect.width());
    m_doc.drawContents(painter);

    painter->restore();
}

QSize RichTextDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const
{
    QString htmlText = index.data(Qt::DisplayRole).toString();
    m_doc.setHtml(htmlText);
    m_doc.setTextWidth(option.rect.width() - 8); // 减去左右边距

    // 返回计算后的尺寸,加上上下边距
    return QSize(option.rect.width(), m_doc.size().height() + 8);
}

二、在主程序中使用

  1. 创建QListView和QStandardItemModel,添加带HTML格式的列表项:
#include <QApplication>
#include <QListView>
#include <QStandardItemModel>
#include "RichTextDelegate.h"

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QListView listView;
    QStandardItemModel model;

    // 添加富文本项,支持表情、斜体、粗体、颜色
    model.appendRow(new QStandardItem(u8"🤒  Mr Smith <span style=\"color:#666\"><i>sick</i></span>"));
    model.appendRow(new QStandardItem(u8"  Mrs Smith <span style=\"color:#2ecc71\"><b>working</b></span>"));
    model.appendRow(new QStandardItem(u8"🌐  Mr Anderson <span style=\"color:#3498db\"><b>traveling</b></span>"));
    model.appendRow(new QStandardItem(u8"  Ms White <span style=\"color:#2ecc71\"><b>working</b></span>"));

    // 设置自定义Delegate
    RichTextDelegate *delegate = new RichTextDelegate(&listView);
    listView.setItemDelegate(delegate);
    listView.setModel(&model);

    listView.show();

    return a.exec();
}

三、关键说明

  • HTML支持:QTextDocument支持大部分基础HTML标签,比如<b>、<i>、<span style="color:...">,系统支持的emoji也能正常显示。
  • 样式适配:如果需要更复杂的选中/悬停样式,可以在paint()方法中根据option.state的状态(如State_MouseOver)调整绘制逻辑。
  • 行高自适应:sizeHint()方法通过QTextDocument计算内容高度,确保每行高度适配文本内容。

内容的提问来源于stack exchange,提问作者Joonas Joensuu

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.28 06:27:35