qt 气泡聊天界面_微信聊天气泡框素材
1、简介
由于最近的项目需要,做了些相关IM的工作。所以聊天框也是必不可少的一部分。聊天框的制作分很多种,本文以QListWidget+QPainter绘制的Item做了一个Demo。该Demo只是做一个示例,代码已公布如下,需要的拿去!
2、效果图
3、实现原理
气泡式聊天的显示是由QListWidget作为控件,每个气泡是由QListWidgetItem提升成QWidget来实现的。每个气泡可以理解位是一个QWidget,这样可以自由布置QWidget里面的内容。每个Item保存聊天的对话、发送状态、时间、种类等。
这个QWidget主要是显示一个头像+气泡,气泡里面是聊天的内容等。 气泡是在paintEvent事件中,采用QPainter来绘制的。
4、核心代码
4.1、头文件
#ifndef QNCHATMESSAGE_H
#define QNCHATMESSAGE_H#include <QWidget>class QPaintEvent;
class QPainter;
class QLabel;
class QMovie;class QNChatMessage : public QWidget
{ Q_OBJECT
public:explicit QNChatMessage(QWidget *parent = nullptr);enum User_Type{ User_System,//系统User_Me, //自己User_She, //用户User_Time, //时间};void setTextSuccess();void setText(QString text, QString time, QSize allSize, User_Type userType);QSize getRealString(QString src);QSize fontRect(QString str);inline QString text() { return m_msg;}inline QString time() { return m_time;}inline User_Type userType() { return m_userType;}
protected:void paintEvent(QPaintEvent *event);
private:QString m_msg;QString m_time;QString m_curTime;QSize m_allSize;User_Type m_userType = User_System;int m_kuangWidth;int m_textWidth;int m_spaceWid;int m_lineHeight;QRect m_iconLeftRect;QRect m_iconRightRect;QRect m_sanjiaoLeftRect;QRect m_sanjiaoRightRect;QRect m_kuangLeftRect;QRect m_kuangRightRect;QRect m_textLeftRect;QRect m_textRightRect;QPixmap m_leftPixmap;QPixmap m_rightPixmap;QLabel* m_loading = Q_NULLPTR;QMovie* m_loadingMovie = Q_NULLPTR;bool m_isSending = false;
};#endif // QNCHATMESSAGE_H
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
4.2、源文件
#include "qnchatmessage.h"
#include <QFontMetrics>
#include <QPaintEvent>
#include <QDateTime>
#include <QPainter>
#include <QMovie>
#include <QLabel>
#include <QDebug>QNChatMessage::QNChatMessage(QWidget *parent) : QWidget(parent)
{ QFont te_font = this->font();te_font.setFamily("MicrosoftYaHei");te_font.setPointSize(12);
// te_font.setWordSpacing(0);
// te_font.setLetterSpacing(QFont::PercentageSpacing,0);
// te_font.setLetterSpacing(QFont::PercentageSpacing, 100); //300%,100为默认 //设置字间距%
// te_font.setLetterSpacing(QFont::AbsoluteSpacing, 0); //设置字间距为3像素 //设置字间距像素值this->setFont(te_font);m_leftPixmap = QPixmap(":/img/Customer Copy.png");m_rightPixmap = QPixmap(":/img/CustomerService.png");m_loadingMovie = new QMovie(this);m_loadingMovie->setFileName(":/img/loading4.gif");m_loading = new QLabel(this);m_loading->setMovie(m_loadingMovie);m_loading->resize(16,16);m_loading->setAttribute(Qt::WA_TranslucentBackground , true);m_loading->setAutoFillBackground(false);
}void QNChatMessage::setTextSuccess()
{ m_loading->hide();m_loadingMovie->stop();m_isSending = true;
}void QNChatMessage::setText(QString text, QString time, QSize allSize, QNChatMessage::User_Type userType)
{ m_msg = text;m_userType = userType;m_time = time;m_curTime = QDateTime::fromTime_t(time.toInt()).toString("hh:mm");m_allSize = allSize;if(userType == User_Me) { if(!m_isSending) { m_loading->move(m_kuangRightRect.x() - m_loading->width() - 10, m_kuangRightRect.y()+m_kuangRightRect.height()/2- m_loading->height()/2);m_loading->show();m_loadingMovie->start();}} else { m_loading->hide();}this->update();
}QSize QNChatMessage::fontRect(QString str)
{ m_msg = str;int minHei = 30;int iconWH = 40;int iconSpaceW = 20;int iconRectW = 5;int iconTMPH = 10;int sanJiaoW = 6;int kuangTMP = 20;int textSpaceRect = 12;m_kuangWidth = this->width() - kuangTMP - 2*(iconWH+iconSpaceW+iconRectW);m_textWidth = m_kuangWidth - 2*textSpaceRect;m_spaceWid = this->width() - m_textWidth;m_iconLeftRect = QRect(iconSpaceW, iconTMPH, iconWH, iconWH);m_iconRightRect = QRect(this->width() - iconSpaceW - iconWH, iconTMPH, iconWH, iconWH);QSize size = getRealString(m_msg); // 整个的sizeqDebug() << "fontRect Size:" << size;int hei = size.height() < minHei ? minHei : size.height();m_sanjiaoLeftRect = QRect(iconWH+iconSpaceW+iconRectW, m_lineHeight/2, sanJiaoW, hei - m_lineHeight);m_sanjiaoRightRect = QRect(this->width() - iconRectW - iconWH - iconSpaceW - sanJiaoW, m_lineHeight/2, sanJiaoW, hei - m_lineHeight);if(size.width() < (m_textWidth+m_spaceWid)) { m_kuangLeftRect.setRect(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), m_lineHeight/4*3, size.width()-m_spaceWid+2*textSpaceRect, hei-m_lineHeight);m_kuangRightRect.setRect(this->width() - size.width() + m_spaceWid - 2*textSpaceRect - iconWH - iconSpaceW - iconRectW - sanJiaoW,m_lineHeight/4*3, size.width()-m_spaceWid+2*textSpaceRect, hei-m_lineHeight);} else { m_kuangLeftRect.setRect(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), m_lineHeight/4*3, m_kuangWidth, hei-m_lineHeight);m_kuangRightRect.setRect(iconWH + kuangTMP + iconSpaceW + iconRectW - sanJiaoW, m_lineHeight/4*3, m_kuangWidth, hei-m_lineHeight);}m_textLeftRect.setRect(m_kuangLeftRect.x()+textSpaceRect,m_kuangLeftRect.y()+iconTMPH,m_kuangLeftRect.width()-2*textSpaceRect,m_kuangLeftRect.height()-2*iconTMPH);m_textRightRect.setRect(m_kuangRightRect.x()+textSpaceRect,m_kuangRightRect.y()+iconTMPH,m_kuangRightRect.width()-2*textSpaceRect,m_kuangRightRect.height()-2*iconTMPH);return QSize(size.width(), hei);
}QSize QNChatMessage::getRealString(QString src)
{ QFontMetricsF fm(this->font());m_lineHeight = fm.lineSpacing();int nCount = src.count("\n");int nMaxWidth = 0;if(nCount == 0) { nMaxWidth = fm.width(src);QString value = src;if(nMaxWidth > m_textWidth) { nMaxWidth = m_textWidth;int size = m_textWidth / fm.width(" ");int num = fm.width(value) / m_textWidth;int ttmp = num*fm.width(" ");num = ( fm.width(value) ) / m_textWidth;nCount += num;QString temp = "";for(int i = 0; i < num; i++) { temp += value.mid(i*size, (i+1)*size) + "\n";}src.replace(value, temp);}} else { for(int i = 0; i < (nCount + 1); i++) { QString value = src.split("\n").at(i);nMaxWidth = fm.width(value) > nMaxWidth ? fm.width(value) : nMaxWidth;if(fm.width(value) > m_textWidth) { nMaxWidth = m_textWidth;int size = m_textWidth / fm.width(" ");int num = fm.width(value) / m_textWidth;num = ((i+num)*fm.width(" ") + fm.width(value)) / m_textWidth;nCount += num;QString temp = "";for(int i = 0; i < num; i++) { temp += value.mid(i*size, (i+1)*size) + "\n";}src.replace(value, temp);}}}return QSize(nMaxWidth+m_spaceWid, (nCount + 1) * m_lineHeight+2*m_lineHeight);
}void QNChatMessage::paintEvent(QPaintEvent *event)
{ Q_UNUSED(event);QPainter painter(this);painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);//消锯齿painter.setPen(Qt::NoPen);painter.setBrush(QBrush(Qt::gray));if(m_userType == User_Type::User_She) { // 用户//头像
// painter.drawRoundedRect(m_iconLeftRect,m_iconLeftRect.width(),m_iconLeftRect.height());painter.drawPixmap(m_iconLeftRect, m_leftPixmap);//框加边QColor col_KuangB(234, 234, 234);painter.setBrush(QBrush(col_KuangB));painter.drawRoundedRect(m_kuangLeftRect.x()-1,m_kuangLeftRect.y()-1,m_kuangLeftRect.width()+2,m_kuangLeftRect.height()+2,4,4);//框QColor col_Kuang(255,255,255);painter.setBrush(QBrush(col_Kuang));painter.drawRoundedRect(m_kuangLeftRect,4,4);//三角QPointF points[3] = { QPointF(m_sanjiaoLeftRect.x(), 30),QPointF(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), 25),QPointF(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), 35),};QPen pen;pen.setColor(col_Kuang);painter.setPen(pen);painter.drawPolygon(points, 3);//三角加边QPen penSanJiaoBian;penSanJiaoBian.setColor(col_KuangB);painter.setPen(penSanJiaoBian);painter.drawLine(QPointF(m_sanjiaoLeftRect.x() - 1, 30), QPointF(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), 24));painter.drawLine(QPointF(m_sanjiaoLeftRect.x() - 1, 30), QPointF(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), 36));//内容QPen penText;penText.setColor(QColor(51,51,51));painter.setPen(penText);QTextOption option(Qt::AlignLeft | Qt::AlignVCenter);option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);painter.setFont(this->font());painter.drawText(m_textLeftRect, m_msg,option);} else if(m_userType == User_Type::User_Me) { // 自己//头像
// painter.drawRoundedRect(m_iconRightRect,m_iconRightRect.width(),m_iconRightRect.height());painter.drawPixmap(m_iconRightRect, m_rightPixmap);//框QColor col_Kuang(75,164,242);painter.setBrush(QBrush(col_Kuang));painter.drawRoundedRect(m_kuangRightRect,4,4);//三角QPointF points[3] = { QPointF(m_sanjiaoRightRect.x()+m_sanjiaoRightRect.width(), 30),QPointF(m_sanjiaoRightRect.x(), 25),QPointF(m_sanjiaoRightRect.x(), 35),};QPen pen;pen.setColor(col_Kuang);painter.setPen(pen);painter.drawPolygon(points, 3);//内容QPen penText;penText.setColor(Qt::white);painter.setPen(penText);QTextOption option(Qt::AlignLeft | Qt::AlignVCenter);option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);painter.setFont(this->font());painter.drawText(m_textRightRect,m_msg,option);} else if(m_userType == User_Type::User_Time) { // 时间QPen penText;penText.setColor(QColor(153,153,153));painter.setPen(penText);QTextOption option(Qt::AlignCenter);option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);QFont te_font = this->font();te_font.setFamily("MicrosoftYaHei");te_font.setPointSize(10);painter.setFont(te_font);painter.drawText(this->rect(),m_curTime,option);}
}
本文福利,莬费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块,面试题等等)↓↓↓↓↓↓见下面↓↓文章底部点击莬费领取↓↓
qt 气泡聊天界面_微信聊天气泡框素材相关推荐
- 微信气泡主题设置_微信猫和老鼠主题怎么弄?猫和老鼠聊天气泡主题设置教程...
阅读本文前,请您先点击上面的"科技阿",再点击"关注",这样您就可以继续免费收到文章了.每天都会有分享,都是免费订阅,请您放心关注. 注:本文转载自网络,如有 ...
- 微信气泡主题设置_微信皮肤主题怎么弄 微信设置更换修改气泡和主题教程
对于微信的皮肤主题是可以根据每个人不同的爱好进行设置的,最近呢就上架了一款超级受欢迎的猫和老鼠气泡主题,如果您想要进行更换修改要怎么弄呢,下面小编会带来详细的微信设置更换修改气泡和主题教程. 微信设置 ...
- 微信气泡主题设置_微信气泡主题华为手机要怎么弄 华为手机微信气泡主题设置方法介绍...
4.下载完成后,打开MT管理器,在左侧找到我们下载的气泡主题所在文件夹,点击进入显示[.mm]文件,然后在右侧找到华为手机主题的文件夹[HUAWEI-Themes],然后随便选择一个主题进入(注意不能 ...
- 微信气泡主题设置_微信猫和老鼠主题皮肤怎么设置 华为手机设置气泡主题方法...
微信猫和老鼠气泡主题应该如何设置?趣味主题带来的乐趣超级多,想要了解主题设置的方法,下面会提供详细的操作流程,让大家都能了解猫和老鼠气泡主题的设置技巧,轻松拥有好看又好玩的主题. 华为手机设置微信猫和 ...
- #解决仿微信聊天界面键盘遮盖聊天的界面
解决仿微信聊天界面键盘遮盖聊天的界面 注意聊天界面的activity一定不能处于全屏模式 //第一步设置属性 <!--模拟的布局文件--><?xml version="1. ...
- h5聊天页面 jquery_HTML5仿微信聊天界面、微信朋友圈实例代码
这几天使用H5开发了一个仿微信聊天前端界面,尤其微信底部编辑器那块处理的很好,使用HTML5来开发,虽说功能效果并没有微信那么全,但是也相当不错了,可以发送消息.表情,发送的消息自动回滚定位到底部,另 ...
- IM即时通信多房间聊天室仿微信聊天(二)
IM即时通信多房间聊天室仿微信聊天(服务器自定义处理客户端消息) 在IM即时通信多房间聊天室仿微信聊天(一)中我们已经搭建了基本的通信架构,接下来重点就是如何在自己的后台接收并处理客户端用户的消息了 ...
- IM即时通信多房间聊天室仿微信聊天(四)
聊天记录的保存和展示 IM即时通信多房间聊天室仿微信聊天(一) IM即时通信多房间聊天室仿微信聊天(二) IM即时通信多房间聊天室仿微信聊天(三) 聊天消息的保存我们直接在服务端接收到客户端发送的消息 ...
- 微信视频气泡 android,变变微信聊天气泡
变变微信聊天气泡是一款非常好用的气泡美化软件,让你的聊天框看起来更加个性化,不需要ROOT即可完成气泡设计,更具趣味性,喜欢的小伙们快来下载试试吧! 软件详情 让气泡在你的指尖跳跃吧! 变变聊天气泡( ...
最新文章
- IDEA 连接MySQL数据库
- Spring MVC配置
- sqlalchemy Specified key was too long; max key length is 767 bytes的解决办法
- NOIP2018初赛提高组复习提纲(By HGOI LJC)
- RAID原理及其使用方法
- nginx中js修改不生效的问题
- 解决prometheus k8s.gcr.io/addon-resizer:1.8.4镜像无法下载的问题
- ITK:将蒙版的反面应用于图像
- C运算符解析及优先级
- socket api中send()和recv()函数工作原理与要点
- ThreadLocal原理、ThreadLocal内存泄漏
- 思科CCNP培训日记全接触
- kali教程--破解wifi密码
- 升级到IE11,IE11调试F12 空白没法调试
- dpt rp1 android apk,DPT-RP1 新固件
- mybatis insert返回自增主键的id值
- Java 初中级程序员如何快速成长?
- 专访Barefoot:被Intel收购后的五倍爆发力
- 【人脸识别6】用haar+adaboost训练自己的人脸检测器
- 2017年中国程序员调查分析:大数据就业前景广阔