绘制基础思路:
内部为一个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();
}