Qt局域网聊天(私聊/截图/文件/语音)

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

个人blog本文地址 http://blog.peoplevip.cn/2019/eba88ba7.html
本文档将依据启动次序来写

  • 设计时这里用的是主机的ip地址,可使用多台主机运行程序进行测试,确保多台主机连接同一局域网,之前调试过程中发现可能会检测到本地多个局域网IP,所以程序启动之初需要手动选择检测列表中的某个IP。
    Qt局域网聊天(私聊/截图/文件/语音)_第1张图片

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

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

Qt局域网聊天(私聊/截图/文件/语音)_第2张图片
Qt局域网聊天(私聊/截图/文件/语音)_第3张图片
此处的关键是在主界面的构造函数中发送上线广播,关闭时发送离线广播
2. 界面介绍

  • 消息发送框上分别代表字体样式、字体大小、加粗、斜体、下划线、颜色、截图、选择文件;
  • 消息接受框上为语音聊天、视频通话(未实现)、文件传输、远程桌面。
  • 选择IP左侧为切换皮肤,效果如下图
Qt局域网聊天(私聊/截图/文件/语音)_第4张图片 Qt局域网聊天(私聊/截图/文件/语音)_第5张图片
  • 截图界面展示
    Qt局域网聊天(私聊/截图/文件/语音)_第6张图片
    3.文件的传输
  • 群聊界面:
    • 在文件传输前,我们首先选择要发送到的IP地址,从右侧的显示主机信息中选择,若未选中,会提示用户未选中并重新选择,在选中接收文件的IP后(群聊可以选中自己IP进行测试),点击消息输入框上的传输文件按钮,此时进入Server文件发送界面。选择发送文件进行发送,此时另一选中的用户弹出Client文件接收界面,选择是否接收。
  • 私聊
    私聊界面文件发送直接点击,效果和主界面相同

4.私人聊天

  • 从右侧显示主机信息栏中双击,为了方便测试,此处可以和自己聊天。当双击用户时,此时弹出私人聊天界面,并显示与某某聊天中,获得它的IP地址。对方收到消息会在主页面显示“XXX正在给您发送私聊消息”
    Qt局域网聊天(私聊/截图/文件/语音)_第7张图片
  • 发送窗口抖动
    建立窗口抖动标志,在发送消息里,接收端收到消息后窗口在上下左右不同幅度抖动
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局域网聊天(私聊/截图/文件/语音)_第8张图片

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

  • 等等,不一一表述。可以在文末下载体验

5.其他细节

  • 支持列表改名

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

视频展示(此处录制较早没有语音聊天,程序里是有的如果无法播放可以点击这里播放)
https://streamja.com/AJGR


主题部分参考

  1. 基于Qt的QQ局域网聊天

  2. QT自定义精美换肤界面

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

源程序代码下载链接:https://download.csdn.net/download/tsvico/11286445

你可能感兴趣的:(qt)