PyQt模拟微信聊天页面开发

一、引述

网上关于Qt模拟微信、QQ的页面开发的多如牛毛,但C++本身来说逻辑上难上手,对只会Python的小伙伴来说太痛苦了。
今天就为大家开个场(下节更精彩),众所周知,要想模拟微信、QQ等这种聊天工具,最重要之一就是聊天框里的气泡问题。

二、思路

1、UI设计

UI的设计风格与微信页面设计大体相似,主要分成了5大部分:

  • 导航栏,消息、用户等点击选择
  • 消息栏框,显示好友消息列表
  • 聊天页面,显示气泡消息
  • 文本框,输入聊天信息
  • 聊天工具框,表情、文件等工具栏

在这里插入图片描述
2、气泡消息绘画

目前采用的方式单独使用一个QWidget类,重写paintEvent事件,主要有三个部分组成:

  • 头像
  • 气泡框
  • 文本框

其中,气泡框大小、文本框大小决定于文本的大小(包括图片的大小)
在这里插入图片描述
3、富文本框(信息输入框)的实现

在这里信息输入框需满足以下要求:

  • 普通文本,部件的基本功能,无需实现
  • 本地图片,实现复制粘贴的需求
  • 网络图片的粘贴,html富文本的格式
  • 本地文件的拖拐(copy)
  • 表情包,与图片类似

在这里插入图片描述
4、服务器实现

暂时以傻瓜式的服务器来实现聊天信息的发送和接受。

  • 中间后端服务器service实现,登录以TCP连接方式进行登录。
  • 各客户端为Client,发送信息时,以UDP方式发送至中转站服务器,服务器再转发至对方。

三、气泡框思路

我们应该知道在聊天框里,每一天聊天记录都是一个item,这个item里包含了头像和信息这两部分内容。
解决这个难题的方法之一就是使用QPainter来进行画图,然后封装成一个QWidget作为一个item。
而聊天框架则使用QListWidget,每当点击发送按钮,触发添加一个item事件。
思路是这样,但实现起来比较难,为此我从CSDN里找到了一位大佬的推文,虽说是C++的Qt写的,但重写为python,问题不大。
首先,我们先写一个气泡类,重写paintEvent事件,并且在类中自定义了消息文本变量data。

window_height = 10
begin_width_spacing = 20
begin_height_spacing = 16
icon_width = 40
icon_height = 40
text_width_spacing = 12
text_height_spacing = 12
triangle_width = 6
triangle_height = 10
triangle_height_spacing = 10
text_min_width = 0
min_width = 0
text_max_width = 0
real_width = 0
text_height = 0
class MyWidget(QtWidgets.QWidget):
    def __init__(self, parent=None, data='',type_mess = 0):
super(MyWidget, self).__init__(parent)
self.setObjectName('myWidget')
self.user_chat_content = data

# 重写paintEvent 否则不能使用样式表定义外观
def paintEvent(self, event):
self.init_data() # 获取文本长度、气泡框架问题

一个气泡的大小决定于文本的长度(自动换行),因此呢,我们应该先定义font的类型,它的字体和大小。

def init_data(self):
    font = QtGui.QFont()
    font.setFamily("实体")
    font.setPointSize(12)
    metrics = QFontMetrics(font)
    global text_min_width, min_width,text_max_width,real_width, text_height, window_height
    if metrics.width("A") * 2 + begin_height_spacing * 1.5 > text_width_spacing:
    text_min_width = begin_height_spacing * 1.5 - text_width_spacing
    else:
    text_min_width = 0
    min_width = begin_width_spacing + icon_width + triangle_width + text_width_spacing + text_width_spacing + icon_width + begin_width_spacing
    if self.width()< min_width+text_min_width:
    self.setMinimumWidth(min_width + text_min_width)
    text_max_width = self.width() - min_width
    real_width = metrics.width(self.user_chat_content)
    if real_width < text_max_width:
    text_max_width = real_width
    if text_height_spacing+metrics.height()+text_height_spacing>triangle_height_spacing+triangle_height+triangle_height_spacing:
    text_height = metrics.height()
    else:
    text_height = triangle_height_spacing + triangle_height + triangle_height_spacing
    else:
    flag = QtCore.Qt.TextWordWrap
    textRect = QRect(0, 0, text_max_width, 0)
                # 自动换行
    textRect = metrics.boundingRect(textRect, flag, self.user_chat_content)
    text_height = textRect.height()

初始化完一些气泡的宽度、长度后,接下来就是画气泡的问题了。气泡=头像+信息,但气泡又分为两种,一种是自己发送的消息气泡,而另一种是对方发送的气泡,分别占据右侧和左侧。

因此呢,还需要再添加一个变量才行,用来判定是否是接收方。最后就是调用painter.drawPixmap函数画出头像,painter.drawText来画出文字即可。

好了,今天就为大家开个场,更多精彩点击——>>跳转
在这里插入图片描述

  • 9
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值