Qt局域网聊天


原文地址 https://blog.csdn.net/tsvico/article/details/94721560

本次设计是一个简易的局域网聊天,功能设计主要分为群聊和私聊两部分,每部分都支持基础聊天以及文件传输功能,私聊页面相较于主页面支持更多功能,例如表情发送、窗口抖动,语音聊天等。参考了《Qt及Qt Quick开发实战精解》中第5章群聊实例,在群聊的基础设计了私聊这部分内容以及其他一些功能。下面介绍下整体的设计以及实现。

本文档将依据启动次序来写

  • 设计时这里用的是主机的ip地址,可使用多台主机运行程序进行测试,确保多台主机连接同一局域网,之前调试过程中发现可能会检测到本地多个局域网IP,所以程序启动之初需要手动选择检测列表中的某个IP。
    选择IP

文件的传输、私聊、语音采用的是TCP、UDP、UDP,其中UDP中主要用来保存进行不同操作的消息状态(新用户的加入、消息的发送,传输文件、拒绝接受文件、用户离开、进入私聊阶段),然后通过广播发送给其他的客户端从而保证各个客户端的即时性,各个客户端接受到不同的消息状态进行响应执行操作。程序执行时属于新用户加入阶段, 此时所有用户都处于同一界面,相当于群聊阶段,可发送消息进行群聊。TCP主要用来传输文件,当接受到由UPD发送的传输文件消息时,发送文件一方作为Server端,接受文件一方作为Client端,实现点到点之间的传输。

用户加入

对于新用户的加入我们会显示主机的用户名,每加入一个客户端,在其他客户端以及自己客户端中显示用户名、主机名(此列存在但被人工隐藏)、IP地址、并在消息记录框中显示xxx在线,此时某一方发送消息在其他客户端即可实时收到消息,实现群聊功能(图一)。当某个客户端关闭或退出程序时,此时在消息框记录框中显示于时间离开,当再有新用户加入时又再次显示xxx在线。(本机局域网的IP是172.16.22.48),另一客户端IP(172.16.22.53)

图一
图二
此处的关键是在主界面的构造函数中发送上线广播,关闭时发送离线广播

界面介绍

  • 消息发送框上分别代表字体样式、字体大小、加粗、斜体、下划线、颜色、截图、选择文件;
  • 消息接受框上为语音聊天、视频通话(未实现)、文件传输、远程桌面。
  • 选择IP左侧为切换皮肤,效果如下图




  • 截图界面展示
    在这里插入图片描述

    文件的传输

  • 群聊界面:
    • 在文件传输前,我们首先选择要发送到的IP地址,从右侧的显示主机信息中选择,若未选中,会提示用户未选中并重新选择,在选中接收文件的IP后(群聊可以选中自己IP进行测试),点击消息输入框上的传输文件按钮,此时进入Server文件发送界面。选择发送文件进行发送,此时另一选中的用户弹出Client文件接收界面,选择是否接收。
  • 私聊
    私聊界面文件发送直接点击,效果和主界面相同

私人聊天

  • 从右侧显示主机信息栏中双击,为了方便测试,此处可以和自己聊天。当双击用户时,此时弹出私人聊天界面,并显示与某某聊天中,获得它的IP地址。对方收到消息会在主页面显示“XXX正在给您发送私聊消息”
    私聊
  • 发送窗口抖动
    建立窗口抖动标志,在发送消息里,接收端收到消息后窗口在上下左右不同幅度抖动
QPropertyAnimation *pAnimation = new QPropertyAnimation(this, "pos");
pAnimation->setDuration(500);
pAnimation->setLoopCount(2);
pAnimation->setKeyValueAt(0, QPoint(geometry().x() - 3, geometry().y() - 3));
pAnimation->setKeyValueAt(0.1, QPoint(geometry().x() + 6, geometry().y() + 6));
pAnimation->setKeyValueAt(0.2, QPoint(geometry().x() - 6, geometry().y() + 6));
pAnimation->setKeyValueAt(0.3, QPoint(geometry().x() + 6, geometry().y() - 6));
pAnimation->setKeyValueAt(0.4, QPoint(geometry().x() - 6, geometry().y() - 6));
pAnimation->setKeyValueAt(0.5, QPoint(geometry().x() + 6, geometry().y() + 6));
pAnimation->setKeyValueAt(0.6, QPoint(geometry().x() - 6, geometry().y() + 6));
pAnimation->setKeyValueAt(0.7, QPoint(geometry().x() + 6, geometry().y() - 6));
pAnimation->setKeyValueAt(0.8, QPoint(geometry().x() - 6, geometry().y() - 6));
pAnimation->setKeyValueAt(0.9, QPoint(geometry().x() + 6, geometry().y() + 6));
pAnimation->setKeyValueAt(1, QPoint(geometry().x() - 3, geometry().y() - 3));
pAnimation->start(QAbstractAnimation::DeleteWhenStopped);
  • 语音发送
    创建语音标志在发送消息里,为了发语音的同时还要能听到,发送时要对语音进行接收。一方取消语音时要发送关闭语音广播,另一方同时关闭语音传输。为了保证接收端和发送端同时关闭,这里重写了关闭事件
void autrans::closeEvent(QCloseEvent *e){
    emit meclose(); //发送关闭信号
    QWidget::closeEvent(e);
}
  • 表情发送
    创建新的tableview在私聊界面,将表情通过代码加载到UI界面
void priroom::addEmotionItem(int row,int low,int lo)
{
    QLabel* label1 = new QLabel;
    QString path = ":/emoji/%1.gif";
    QMovie *movie =new QMovie(path.arg(lo+1));
    movie->setScaledSize(QSize(25,25));
    label1->setMovie(movie);
    ui->tableWidget->setCellWidget(row,low,label1);
    movie->start();
}

获取点击的行列位置,计算出图片路径,将表情发送

  • 等等

其他细节

  • 支持列表改名

总结:基本也就这么多,目前没有注册、登录功能,对于数据库的操作,后面打算把这些也添加进去,代码解释大家可以去看《Qt及Qt Quick开发实战精解》这本书,对于私聊这块大家也可以下载下面的源程序链接,添加了很多注释,以及qDebug调试。

视频展示(此处录制较早没有语音聊天,如果无法播放可以点击这里)

主题部分参考

应用程序测试链接(双击.exe文件):
https://www.lanzous.com/i4unced

猜你喜欢

转载自www.cnblogs.com/tsvico/p/12244473.html