前言
本文实现 QTableView 富文本显示,同样适用于QTreeView、QListView 等 Q*View 控件。
相比参考博客增加了文本居中、多行显示优化等。
代码实现
RichTextDelegate 类声明(部分实现省略):
class RichTextDelegate : public QStyledItemDelegate
{
}
RichTextDelegate 类实现(部分实现省略):
void RichTextDelegate::paint(QPainter* painter,
const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
// 第一列富文本
if (0 == index.column())
{
QStyleOptionViewItem opt(option);
initStyleOption(&opt, index);
// 清空文本
opt.text = "";
QStyle* pStyle = opt.widget ? opt.widget->style() : QApplication::style();
pStyle->drawControl(QStyle::CE_ItemViewItem, &opt, painter, opt.widget);
// 文本可用显示区域
QRect textRect = pStyle->subElementRect(QStyle::SE_ItemViewItemText, &opt);
painter->save();
// 设置 html 文本
QString html = index.data(Qt::UserRole + 1).toString();
QTextDocument doc;
// html 文本居中显示
QTextOption textOpt = doc.defaultTextOption();
textOpt.setAlignment(Qt::AlignCenter);
doc.setDefaultTextOption(textOpt);
doc.setTextWidth(textRect.width());
doc.setHtml(html);
// 坐标转换,painter 从原点开始绘制,将文本区域左上角转化为原点
// 经验证,doc.size().height() 可能会比 textRect.height() 大
// 所以根据文本区域大小和 QTextDocument 区域大小手动算原点位置
int orignX = textRect.left() + (textRect.width() - doc.size().width()) / 2;
int orignY = textRect.top() + (textRect.height() - doc.size().height()) / 2;
painter->translate(orignX, orignY);
// 设置 html 绘制区域
QRect htmlRect(0, 0, doc.size().width(), doc.size().height());
painter->setClipRect(htmlRect);
QAbstractTextDocumentLayout::PaintContext paintContext;
doc.documentLayout()->draw(painter, paintContext);
painter->restore();
}
else
{
QStyledItemDelegate::paint(painter, option, index);
}
}
QSize RichTextDelegate::sizeHint(const QStyleOptionViewItem& option,
const QModelIndex& index) const
{
QSize size = QStyledItemDelegate::sizeHint(option, index);
// 自定义端面命名表格最小行高为 32px
size.setHeight(qMax(size.height(), 32));
return size;
}
QTableView 类实现(部分实现省略):
// 设置默认行高 32px、自适应高度、文本换行
this->verticalHeader()->setDefaultSectionSize(32);
this->verticalHeader()->setSectionResizeMode(QHeaderView::ResizeToContents);
this->setWordWrap(true);
// 设置代理 RichTextDelegate
RichTextDelegate * pDelegate = new RichTextDelegate (this);
this->setItemDelegate(pDelegate );
// QTableView 添加数据
QStandardItem* pItem = new QStandardItem();
pItem->setData(text, Qt::DisplayRole);
pItem->setData(html, Qt::UserRole + 1);
pItem->setTextAlignment(Qt::AlignCenter);
m_pDataModel->setItem(row, column, pItem);
HTML 代码
<html>
<head>
<style>
.NormalText
{
font-family: "Microsoft YaHei UI";
font-size: 14px;
color: #F5F9FC;
}
.HighlightText
{
font-family: "Microsoft YaHei UI";
font-size: 14px;
color: #14CDBA;
}
</style>
</head>
<body>
<font class = "NormalText">NormalText</font>
<font class = "HighlightText">HighlightText</font>
</body>
</html>