03 从QLabel聊起:自定义控件扩展-文本控件

系列文章目录

01 Qt自定义风格控件的基本原则-CSDN博客

02 从QLabel聊起:自定义控件扩展-图片控件-CSDN博客


目录

系列文章目录

前言

一、QLabel文本展示接口的弊端

二、自定义Text组件使用场景

三、实现思路

1.概述

单行文本的场景:

多行文本的场景:

2.功能接口举例

3. 文本渲染示例

 单行文本渲染:

多行文本渲染:

总结


前言

在上一篇《02 从QLabel聊起:自定义控件扩展-图片控件-CSDN博客》中已经提到,QLabel控件不仅仅杂糅了图片展示功能与文本展示功能, 而且在真正的业务使用场景中又极其鸡肋!

在上一篇中,我们针对QLabel的图片展示功能,独立封装了Image组件类,本篇幅想和大家分享下个人在拆解并扩展QLabel的文本展示功能,封装自定义文本组件Text!

既聊思路,也说代码!开始今天的Text功能控件的分享!

一、QLabel文本展示接口的弊端

不得不说, QLabel的组件真的是Qt业务开发中很基础的控件类,在展示标题时、文本时、属性名称时等等场景!然而, 用的多了你就会发现,QLabel的文本展示功能真的不好用!不方便之处如下:

  1. 在长文本换行场景下,多行文本无法设置行间距
  2. 长文本单行、多行展示场景下,无法设置文本省略模式(即:文本太长时,显示...)

也正是以上两个不便利之处,促使我想封装一个弥补上面两个缺陷的自定义Text组件

二、自定义Text组件使用场景

使用场景很简单而普遍,任何你需要单行或单行展示文字信息的地方,都可以复用!

如标题文本、列表的列名等等!Demo示意图如下

03 从QLabel聊起:自定义控件扩展-文本控件_第1张图片 图2-1

三、实现思路

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扩展组件类,后面会封装成插件动态库,感兴趣的同学可以留言哦!

你可能感兴趣的:(Qt-GUI:自定义组件的思路,qt)