Qt软件开发文档15---聊天窗口的实现(2),QTextEdit+QPainter实现聊天框自适应大小

绘制基础思路:

内部为一个textEdit框,外部Qpainter跟随textEdit框的大小绘制出”气泡”。 
聊天框绘制效果如下: 
这里写图片描述

计算textEdit的高度:

已知textEdit的宽度m_msgW,可以利用QTextDocument计算出textEdit的高度。代码如下:

void HiBubble::getTextHeight()
{
    QTextDocument *document = m_tedMsg->document();
    //document->setTextWidth(m_tedMsg->width());
    document->setTextWidth(m_msgW);
    //setting line height
    QTextCursor textCursor = m_tedMsg->textCursor();
    QTextBlockFormat textBlockFormat;

    QFont ft;
    ft.setPixelSize(14);
    ft.setFamily("Microsoft YaHei UI");
    m_tedMsg->setFont(ft);
    if (document){
        if (m_tedMsg)
        {
            int newHeight = document->size().height();
            int h = newHeight > msgRoleH ? newHeight : (msgRoleH-4);
            if (newHeight > msgRoleH) {
                textBlockFormat.setLineHeight(22, QTextBlockFormat::FixedHeight);//设置固定行高
                isSingleHeight = false;
            } else {
                textBlockFormat.setLineHeight(26, QTextBlockFormat::FixedHeight);//设置固定行高
                isSingleHeight = true;
            }
            textCursor.setBlockFormat(textBlockFormat);
            m_tedMsg->setTextCursor(textCursor);
            m_tedMsg->setFixedHeight(h);
            h += 55;
            m_wgtMsg->setFixedWidth(m_tedMsg->width() + msgOffset);
            if (h != height()) {
                m_itemH = h;
                emit sigBubleHeightChange(m_index, m_itemH);
            }
        }
    }
}
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

QTextBlockFormat::setLineHeight(qreal height, int heightType) 用于设置textEdit的行高。 
接下来根据textEdit区域利用QPainter绘制出”气泡”效果。

绘制气泡:

void HiBubble::paintEvent(QPaintEvent *event)
{
    QPainter painter(this);
    painter.begin(this);
    painter.fillRect(rect(), Qt::white);
    painter.setRenderHint(QPainter::Antialiasing);
    painter.setPen(QPen(bgSceneToolBox, 0, Qt::SolidLine, Qt::RoundCap, Qt::RoundJoin));
    QRect msgRect;

    QPoint tl = m_tedMsg->mapTo(this, m_tedMsg->rect().topLeft());
    QPoint br = m_tedMsg->mapTo(this, m_tedMsg->rect().bottomRight());

    msgRect.setTopLeft(tl);
    msgRect.setBottomRight(br);
    if (true == isSingleHeight) {
        msgRect.adjust(-4, 0, 4, 4);
    } else {
        msgRect.adjust(-4, 2, 4, 4);
    }
    QPainterPath lPath;
    // calc the path
    //QVector<QLine> bPath;
    QPoint p0, p1, p2, p3, p4, p5, p6;
    p0 = msgRect.topLeft();
    p1 = msgRect.topRight();
    p2 = msgRect.bottomRight();
    p3 = msgRect.bottomLeft();
    lPath.moveTo(p0);
    if (true) {
        /*
        p0--------------------------------p1
        |                                 |
        |                                 |
        p6                                |
       /                                  |
     p5                                   |
       \                                  |
        p4                                |
        |                                 |
        |                                 |
        p3--------------------------------p2
        */
        p6 = QPoint(p0.x(), p0.y() + 12);
        p5 = QPoint(p0.x() - 7, p0.y() + 18);
        p4 = QPoint(p0.x(), p0.y() + 25);
        lPath.lineTo(p1);
        lPath.lineTo(p2);
        lPath.lineTo(p3);
        lPath.lineTo(p4);
        lPath.lineTo(p5);
        lPath.lineTo(p6);
        lPath.lineTo(p0);
        painter.drawPath(lPath);
        msgRect.adjust(0, 0, -1, -1);
        //painter.fillRect(msgRect, Qt::white);
        painter.fillPath(lPath, Qt::white);
        painter.end();
    }

猜你喜欢

转载自blog.csdn.net/u014746838/article/details/79328709