聊天气泡的绘制(圆角矩形+三角形+黑色边框,关键学会QPainter的draw函数就行了),注意每个QLabel都有自己的独立坐标

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了聊天气泡的绘制(圆角矩形+三角形+黑色边框,关键学会QPainter的draw函数就行了),注意每个QLabel都有自己的独立坐标相关的知识,希望对你有一定的参考价值。

头文件:

#ifndef GLABEL_H
#define GLABEL_H

#include <QLabel>
#include <QPainter>
#include <QPaintEvent>
#include <QMouseEvent>

class GLabel : public QLabel
{
    Q_OBJECT
public:
    enum PEOPLE{She,Me};
    Q_PROPERTY(QString str_context READ getStrContext WRITE setContext)
    explicit GLabel(QWidget *parent = 0,GLabel::PEOPLE f=GLabel::She);
    void setContext(const QString s){str_context = s;}
    QString getStrContext()const{return str_context;}

    QString str_context;
    QLabel *label_text;
    QLabel *label_people;
    PEOPLE people;
public:
    int m_width;
    int m_height;
    int parent_maxwidth;

    void init();
    void initUI(GLabel::PEOPLE f);
    void setSize(QString&);
    void setOurText(QString);
    void setHeadpic(QString);
    void  paintEvent(QPaintEvent *e);
    void mousePressEvent(QMouseEvent *e);
//signals:

//public slots:

};

#endif // GLABEL_H

.cpp文件:

#include "glabel.h"
#include <QPen>
#include <QDebug>

GLabel::GLabel(QWidget *parent,GLabel::PEOPLE f) :
    QLabel(parent)
{
      people = f;
      parent_maxwidth = ((QWidget*)this->parent())->width();
      init();
}

void GLabel::init()
{
    label_text  = new QLabel(this);
    label_text->setWordWrap(true);
    label_text->setGeometry(20+30,20,this->width()-40-30,this->height()-40);
    label_text->setStyleSheet("QLabel{background:rgb(173,216,67)}");//rgb(173,216,67)
    label_text->show();

    label_people = new QLabel(this);
    if(people == GLabel::She)
    {
        label_people->setGeometry(0,18,30,30);
        label_text->setStyleSheet("QLabel{background:rgb(173,216,67)}");
        label_people->setPixmap(QPixmap(":/image/she.png"));
    }
    else
    {
       label_people->setGeometry(this->width()-30,18,30,30);
       label_text->setStyleSheet("QLabel{background:rgb(240,240,240)}");
       label_people->setPixmap(QPixmap(":/image/he.png"));
    }
}

void GLabel::initUI(GLabel::PEOPLE f)
{

}

void GLabel::setSize(QString &paramstr)
{
//    int all_word_width  = this->fontMetrics().width(paramstr);
//    int one_line_height = this->fontMetrics().lineSpacing();
    int max_width = parent_maxwidth-50;//-label_people->width();
    int all_word_width;

    label_text->setWordWrap(false);
    label_text->setText(paramstr);
    label_text->adjustSize();
    all_word_width = label_text->width();
    label_text->setWordWrap(true);

    float line_count;
    int line;

    if(all_word_width > max_width)
    {
//        line_count = (float)all_word_width/max_width;
//        line = (int)line_count;
//        if(line < line_count)line=line+2;
        label_text->setMaximumWidth(max_width-20-30);
        label_text->setText(paramstr);
        label_text->adjustSize();
        qDebug()<<"the size of text"<<label_text->size()<<((QWidget*)this->parent())->width()-15;

        m_height = label_text->height()/*line*one_line_height*/;
        m_width  = parent_maxwidth-15;
       // qDebug()<<"linr_count"<<line_count<<one_line_height<<max_width<<all_word_width;
        this->resize(m_width,m_height+40);
    }
    else
    {
        label_text->setWordWrap(false);
        m_height = 66;

        label_text->setText(paramstr);
        label_text->adjustSize();
        m_width = label_text->width()+40+30;
        //label_text->setMinimumWidth(all_word_width);
        this->resize(m_width+10,m_height);
    }

    if(people == GLabel::She)
        label_text->setGeometry(20+40,20,this->width()-40-30,this->height()-40);
    else
        label_text->setGeometry(20,20,this->width()-40-30,this->height()-40);

    update();
}

void GLabel::setOurText(QString paramstr)
{
    setSize(paramstr);
    qDebug()<<"setSize"<<this->width()<<this->height();
    //label_text->setWordWrap(true);
   // label_text->setText(paramstr);
}

void GLabel::mousePressEvent(QMouseEvent *e)
{
    qDebug()<<"this pos is"<<e->pos();
}

void GLabel::setHeadpic(QString dir)
{
    label_people->setPixmap(QPixmap(dir));
}

void GLabel::paintEvent(QPaintEvent *e)
{
    //QPainter painter(this);
    if(people == GLabel::She)
    {
        QRectF rectangle(50.0, 10.0, this->width()-20-40, this->height()-20);

        QPainter painter(this);
        painter.setRenderHint( QPainter::Antialiasing, true );
        painter.setBrush(QBrush(QColor(173,216,67)));
        painter.drawRoundedRect(rectangle,10,10);

        QPointF points[3] = {
           QPointF(40, 33),
           QPointF(51, 28),
           QPointF(51, 38),
       };

       QPen pen;
       pen.setColor(QColor(173,216,67));
       painter.setPen(pen);
       painter.drawPolygon(points, 3);

       QPen pen1;
       pen.setColor(Qt::black);
       painter.setPen(pen1);
       painter.drawLine(points[0],points[1]);
       painter.drawLine(points[0],points[2]);
    }
    else if(people == GLabel::Me)
    {
        QRectF rectangle(10.0, 10.0, this->width()-20-40, this->height()-20);

        QPainter painter(this);
        painter.setRenderHint( QPainter::Antialiasing, true );
        painter.setBrush(QBrush(QColor(240,240,240)));
        painter.drawRoundedRect(rectangle,10,10);

        QPointF points[3] = {
           QPointF(this->width()-40, 33),
           QPointF(this->width()-51, 28),
           QPointF(this->width()-51,38),
       };

       QPen pen;
       pen.setColor(QColor(240,240,240));
       painter.setPen(pen);
       painter.drawPolygon(points, 3);

       QPen pen1;
       pen.setColor(Qt::black);
       painter.setPen(pen1);
       painter.drawLine(points[0],points[1]);
       painter.drawLine(points[0],points[2]);

      // label_text->setGeometry(20,20,this->width()-40-30,this->height()-40);
       label_people->setGeometry(this->width()-30,18,30,30);
       this->setGeometry(((QWidget*)this->parent())->width()-15-this->width(),this->y(),this->width(),this->height());
    }
   // qDebug()<<"this size of pix"<<label_people->size();
   // drawShe();
}

实际调用:

#include "dialog.h"
#include "ui_dialog.h"
#include <QDebug>

Dialog::Dialog(QWidget *parent) :
    QDialog(parent),
    ui(new Ui::Dialog)
{
    ui->setupUi(this);

    label[0] = new GLabel(this,GLabel::Me);
    label[0]->setGeometry(05,10,100,66);
    label[0]->setOurText(tr("你好!"));
    label[0]->show();

    label[1] = new GLabel(this,GLabel::She);
    label[1]->setGeometry(5,label[0]->y()+label[0]->height(),100,66);
    label[1]->setOurText(tr("你好!"));
    label[1]->show();

    label[2] = new GLabel(this,GLabel::Me);
    label[2]->setGeometry(5,label[1]->y()+label[1]->height(),100,66);
    label[2]->setOurText(tr("我们好像在哪里见过?"));
    label[2]->show();

    label[3] = new GLabel(this,GLabel::She);
    label[3]->setGeometry(5,label[2]->y()+label[2]->height(),100,66);
    label[3]->setOurText(tr(""));
    label[3]->show();

    label[4] = new GLabel(this,GLabel::Me);
    label[4]->setGeometry(5,label[3]->y()+label[3]->height(),100,66);
    label[4]->setOurText(tr("我们好像在哪见过你记得吗?好像那是一个秋天夕阳西下,你美得让我不敢和你说话,你经过我时风起浮动我的发"));
    label[4]->show();

    label[5] = new GLabel(this,GLabel::She);
    label[5]->setGeometry(5,label[4]->y()+label[4]->height(),100,66);
    label[5]->setOurText(tr("银杏还是会黄的,雪也会再次染白整个世界。安好"));
    label[5]->show();
}

Dialog::~Dialog()
{
    delete ui;
}

下载:http://download.csdn.net/download/yangkping123/8620775

以上是关于聊天气泡的绘制(圆角矩形+三角形+黑色边框,关键学会QPainter的draw函数就行了),注意每个QLabel都有自己的独立坐标的主要内容,如果未能解决你的问题,请参考以下文章

如何在 Javascript 中制作可拉伸的聊天气泡?

绘制没有底部边框的圆角矩形边框

如何绘制圆角窗口的边框?

MFC怎么绘制一个圆角矩形

html5中canvas通过js绘制圆角矩形

html5中canvas通过js绘制圆角矩形