QLabel设置富文本,过长用省略号显示的方法

张开发
2026/4/14 23:01:13 15 分钟阅读

分享文章

QLabel设置富文本,过长用省略号显示的方法
目录1.背景2.QFontMetrics2.1.基本介绍2.2.核心方法2.3.使用注意3.解决方法3.1.简单方案固定汉字数量截断超过 N 字显示…3.2.推荐方案按 Label 宽度自动省略更美观1.背景QLabel 设置 ** 富文本HTML** 时原生的setElideMode会失效无法像纯文本那样自动显示省略号同时汉字是可变宽度不能单纯按固定字数判断更合理的是按「控件宽度」自动截断。2.QFontMetricsQFontMetrics是 Qt 中计算字体渲染实际尺寸的核心类用来精准获取文本 / 字符在屏幕上的像素宽度、高度、行间距、省略文本等解决「文本过长显示省略号」「文本居中 / 对齐」「自适应布局」等 UI 文本问题。它基于具体字体 字号 屏幕 DPI计算不是按字符数估算结果是实际渲染像素值这也是它比「固定字数截断」更精准的原因。2.1.基本介绍1.作用计算指定字体下单个字符 / 整段文本的宽度、高度文本行高、基线、间距文本超出宽度时自动生成带省略号的文本文本占据的矩形区域2.构造方式// 1. 从指定字体构造 QFont font(Microsoft YaHei, 12); QFontMetrics fm(font); // 2. 直接用控件的字体最常用 QFontMetrics fm(ui-label-font()); // 3. 高分屏/浮点精度推荐高DPI屏幕使用 QFontMetricsF fmf(ui-label-font());3.QFontMetrics vs QFontMetricsFQFontMetrics整数像素普通屏幕够用QFontMetricsF浮点精度高分屏2K/4K/Retina必须用避免尺寸偏差2.2.核心方法1.文本宽度计算最常用int width(const QString text) const计算文本渲染后的实际像素宽度自动区分汉字、英文、符号宽度不同。QString text 你好Qt123; int w fm.width(text); // 得到该文本实际占多少像素QRect boundingRect(const QString text) const返回文本渲染后占据的矩形区域x/y/ 宽 / 高。QRect rect fm.boundingRect(测试文本); int textWidth rect.width(); int textHeight rect.height();2.自动省略超长文本QString elidedText( const QString text, Qt::TextElideMode mode, int width, int flags 0 ) const自动截断文本并添加省略号是 QLabel 省略显示的核心方法。参数说明text原始文本mode省略位置Qt::ElideRight末尾省略最常用如「文本太长…」Qt::ElideLeft开头省略… 本太长Qt::ElideMiddle中间省略文… 长Qt::ElideNone不省略width允许的最大像素宽度flags文本标志默认 0 即可单行文本使用示例QString rawText 这是一段非常非常长的需要显示省略号的文本; // 最大宽度200px末尾加省略号 QString elided fm.elidedText(rawText, Qt::ElideRight, 200); ui-label-setText(elided);3.字体行高 / 高度相关①int height() const字体总高度字符最高点到最低点。②int lineSpacing() const推荐行高换行后两行文本的间距。③int ascent() const基线到字符顶部的距离。④int descent() const基线到字符底部的距离如 g、y 的下延部分。int h fm.height(); // 字体总高度 int spacing fm.lineSpacing(); // 行间距4.字符基础尺寸int minWidth()字体中最窄字符宽度int maxWidth()字体中最宽字符宽度int charWidth(QChar ch)单个字符的宽度2.3.使用注意1.宽度≠字符数汉字≈2 个英文字符宽度不同字体 / 字号宽度不同绝对不能用字符数代替像素宽度。2.控件宽度要留边距计算时用label-width() - 间距否则会紧贴边框。int maxW ui-label-width() - 4; // 左右各留2px边距3.富文本必须先转纯文本HTML 标签不占渲染宽度需先去除标签再计算QString plain richText.remove(QRegularExpression([^]));4.控件大小变化时重算窗口拉伸后 label 宽度改变需在resizeEvent中重新计算省略文本。3.解决方法3.1.简单方案固定汉字数量截断超过 N 字显示…适合你明确要限制多少个汉字的场景直接判断长度后拼接省略号再套富文本。#include QLabel #include QString // 示例超过20个汉字就截断省略号 QString richText span stylecolor:red; font-size:14px;这里是很长的富文本内容.../span; // 提取纯文本长度去掉HTML标签 QString plainText richText.remove(QRegularExpression([^])); const int maxLen 20; if (plainText.length() maxLen) { // 截断后加省略号 QString showText plainText.left(maxLen) ...; // 重新包装成富文本 ui-label-setText(QString(span stylecolor:red; font-size:14px;%1/span).arg(showText)); } else { ui-label-setText(richText); }3.2.推荐方案按 Label 宽度自动省略更美观#include QFontMetrics #include QRegularExpression // 通用设置带省略号的富文本 void setElidedLabel(QLabel *label, const QString richText) { if(!label) return; // 1. 关闭换行 label-setWordWrap(false); // 2. 提取纯文本 QString plain richText.remove(QRegularExpression([^])); // 3. 计算最大宽度减去边距 QFontMetrics fm(label-font()); int maxWidth label-width() - 4; // 4. 生成省略文本 QString elided fm.elidedText(plain, Qt::ElideRight, maxWidth); // 5. 重新套回富文本样式 label-setText(QString(span stylecolor:#333;%1/span).arg(elided)); } // 窗口/控件resize时调用适配宽度变化 void Widget::resizeEvent(QResizeEvent *event) { QWidget::resizeEvent(event); setElidedLabel(ui-label, b超长富文本内容测试/b); }关键说明1.原生不支持原因Qt::ElideRight只对纯文本生效一旦用setTextFormat(Qt::RichText)或传入 HTML省略号自动失效。2.单行显示前提记得关闭换行label-setWordWrap(false); label-setAlignment(Qt::AlignLeft | Qt::AlignVCenter);

更多文章