系列文章目录
02 从QLabel聊起:自定义控件扩展-图片控件-CSDN博客
目录
前言
在上一篇《02 从QLabel聊起:自定义控件扩展-图片控件-CSDN博客》中已经提到,QLabel控件不仅仅杂糅了图片展示功能与文本展示功能, 而且在真正的业务使用场景中又极其鸡肋!
在上一篇中,我们针对QLabel的图片展示功能,独立封装了Image组件类,本篇幅想和大家分享下个人在拆解并扩展QLabel的文本展示功能,封装自定义文本组件Text!
既聊思路,也说代码!开始今天的Text功能控件的分享!
一、QLabel文本展示接口的弊端
不得不说, QLabel的组件真的是Qt业务开发中很基础的控件类,在展示标题时、文本时、属性名称时等等场景!然而, 用的多了你就会发现,QLabel的文本展示功能真的不好用!不方便之处如下:
- 在长文本换行场景下,多行文本无法设置行间距
- 长文本单行、多行展示场景下,无法设置文本省略模式(即:文本太长时,显示...)
也正是以上两个不便利之处,促使我想封装一个弥补上面两个缺陷的自定义Text组件
二、自定义Text组件使用场景
使用场景很简单而普遍,任何你需要单行或单行展示文字信息的地方,都可以复用!
如标题文本、列表的列名等等!Demo示意图如下
三、实现思路
1.概述
继承QWidget类, 在paintEvent中实时绘制文本内容。
单行文本的场景:
直接使用QPainter::drawText接口即可!
多行文本的场景:
该场景相对复杂些,要使用一个相对冷门的文本布局类:
- QTextLayout
- QTextLine
- QTextOption
在paintEvent中综合使用QTextLayout、QTextOption类来实现多行文本的绘制以及各种文本效果,包括:居中、换行等等特殊文本效果!
2.功能接口举例
概述
Text扩展类在原QLabel文本接口的基础上,扩展了如下功能:
- 设置行间距
- 设置长文本Elide模式
- 设置文本颜色
代码示例
//文本
void setText(const QString& text);
QString text()const { return m_textCfg.strContentText; }
//文本省略模式
void setTextElideMode(Qt::TextElideMode elideMode);
Qt::TextElideMode elideMode()const {return m_textCfg.eEdlideMode;}
//设置最大展示行数
void setMaxLineCount(int lineCnt);
int maxLineCount()const {return m_textCfg.iMaxLineCount;}
//文本风格
void setTextColor(const QColor& textClr);
QColor textColor()const { return m_textCfg.clrText; }
//设置文本四周边距
void setTextPaddings(const QMargins& margin);
QMargins textPaddings()const { return m_textCfg.textPaddings; }
//对齐方式
void setAlignment(Qt::Alignment align);
Qt::Alignment alignment()const { return m_textCfg.textAlignment; }
//行间距
void setLineSpacing(int lineSpaceing);
int lineSpacing()const { return m_textCfg.iLineSpacing; }
//当前是否是文本省略状态
bool isElidedText()const {return m_bIsElidedState;}
//设置wrap模式
void setWordWrap(bool on);
3. 文本渲染示例
单行文本渲染:
QFontMetrics fontMetrics(this->font());
QRect rcSingleLine = rect().marginsRemoved(m_textCfg.textPaddings);
QString elidedText = fontMetrics.elidedText(m_textCfg.strContentText
, m_textCfg.eEdlideMode
, rcSingleLine.width());
painter->drawText(rcSingleLine, m_textCfg.textAlignment, elidedText);
多行文本渲染:
for (;;)
{
QTextLine line = textLayout.createLine();
if (!line.isValid())
break;
line.setLineWidth(contextWidth);
int lineBottomY = startY + lineHeight+ m_textCfg.textPaddings.bottom();
if (height() >= lineBottomY && curLineNo < m_textCfg.iMaxLineCount-1)//高度足够展示该行文本,且没有超过最大行数
{
line.draw(painter, QPoint(startX, startY));
startY = lineBottomY + m_textCfg.iLineSpacing;//加上一个行间距
curLineNo++;
}
else//下一行高度已经不够显示时余下内容或者已经达到最后一行时,把余下所有文本展示在最后一行中
{
QString lastLine = m_textCfg.strContentText.mid(line.textStart());
QString elidedLastLine = fontMetrics.elidedText(lastLine, m_textCfg.eEdlideMode, contextWidth);
QRect rcLastLine = QRect(startX, startY, contextWidth, lineHeight);
painter->drawText(rcLastLine, m_textCfg.textAlignment, elidedLastLine);
break;
}
}
总结
以上就是今天要讲的内容,本篇主要针对QLabel文本功能接口进行功能仿写与扩展,然后独立出一个自定义的组件功能类Text。
既聊思路,也说代码!我们下次继续分享自定义风格扩展组件!
PS:本专栏涉及的UI扩展组件类,后面会封装成插件动态库,感兴趣的同学可以留言哦!