当前位置:   article > 正文

qt 气泡聊天界面_微信聊天气泡框素材_qt聊天界面

qt聊天界面

1、简介

由于最近的项目需要,做了些相关IM的工作。所以聊天框也是必不可少的一部分。聊天框的制作分很多种,本文以QListWidget+QPainter绘制的Item做了一个Demo。该Demo只是做一个示例,代码已公布如下,需要的拿去!

2、效果图

3、实现原理

气泡式聊天的显示是由QListWidget作为控件,每个气泡是由QListWidgetItem提升成QWidget来实现的。每个气泡可以理解位是一个QWidget,这样可以自由布置QWidget里面的内容。每个Item保存聊天的对话、发送状态、时间、种类等。

这个QWidget主要是显示一个头像+气泡,气泡里面是聊天的内容等。 气泡是在paintEvent事件中,采用QPainter来绘制的。

4、核心代码

学习Qt开发不知道做什么?UP主为大家整理的这些领域都涉及到Qt开发:嵌入式领域、桌面端开发、移动端、微控制器MCU、客户端(游戏、直播等等)、汽车领域行业、 消费类电子设备、医疗领域行业、工业自动化领域等等

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件QT6,C++语言基础,qt基础编程,qt软件开发,Qt架构设计,qt布局管理器,qt嵌入式开发,qt编程入门,qt数据库编程,qt跨平台框架,QT项目实战,Quick模块,OpenCV,Qt实战,OpenCV教程,QT界面开发,Qt框架,C++数据结构,Qt线程,桌面应用开发,qt桌面应用开发,Socket网络编程,qt开发工程师,qt开发,应用程序开发框架,图形视图框架,数据库编程,Qt开发编程,Qt开发控件,Qt开发工程师,QT开发必备技能栈,qt编码,qt网络编程,qt网络通信,Qt信号,Qt槽机制,qt字符串,qt数据类型,qt容器,qt客户端开发,qt软件工程师,qt页面绘制

4.1、头文件

  1. #ifndef QNCHATMESSAGE_H
  2. #define QNCHATMESSAGE_H
  3. #include <QWidget>
  4. class QPaintEvent;
  5. class QPainter;
  6. class QLabel;
  7. class QMovie;
  8. class QNChatMessage : public QWidget
  9. {
  10. Q_OBJECT
  11. public:
  12. explicit QNChatMessage(QWidget *parent = nullptr);
  13. enum User_Type{
  14. User_System,//系统
  15. User_Me, //自己
  16. User_She, //用户
  17. User_Time, //时间
  18. };
  19. void setTextSuccess();
  20. void setText(QString text, QString time, QSize allSize, User_Type userType);
  21. QSize getRealString(QString src);
  22. QSize fontRect(QString str);
  23. inline QString text() {
  24. return m_msg;}
  25. inline QString time() {
  26. return m_time;}
  27. inline User_Type userType() {
  28. return m_userType;}
  29. protected:
  30. void paintEvent(QPaintEvent *event);
  31. private:
  32. QString m_msg;
  33. QString m_time;
  34. QString m_curTime;
  35. QSize m_allSize;
  36. User_Type m_userType = User_System;
  37. int m_kuangWidth;
  38. int m_textWidth;
  39. int m_spaceWid;
  40. int m_lineHeight;
  41. QRect m_iconLeftRect;
  42. QRect m_iconRightRect;
  43. QRect m_sanjiaoLeftRect;
  44. QRect m_sanjiaoRightRect;
  45. QRect m_kuangLeftRect;
  46. QRect m_kuangRightRect;
  47. QRect m_textLeftRect;
  48. QRect m_textRightRect;
  49. QPixmap m_leftPixmap;
  50. QPixmap m_rightPixmap;
  51. QLabel* m_loading = Q_NULLPTR;
  52. QMovie* m_loadingMovie = Q_NULLPTR;
  53. bool m_isSending = false;
  54. };
  55. #endif // QNCHATMESSAGE_H

学习Qt开发不知道做什么?UP主为大家整理的这些领域都涉及到Qt开发:嵌入式领域、桌面端开发、移动端、微控制器MCU、客户端(游戏、直播等等)、汽车领域行业、 消费类电子设备、医疗领域行业、工业自动化领域等等

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件QT6,C++语言基础,qt基础编程,qt软件开发,Qt架构设计,qt布局管理器,qt嵌入式开发,qt编程入门,qt数据库编程,qt跨平台框架,QT项目实战,Quick模块,OpenCV,Qt实战,OpenCV教程,QT界面开发,Qt框架,C++数据结构,Qt线程,桌面应用开发,qt桌面应用开发,Socket网络编程,qt开发工程师,qt开发,应用程序开发框架,图形视图框架,数据库编程,Qt开发编程,Qt开发控件,Qt开发工程师,QT开发必备技能栈,qt编码,qt网络编程,qt网络通信,Qt信号,Qt槽机制,qt字符串,qt数据类型,qt容器,qt客户端开发,qt软件工程师,qt页面绘制

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓ 

学习Qt开发不知道做什么?UP主为大家整理的这些领域都涉及到Qt开发:嵌入式领域、桌面端开发、移动端、微控制器MCU、客户端(游戏、直播等等)、汽车领域行业、 消费类电子设备、医疗领域行业、工业自动化领域等等

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件QT6,C++语言基础,qt基础编程,qt软件开发,Qt架构设计,qt布局管理器,qt嵌入式开发,qt编程入门,qt数据库编程,qt跨平台框架,QT项目实战,Quick模块,OpenCV,Qt实战,OpenCV教程,QT界面开发,Qt框架,C++数据结构,Qt线程,桌面应用开发,qt桌面应用开发,Socket网络编程,qt开发工程师,qt开发,应用程序开发框架,图形视图框架,数据库编程,Qt开发编程,Qt开发控件,Qt开发工程师,QT开发必备技能栈,qt编码,qt网络编程,qt网络通信,Qt信号,Qt槽机制,qt字符串,qt数据类型,qt容器,qt客户端开发,qt软件工程师,qt页面绘制

 

4.2、源文件

  1. #include "qnchatmessage.h"
  2. #include <QFontMetrics>
  3. #include <QPaintEvent>
  4. #include <QDateTime>
  5. #include <QPainter>
  6. #include <QMovie>
  7. #include <QLabel>
  8. #include <QDebug>
  9. QNChatMessage::QNChatMessage(QWidget *parent) : QWidget(parent)
  10. {
  11. QFont te_font = this->font();
  12. te_font.setFamily("MicrosoftYaHei");
  13. te_font.setPointSize(12);
  14. // te_font.setWordSpacing(0);
  15. // te_font.setLetterSpacing(QFont::PercentageSpacing,0);
  16. // te_font.setLetterSpacing(QFont::PercentageSpacing, 100); //300%,100为默认 //设置字间距%
  17. // te_font.setLetterSpacing(QFont::AbsoluteSpacing, 0); //设置字间距为3像素 //设置字间距像素值
  18. this->setFont(te_font);
  19. m_leftPixmap = QPixmap(":/img/Customer Copy.png");
  20. m_rightPixmap = QPixmap(":/img/CustomerService.png");
  21. m_loadingMovie = new QMovie(this);
  22. m_loadingMovie->setFileName(":/img/loading4.gif");
  23. m_loading = new QLabel(this);
  24. m_loading->setMovie(m_loadingMovie);
  25. m_loading->resize(16,16);
  26. m_loading->setAttribute(Qt::WA_TranslucentBackground , true);
  27. m_loading->setAutoFillBackground(false);
  28. }
  29. void QNChatMessage::setTextSuccess()
  30. {
  31. m_loading->hide();
  32. m_loadingMovie->stop();
  33. m_isSending = true;
  34. }
  35. void QNChatMessage::setText(QString text, QString time, QSize allSize, QNChatMessage::User_Type userType)
  36. {
  37. m_msg = text;
  38. m_userType = userType;
  39. m_time = time;
  40. m_curTime = QDateTime::fromTime_t(time.toInt()).toString("hh:mm");
  41. m_allSize = allSize;
  42. if(userType == User_Me) {
  43. if(!m_isSending) {
  44. m_loading->move(m_kuangRightRect.x() - m_loading->width() - 10, m_kuangRightRect.y()+m_kuangRightRect.height()/2- m_loading->height()/2);
  45. m_loading->show();
  46. m_loadingMovie->start();
  47. }
  48. } else {
  49. m_loading->hide();
  50. }
  51. this->update();
  52. }
  53. QSize QNChatMessage::fontRect(QString str)
  54. {
  55. m_msg = str;
  56. int minHei = 30;
  57. int iconWH = 40;
  58. int iconSpaceW = 20;
  59. int iconRectW = 5;
  60. int iconTMPH = 10;
  61. int sanJiaoW = 6;
  62. int kuangTMP = 20;
  63. int textSpaceRect = 12;
  64. m_kuangWidth = this->width() - kuangTMP - 2*(iconWH+iconSpaceW+iconRectW);
  65. m_textWidth = m_kuangWidth - 2*textSpaceRect;
  66. m_spaceWid = this->width() - m_textWidth;
  67. m_iconLeftRect = QRect(iconSpaceW, iconTMPH, iconWH, iconWH);
  68. m_iconRightRect = QRect(this->width() - iconSpaceW - iconWH, iconTMPH, iconWH, iconWH);
  69. QSize size = getRealString(m_msg); // 整个的size
  70. qDebug() << "fontRect Size:" << size;
  71. int hei = size.height() < minHei ? minHei : size.height();
  72. m_sanjiaoLeftRect = QRect(iconWH+iconSpaceW+iconRectW, m_lineHeight/2, sanJiaoW, hei - m_lineHeight);
  73. m_sanjiaoRightRect = QRect(this->width() - iconRectW - iconWH - iconSpaceW - sanJiaoW, m_lineHeight/2, sanJiaoW, hei - m_lineHeight);
  74. if(size.width() < (m_textWidth+m_spaceWid)) {
  75. m_kuangLeftRect.setRect(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), m_lineHeight/4*3, size.width()-m_spaceWid+2*textSpaceRect, hei-m_lineHeight);
  76. m_kuangRightRect.setRect(this->width() - size.width() + m_spaceWid - 2*textSpaceRect - iconWH - iconSpaceW - iconRectW - sanJiaoW,
  77. m_lineHeight/4*3, size.width()-m_spaceWid+2*textSpaceRect, hei-m_lineHeight);
  78. } else {
  79. m_kuangLeftRect.setRect(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), m_lineHeight/4*3, m_kuangWidth, hei-m_lineHeight);
  80. m_kuangRightRect.setRect(iconWH + kuangTMP + iconSpaceW + iconRectW - sanJiaoW, m_lineHeight/4*3, m_kuangWidth, hei-m_lineHeight);
  81. }
  82. m_textLeftRect.setRect(m_kuangLeftRect.x()+textSpaceRect,m_kuangLeftRect.y()+iconTMPH,
  83. m_kuangLeftRect.width()-2*textSpaceRect,m_kuangLeftRect.height()-2*iconTMPH);
  84. m_textRightRect.setRect(m_kuangRightRect.x()+textSpaceRect,m_kuangRightRect.y()+iconTMPH,
  85. m_kuangRightRect.width()-2*textSpaceRect,m_kuangRightRect.height()-2*iconTMPH);
  86. return QSize(size.width(), hei);
  87. }
  88. QSize QNChatMessage::getRealString(QString src)
  89. {
  90. QFontMetricsF fm(this->font());
  91. m_lineHeight = fm.lineSpacing();
  92. int nCount = src.count("\n");
  93. int nMaxWidth = 0;
  94. if(nCount == 0) {
  95. nMaxWidth = fm.width(src);
  96. QString value = src;
  97. if(nMaxWidth > m_textWidth) {
  98. nMaxWidth = m_textWidth;
  99. int size = m_textWidth / fm.width(" ");
  100. int num = fm.width(value) / m_textWidth;
  101. int ttmp = num*fm.width(" ");
  102. num = ( fm.width(value) ) / m_textWidth;
  103. nCount += num;
  104. QString temp = "";
  105. for(int i = 0; i < num; i++) {
  106. temp += value.mid(i*size, (i+1)*size) + "\n";
  107. }
  108. src.replace(value, temp);
  109. }
  110. } else {
  111. for(int i = 0; i < (nCount + 1); i++) {
  112. QString value = src.split("\n").at(i);
  113. nMaxWidth = fm.width(value) > nMaxWidth ? fm.width(value) : nMaxWidth;
  114. if(fm.width(value) > m_textWidth) {
  115. nMaxWidth = m_textWidth;
  116. int size = m_textWidth / fm.width(" ");
  117. int num = fm.width(value) / m_textWidth;
  118. num = ((i+num)*fm.width(" ") + fm.width(value)) / m_textWidth;
  119. nCount += num;
  120. QString temp = "";
  121. for(int i = 0; i < num; i++) {
  122. temp += value.mid(i*size, (i+1)*size) + "\n";
  123. }
  124. src.replace(value, temp);
  125. }
  126. }
  127. }
  128. return QSize(nMaxWidth+m_spaceWid, (nCount + 1) * m_lineHeight+2*m_lineHeight);
  129. }
  130. void QNChatMessage::paintEvent(QPaintEvent *event)
  131. {
  132. Q_UNUSED(event);
  133. QPainter painter(this);
  134. painter.setRenderHints(QPainter::Antialiasing | QPainter::SmoothPixmapTransform);//消锯齿
  135. painter.setPen(Qt::NoPen);
  136. painter.setBrush(QBrush(Qt::gray));
  137. if(m_userType == User_Type::User_She) {
  138. // 用户
  139. //头像
  140. // painter.drawRoundedRect(m_iconLeftRect,m_iconLeftRect.width(),m_iconLeftRect.height());
  141. painter.drawPixmap(m_iconLeftRect, m_leftPixmap);
  142. //框加边
  143. QColor col_KuangB(234, 234, 234);
  144. painter.setBrush(QBrush(col_KuangB));
  145. painter.drawRoundedRect(m_kuangLeftRect.x()-1,m_kuangLeftRect.y()-1,m_kuangLeftRect.width()+2,m_kuangLeftRect.height()+2,4,4);
  146. //
  147. QColor col_Kuang(255,255,255);
  148. painter.setBrush(QBrush(col_Kuang));
  149. painter.drawRoundedRect(m_kuangLeftRect,4,4);
  150. //三角
  151. QPointF points[3] = {
  152. QPointF(m_sanjiaoLeftRect.x(), 30),
  153. QPointF(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), 25),
  154. QPointF(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), 35),
  155. };
  156. QPen pen;
  157. pen.setColor(col_Kuang);
  158. painter.setPen(pen);
  159. painter.drawPolygon(points, 3);
  160. //三角加边
  161. QPen penSanJiaoBian;
  162. penSanJiaoBian.setColor(col_KuangB);
  163. painter.setPen(penSanJiaoBian);
  164. painter.drawLine(QPointF(m_sanjiaoLeftRect.x() - 1, 30), QPointF(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), 24));
  165. painter.drawLine(QPointF(m_sanjiaoLeftRect.x() - 1, 30), QPointF(m_sanjiaoLeftRect.x()+m_sanjiaoLeftRect.width(), 36));
  166. //内容
  167. QPen penText;
  168. penText.setColor(QColor(51,51,51));
  169. painter.setPen(penText);
  170. QTextOption option(Qt::AlignLeft | Qt::AlignVCenter);
  171. option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
  172. painter.setFont(this->font());
  173. painter.drawText(m_textLeftRect, m_msg,option);
  174. } else if(m_userType == User_Type::User_Me) {
  175. // 自己
  176. //头像
  177. // painter.drawRoundedRect(m_iconRightRect,m_iconRightRect.width(),m_iconRightRect.height());
  178. painter.drawPixmap(m_iconRightRect, m_rightPixmap);
  179. //
  180. QColor col_Kuang(75,164,242);
  181. painter.setBrush(QBrush(col_Kuang));
  182. painter.drawRoundedRect(m_kuangRightRect,4,4);
  183. //三角
  184. QPointF points[3] = {
  185. QPointF(m_sanjiaoRightRect.x()+m_sanjiaoRightRect.width(), 30),
  186. QPointF(m_sanjiaoRightRect.x(), 25),
  187. QPointF(m_sanjiaoRightRect.x(), 35),
  188. };
  189. QPen pen;
  190. pen.setColor(col_Kuang);
  191. painter.setPen(pen);
  192. painter.drawPolygon(points, 3);
  193. //内容
  194. QPen penText;
  195. penText.setColor(Qt::white);
  196. painter.setPen(penText);
  197. QTextOption option(Qt::AlignLeft | Qt::AlignVCenter);
  198. option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
  199. painter.setFont(this->font());
  200. painter.drawText(m_textRightRect,m_msg,option);
  201. } else if(m_userType == User_Type::User_Time) {
  202. // 时间
  203. QPen penText;
  204. penText.setColor(QColor(153,153,153));
  205. painter.setPen(penText);
  206. QTextOption option(Qt::AlignCenter);
  207. option.setWrapMode(QTextOption::WrapAtWordBoundaryOrAnywhere);
  208. QFont te_font = this->font();
  209. te_font.setFamily("MicrosoftYaHei");
  210. te_font.setPointSize(10);
  211. painter.setFont(te_font);
  212. painter.drawText(this->rect(),m_curTime,option);
  213. }
  214. }

学习Qt开发不知道做什么?UP主为大家整理的这些领域都涉及到Qt开发:嵌入式领域、桌面端开发、移动端、微控制器MCU、客户端(游戏、直播等等)、汽车领域行业、 消费类电子设备、医疗领域行业、工业自动化领域等等

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件

Qt框架,GUI应用程序,跨平台开发,信号与槽机制,QML语言,模型视图编程,多线程编程,数据库编程,网络编程,XML解析,JSON解析,图形图像处理,用户界面设计,动画效果,OpenGL,WebKit,嵌入式开发,客户端/服务器应用程序.自定义控件QT6,C++语言基础,qt基础编程,qt软件开发,Qt架构设计,qt布局管理器,qt嵌入式开发,qt编程入门,qt数据库编程,qt跨平台框架,QT项目实战,Quick模块,OpenCV,Qt实战,OpenCV教程,QT界面开发,Qt框架,C++数据结构,Qt线程,桌面应用开发,qt桌面应用开发,Socket网络编程,qt开发工程师,qt开发,应用程序开发框架,图形视图框架,数据库编程,Qt开发编程,Qt开发控件,Qt开发工程师,QT开发必备技能栈,qt编码,qt网络编程,qt网络通信,Qt信号,Qt槽机制,qt字符串,qt数据类型,qt容器,qt客户端开发,qt软件工程师,qt页面绘制

 

本文福利,费领取Qt开发学习资料包、技术视频,内容包括(C++语言基础,Qt编程入门,QT信号与槽机制,QT界面开发-图像绘制,QT网络,QT数据库编程,QT项目实战,QT嵌入式开发,Quick模块等等)↓↓↓↓↓↓见下面↓↓文章底部点击费领取↓↓

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/知新_RL/article/detail/652301
推荐阅读