如何在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); }
二、在主程序中使用
- 创建
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
相关产品推荐
相关产品推荐

