橄榄球世界杯_1990世界杯阿根廷 - liuweiqing95511.com

橄榄球世界杯_1990世界杯阿根廷 - liuweiqing95511.com

QT实现聊天室

Home 2025-10-18 18:59:29 QT实现聊天室

QT实现聊天室

qt实现聊天室 项目功能简介 1) 连接 客户端,需要先连接服务器。就是输入服务器端的IP和端口连接服务器,如果连接成功,连接按钮显示文字

  • admin 18世界杯德国
  • 2025-10-18 18:59:29

qt实现聊天室

项目功能简介

1) 连接

客户端,需要先连接服务器。就是输入服务器端的IP和端口连接服务器,如果连接成功,连接按钮显示文字会显示已连接,颜色变浅。

2) 注册

接下来是注册,如果申请的用户名还有人用户注册,则可以注册成功,如果之前有用户注册过之后会显示注册失败。

3)登录

在接下来是登录,如果要登录的用户名还没有注册过,会显示未注册。如果密码错误会显示密码错误。如果换设备登录会显示新设备登录。如果用户名与密码都正确,则可以成功登录。

4)聊天

登录成功后就可以进入主界面。在主界面中,有三个功能区:用户管理、聊天、文本传输。

1)

用户管理功能区,可以更换昵称、更改头像、退出登录与注销账号

2)

聊天,可以群聊、私聊、群历史、私聊历史、删除私聊历史、显示好友列表、清屏

3)

文本传输,可以获取所有聊天室的用户,上传到服务器端的文件列表。还可以上传、下载文件。

1、项目运行展示

登录界面

聊天界面

1.1连接

1.2注册

1.3登录

1.4用户管理

1.5聊天

1)群聊

2)私聊

3)关闭历史记录显示(清屏)

4)群聊历史查询

5)私聊历史

6)清空私聊历史记录

7)我的好友

1.6文件传输

1)获取文件列表

2)上传文件

2、项目设计流程

服务器端一开始运行就会建立一个数据库文件。里面有四张表(注册表、登录表、群历史聊天记录表、私聊历史记录表)。

2.1 连接

客户端获取用户输入的IP和密码,建立一个连接对象,连接这个IP和端口的服务器。服务器端先是创建一个连接管理类对象,监听客户端连接。如果有客户端连接,创建一个唯一与之对应的连接对象。把他添加到容器中。

2.2 注册

客户端

获取用户输入的用户名与密码,拼接好后,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是注册消息,则调用对应的注册函数。在注册函数中会先调用查询注册表的函数,判断用户注册的用户名是否可以成功注册,如果可以,调用插入注册表的函数,将该用户注册的用户名与密码保存在注册表中,给客户端发送注册成功标志,如果错误,则发送注册失败标志。

客户端

接收服务器端发送过来的信息,判断是那一种标志,

如果是注册失败标志,则弹出“注册失败”对话框

如果是注册成功标志,则弹出“注册成功”对话框

2.3 登录

客户端

获取用户输入的用户名与密码,拼接好后,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是登录消息,则调用对应的登录函数。在登录函数中会先调用查询注册表的函数,判断用户登录的用户名是否已经注册。

1)如果没有注册过,则给客户端发送未注册标志。

2)如果该用户已经注册,但是密码不匹配,则给客户端发送密码错误标志

3)如果用户名与密码都正确,则给客户端发送登录成功标志。并去调用查登录表的函数,如果该用户第一次登录,需要把该用户的用户名、登录IP和端口插入到登录表中。如果已经登录过,则检测IP是否更换,未更换的话,给客户端发送成功登录的标志。如果更换则给它发送换设备标志,并更新登录表。

客户端

接收服务器端发送过来的信息,判断是那一种标志,

如果是未注册标志,则弹出“未注册”对话框

如果是是密码错误标志,则弹出“密码错误”对话框

如果是是登录成功标志,则弹出“登录成功”对话框,并跳转到主界面,关闭登录界面

如果是换设备标志,则弹出“换新设备登录”对话框,跳转到主界面,关闭登录界面

2.4 聊天

(1)群聊

客户端

获取用户输入消息内容,前面拼接上消息的类型,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是群聊消息,则调用对应的群聊函数。

将信息发送给其他客户端,并将信息加上用户名与时间存放到群聊历史记录表中。

客户端

接收服务器端发送过来的信息,将信息显示在聊天窗口

(2)群聊历史

客户端

将查询群聊历史的命令,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是查询群聊历史消息,则调用对应的查询群聊历史函数。在该函数中查询聊天记录,发送给客户端。

客户端

接收服务器端发送过来的信息,将信息显示在聊天窗口

(3)私聊

客户端

获取用户输入消息内容与接受此消息的用户,前面拼接上消息的类型,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是私聊消息,则调用对应的私聊函数。去查询注册表,如果有此用户,再去查询登录表,找到对应的IP和端口。通过迭代器指针遍历当前连接客户端对象容器,对比IP和端口,找到相同的客户端,将信息发送过去。并将信息加上用户名与时间存放到私聊历史记录表中。

客户端

接收服务器端发送过来的信息,将信息显示在聊天窗口

(4)查私聊历史

客户端

将查询私聊历史的命令,后面拼接上本用户的用户名,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是查询私聊消息,则调用对应的私聊函数。去查询私聊历史记录表,找到发给该用户的所有私聊信息,并将信息发送过去。

客户端

接收服务器端发送过来的信息,将信息显示在聊天窗口

(5)清空私聊历史

客户端

将查询私聊历史的命令,后面拼接上本用户的用户名,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是清空私聊历史消息,则调用对应的私聊函数。去删除指定用户的私聊历史记录表。

(6)查好友历史

客户端

将查询好友的命令,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是查询好友消息,则调用对应的查询好友函数。去查询注册表,将已注册的所有用户的用户名发送给客户端。

客户端

接收服务器端发送过来的信息,将信息显示在聊天窗口。

(7)关闭历史记录显示

则调用该组件的清空函数,清空显示。

2.5 文本传输

(1)获取文件列表

客户端

将查询文件的命令,后面拼接上,服务器给该聊天室创建的文件夹路径,创建一个文本流对象,发送给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是查询文件列表消息,则调用对应的查询文件列表函数。去查指定路径下的文件夹信息,发送给客户端。

客户端

接收服务器端发送过来的信息,将信息显示在聊天窗口。

(2)上传文件

客户端

弹出打开文件的弹窗,在里面选择要发送的文件。

将上传的命令,后面拼接上该文件名,创建一个文本流对象,发送给服务器。接着创建一个线程对象,定义好进度条更新的信号与槽函数连接协议,调用start()函数,执行线程中run函数,发送文件内容给服务器。

服务器端

接受到客户端发来的消息,先判断是什么类型的消息,如果是上传文件消息,则调用对应的接受上传文件的函数。先接收客户端发送过来的文件名,创建一个线程对象,并通过构找函数传参的方式将文件名传给子线程,调用start()函数。执行子线程的run()函数。在run()函数中,先判断路径下有没有该文件,没有则创建。并将接受到的文件内容填充进去

3、完整代码

3.1客户端

1).pro文件

加上network网络通信模块

#-------------------------------------------------

#

# Project created by QtCreator 2023-07-20T14:39:05

#

#-------------------------------------------------

QT += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = UdpChatClient

TEMPLATE = app

SOURCES += main.cpp\

dialog.cpp \

mydialog.cpp \

sendthread.cpp

HEADERS += dialog.h \

mydialog.h \

sendthread.h

FORMS += dialog.ui \

mydialog.ui

RESOURCES += \

res.qrc

OTHER_FILES += \

iconfig.rc

RC_FILE += iconfig.rc

2)dialog.h文件

#ifndef DIALOG_H

#define DIALOG_H

#include

#include

#include

#include

#include

namespace Ui {

class Dialog;

}

class Dialog : public QDialog

{

Q_OBJECT

public:

explicit Dialog(QWidget *parent = 0);

~Dialog();

private:

Ui::Dialog *ui;

QTcpSocket *client;// 连接对象

MyDialog *md; //聊天窗口对象

private slots:

void btnConnectClickedSlot(); //连接的槽函数

void btnRegisterClickedSlot(); //注册的槽函数

void btnLogonClickedSlot(); //登录的槽函数

void conntedSlot(); //连接成功槽函数

void disconntedSlot();//断开连接槽函数

void readyreadSlot();//接受服务器端发送过来的标志

void switchInterfaceSlot(); //切换回主界面

};

#endif // DIALOG_H

3)mydialog.h文件

#ifndef MYDIALOG_H

#define MYDIALOG_H

#include

#include

#include

#include

#include

#include

#include

#include

#include"sendthread.h"

namespace Ui {

class MyDialog;

}

class MyDialog : public QDialog

{

Q_OBJECT

public:

explicit MyDialog(QString name,QString ip,int port,QWidget *parent = 0);

~MyDialog();

private:

Ui::MyDialog *ui;

QString name; //用户名

QTcpSocket *client; //连接对象

QString cmd; //命令

QString readPath; //读路径

QList list;//声明list容器对象成员变量

QList::iterator iter;//声明迭代器指针

QString ip; //获取服务器的ip和端口

int port;

void connntPort(); //建立本进程与服务器端的连接

void updataPort(); //更新端口

void creatFolder(); //创建下载目录

private slots:

void btnSendClickedSlot();//群发

void btnHisQClickedSlot();//群历史聊天记录查询

void btnSendUsrClickedSlot();//私发

void btnHisSClickedSlot();//私聊自己的历史记录

void btnSelectChatUsrClickedSlot();//查询聊天室的成员

void btnNoLogClickedSlot();//退出登录

void btnNoResClickedSlot();//注销账户

void btnClearClickedSlot();//清空历史记录

void btnCloseDpClieckedSlot();//关闭历史记录显示

void btnGetFileListSlot(); //获取文件列表

void btnSendFileSlot(); //上传文件

void btnDownloadSlot(); //下载文件

void mydialogReadyreadSlot();//接受消息

void btnSetnameClickedSlot();//修改昵称

void btnSelectPtoClickedSlot();//选择头像

void btnSurePhoClickedSlot(); //确认头像

// void sendValueSlot(int); //更新上传文件进度条

void sendValueSlot(int);

void sendFinishSlot();

signals:

void switchInterface();//切换回主界面信号

};

#endif // MYDIALOG_H

4)sendthread.h文件(上传文件子线程)

#ifndef SENDTHREAD_H

#define SENDTHREAD_H

#include

#include

#include

#include

#include

#include

class SendThread : public QThread

{

Q_OBJECT

public:

explicit SendThread(QTcpSocket *client,QString readpth,QObject *parent = 0);

protected:

void run();

private:

QString readpth;

QString ip; //服务器端ip

int port;

QTcpSocket *client;

void threadClickedSlot();

signals:

void sendValueSignal(int);

void sendFinish();

public slots:

};

#endif // SENDTHREAD_H

5)dialog.cpp文件

#include "dialog.h"

#include "ui_dialog.h"

Dialog::Dialog(QWidget *parent) :

QDialog(parent),

ui(new Ui::Dialog)

{

ui->setupUi(this);

//连接、登录、注册按钮点击时触发的信号

connect(ui->pushButtonConn,SIGNAL(clicked()),this,SLOT(btnConnectClickedSlot()));

connect(ui->pushButtonRegister,SIGNAL(clicked()),this,SLOT(btnRegisterClickedSlot()));

connect(ui->pushButtonLogon,SIGNAL(clicked()),this,SLOT(btnLogonClickedSlot()));

//创建一个TCP连接类对象

client =new QTcpSocket(this);

//连接状态改变时触发的信号

connect(client,SIGNAL(connected()),this,SLOT(conntedSlot()));

connect(client,SIGNAL(disconnected()),this,SLOT(disconntedSlot()));

//接受到服务器发送过来的数据触发

connect(client,SIGNAL(readyRead()),this,SLOT(readyreadSlot()));

}

Dialog::~Dialog()

{

disconnect(client,SIGNAL(disconnected()),this,SLOT(disconntedSlot()));

if(client->isOpen())

client->close();

delete ui;

}

//连接槽函数

void Dialog::btnConnectClickedSlot()

{

//获取用户输入的ip和端口

QString ip=ui->lineEditIP->text();

int port=ui->spinBox->value();

////为了解决第一次输入错误的IP和端口不能连接的问题

//终止当前连接

client->abort();

//建立新的连接对象

client =new QTcpSocket(this);

////新的连接对象也需要建立这些信号的约定

//连接状态改变时触发的信号

connect(client,SIGNAL(connected()),this,SLOT(conntedSlot()));

connect(client,SIGNAL(disconnected()),this,SLOT(disconntedSlot()));

//接受到服务器发送过来的数据触发

connect(client,SIGNAL(readyRead()),this,SLOT(readyreadSlot()));

//连接服务器

client->connectToHost(ip,port);

//设置标题

setWindowTitle("聊吧");

}

//成功连接

void Dialog::conntedSlot()

{

//屏蔽连接按钮

ui->pushButtonConn->setEnabled(false);

//回复登录、注册按钮

ui->pushButtonRegister->setEnabled(true);

ui->pushButtonLogon->setEnabled(true);

ui->pushButtonConn->setText("已连接");

}

//连接断开

void Dialog::disconntedSlot()

{

//恢复连接按钮

ui->pushButtonConn->setEnabled(true);

//屏蔽登录、注册按钮

ui->pushButtonRegister->setEnabled(false);

ui->pushButtonLogon->setEnabled(false);

ui->pushButtonConn->setText("连接");

QMessageBox::warning(this,"提示","连接已断开");

}

//接受服务器端发送过来的标志,执行相应的逻辑处理

void Dialog::readyreadSlot()

{

//获取用户输入的ip和端口

QString ip=ui->lineEditIP->text();

int port=ui->spinBox->value();

QTextStream input(client);

QString text=input.readLine(256);

//qDebug()<

if(text=="register sucess")

QMessageBox::information(this,"提示","注册成功");

else if(text=="register fause")

QMessageBox::warning(this,"提示","注册失败,用户名已存在");

else if(text=="nouser")

QMessageBox::warning(this,"提示","登录失败,该用户名还没有注册,请先注册");

else if(text=="pwderr")

QMessageBox::warning(this,"提示","登录失败,密码错误,请重新输入");

else if(text=="loginsuccess")

{

QString name=ui->lineEditUsr->text();

md=new MyDialog(name,ip,port);

connect(md,SIGNAL(switchInterface()),this,SLOT(switchInterfaceSlot()));//切换回主界面的连接信号槽的约定

md->show();

this->close();

}

else if(text=="deviceh")

{

QMessageBox::warning(this,"提示","登录成功,该账号使用新设备登录");

QString name=ui->lineEditUsr->text();

md=new MyDialog(name,ip,port);

connect(md,SIGNAL(switchInterface()),this,SLOT(switchInterfaceSlot()));//切换回主界面的连接信号槽的约定

md->show();

this->close();

}

}

//注册

void Dialog::btnRegisterClickedSlot()

{

QString name=ui->lineEditUsr->text();

if(name=="")

{

QMessageBox::warning(this,"提示","请输入用户名");

return;

}

QString pwd=ui->lineEditPwd->text();

if(pwd=="")

{

QMessageBox::warning(this,"提示","请输入密码");

return;

}

QString cmd="register";

//拼接

QString text=cmd.append("\n").append(name).append("\n").append(pwd);

//创建文本流类

QTextStream output(client);

//发送消息

output<

}

//登录

void Dialog::btnLogonClickedSlot()

{

QString name=ui->lineEditUsr->text();

if(name=="")

{

QMessageBox::warning(this,"提示","请输入用户名");

return;

}

QString pwd=ui->lineEditPwd->text();

if(pwd=="")

{

QMessageBox::warning(this,"提示","请输入密码");

return;

}

QString cmd="login";

//拼接

QString text=cmd.append("\n").append(name).append("\n").append(pwd);

//创建文本流类

QTextStream output(client);

//发送消息

output<

}

//切换回主界面

void Dialog::switchInterfaceSlot()

{

Dialog *dz=new Dialog;

dz->show();

md->close();

}

6)mydialog.cpp文件

#include "mydialog.h"

#include "ui_mydialog.h"

MyDialog::MyDialog(QString name,QString ip,int port,QWidget *parent) :

QDialog(parent),name(name),ip(ip),port(port),

ui(new Ui::MyDialog)

{

client = new QTcpSocket(this);

ui->setupUi(this);

qDebug()<

creatFolder();//创建目录

//按钮触发的槽函数(群发送、群历史记录、私聊、私聊历史记录、退出登录、注销账户、清空私聊历史记录)

connect(ui->pushButtonSend,SIGNAL(clicked()),this,SLOT(btnSendClickedSlot()));

connect(ui->pushButtonHisQ,SIGNAL(clicked()),this,SLOT(btnHisQClickedSlot()));

connect(ui->pushButtonSendUsr,SIGNAL(clicked()),this,SLOT(btnSendUsrClickedSlot()));

connect(ui->pushButtonHisS,SIGNAL(clicked()),this,SLOT(btnHisSClickedSlot()));

connect(ui->pushButtonNoLog,SIGNAL(clicked()),this,SLOT(btnNoLogClickedSlot()));

connect(ui->pushButtonNoRes,SIGNAL(clicked()),this,SLOT(btnNoResClickedSlot()));

connect(ui->pushButtonClear,SIGNAL(clicked()),this,SLOT(btnClearClickedSlot()));

//关闭历史记录显示

connect(ui->pushButtonClosedp,SIGNAL(clicked()),this,SLOT(btnCloseDpClieckedSlot()));

//按钮触发文件上传、下载

connect(ui->pushButtonGetFileList,SIGNAL(clicked()),this,SLOT(btnGetFileListSlot()));

connect(ui->pushButtonSendFile,SIGNAL(clicked()),this,SLOT(btnSendFileSlot()));

connect(ui->pushButtonDownload,SIGNAL(clicked()),this,SLOT(btnDownloadSlot()));

//按钮触发修改头像、昵称

connect(ui->pushButtonSelectPho,SIGNAL(clicked()),this,SLOT(btnSelectPtoClickedSlot()));

connect(ui->pushButtonSurePho,SIGNAL(clicked()),this,SLOT(btnSurePhoClickedSlot()));

connect(ui->pushButtonSetname,SIGNAL(clicked()),this,SLOT(btnSetnameClickedSlot()));

//获取好友列表

connect(ui->pushButtonSelectChatUsr,SIGNAL(clicked()),this,SLOT(btnSelectChatUsrClickedSlot()));

//接受到消息时触发的槽函数

connect(client,SIGNAL(readyRead()),this,SLOT(mydialogReadyreadSlot()));

//连接服务器(因为换页面进程了,端口号换了,需要重新连接)

connntPort();//本进程连接服务器

updataPort();//更新登录表

//设置头像

list.append(":/new/prefix1/b.jpg");

list.append(":/new/prefix1/a.jpg");

list.append(":/new/prefix1/d.jpg");

list.append(":/new/prefix1/c.jpg");

list.append(":/new/prefix1/e.jpg");

list.append(":/new/prefix1/f.jpg");

//初始化迭代器指针

iter=list.begin();

//设置图片大小为适应Label

QSize size(ui->labelPixmap->width(),ui->labelPixmap->height());

QPixmap pic(*iter);

pic=pic.scaled(size,Qt::KeepAspectRatioByExpanding);

ui->labelPixmap->setPixmap(*iter);

//设置图标

QString icoPath=":/new/prefix1/sun.ico";

QIcon ico(icoPath);

setWindowIcon(ico);

}

MyDialog::~MyDialog()

{

if(client->isOpen())

client->close();

delete ui;

}

//换昵称

void MyDialog::btnSetnameClickedSlot()

{

QString username=ui->lineEditSetname->text();

this->setWindowTitle(username);

}

//选择头像

void MyDialog::btnSelectPtoClickedSlot()

{

//如果向上翻到最后一张,就把迭代器指针指向第一张图片

if(*iter==":/new/prefix1/f.jpg")

{

qDebug()<<"6";

iter=list.begin();

}

//向下,迭代器指针++

else

{

++iter;

}

//设置图片大小为适应Label

QSize size(ui->labelPixmap->width(),ui->labelPixmap->height());

QPixmap pic(*iter);

pic=pic.scaled(size,Qt::KeepAspectRatioByExpanding);

ui->labelPixmap->setPixmap(*iter);

}

//确认头像

void MyDialog::btnSurePhoClickedSlot()

{

QMessageBox::information(this,"提示","确认更换");

}

void MyDialog::btnSelectChatUsrClickedSlot()

{

cmd="selectChatUsr";

QString text=cmd.append("\n").append(name).append("\n").append(ip);

QTextStream output(client);

output<

}

//本进程连接服务器

void MyDialog::connntPort()

{

client->connectToHost(ip,port);

}

//更新服务器端登录表

void MyDialog::updataPort()

{

cmd="updataPort";

QString text=cmd.append("\n").append(name).append("\n").append(ip);

QTextStream output(client);

output<

}

//创建下载目录

void MyDialog::creatFolder()

{

qDebug()<<"建目录";

QDir dir;

QString path="D:/XinClientFileDownLoad";

if(dir.mkdir(path))

qDebug()<<"创建目录成功";

else

{

qDebug()<<"创建目录失败";

}

}

//获取文件列表

void MyDialog::btnGetFileListSlot()

{

//获取服务器端指定文件夹路径

QString path="D:/XinServerFileDownLoad";

cmd="getFileList";

QString text=cmd.append("\n").append(path).append("\n").append("a");

//创建文本流对象

QTextStream output(client);

output<

}

void MyDialog::sendFinishSlot()

{

qDebug()<<"写入完成";

}

//上传文件

void MyDialog::btnSendFileSlot()

{

cmd="sendFile";

QString fileter="所有文件(*.*);;文本文件(*.txt);;Qt(*.cpp *.h *.ui)";

QString path=QFileDialog::getOpenFileName(this,

"打开",

"D:/XinServerFileDownLoad",

fileter);

if(path==""&&readPath=="")

{

QMessageBox::warning(this,"提示","请选择文件!");

return;

}

if(path==""&&readPath!="")

return;

readPath=path;

//获取文件名

QFileInfo info(readPath);

QString filename=info.fileName();

// qDebug()<

QString text=cmd.append("\n").append(filename).append("\n").append("ip");

//创建文本流对象

QTextStream output(client);

//发送

output<

//qDebug()<

//屏蔽上传按钮

ui->pushButtonSendFile->setEnabled(false);

// QThread::msleep(8000);

SendThread *st=new SendThread(client,readPath,this);

connect(st,SIGNAL(sendValueSignal(int)),this,SLOT(sendValueSlot(int)));

connect(st,SIGNAL(sendFinish()),this,SLOT(sendFinishSlot()));

st->start();

// //创建读对象

// QFile readFile(readPath);

// readFile.open(QIODevice::ReadOnly);

// //获取文件总大小

// qint64 totalSize=readFile.size();

// qint64 hasRead=0;

// int lastper=0;

// QByteArray buffer;

// while(!readFile.atEnd())

// {

// buffer=readFile.read(1024);

// qDebug()<

// // hasRead+=client->write(buffer);

// client->waitForBytesWritten(true);

// int per=hasRead*100/totalSize;

// ui->progressBarSend->setValue(per);

// }

// ui->pushButtonSendFile->setEnabled(true);

}

void MyDialog::sendValueSlot(int value)

{

ui->progressBarSend->setValue(value);

if(value==100)

ui->pushButtonSendFile->setEnabled(true);

}

//下载文件

void MyDialog::btnDownloadSlot()

{

}

//接受消息

void MyDialog::mydialogReadyreadSlot()

{

if(cmd=="hisq"||cmd=="hiss")

ui->textBrowser->clear();

QTextStream input(client);

QString text=input.readAll();

qDebug()<

//如果存在"end"则移除

QString e="end";

text.remove(e);

ui->textBrowser->append(text);

}

//发送消息

void MyDialog::btnSendClickedSlot()

{

cmd="chatq";

QString msg=ui->lineEdit->text();

if(msg=="")

{

QMessageBox::warning(this,"提示","请输入要发送的内容");

return;

}

QString text=cmd.append("\n").append(name).append("\n").append(msg);

//创建文本流对象

QTextStream output(client);

output<

}

//查询历史记录

void MyDialog::btnHisQClickedSlot()

{

ui->textBrowser->clear();

cmd="hisq";

QString text=cmd.append("\n").append("a").append("\n").append("b");

//创建文本流对象

QTextStream output(client);

output<

}

//私发

void MyDialog::btnSendUsrClickedSlot()

{

qDebug()<<"私发";

cmd="chats";

QString msg=ui->lineEdit->text();

if(msg=="")

{

QMessageBox::warning(this,"提示","请输入要发送的内容");

return;

}

QString resiveuser=ui->lineEditSendUser->text();

if(resiveuser=="")

{

QMessageBox::warning(this,"提示","请输入指定接收者");

return;

}

QString text=cmd.append("\n").append(name).append("\n").append(resiveuser).append("\n").append(msg);

//创建文本流对象

QTextStream output(client);

output<

}

//私聊的历史记录查询

void MyDialog::btnHisSClickedSlot()

{

ui->textBrowser->clear();

cmd="hiss";

QString text=cmd.append("\n").append(name).append("\n").append("b");

//创建文本流对象

QTextStream output(client);

output<

}

//退出登录

void MyDialog::btnNoLogClickedSlot()

{

cmd="nologin";

QString text=cmd.append("\n").append(name).append("\n").append("b");

//创建文本流对象

QTextStream output(client);

output<

emit switchInterface();//发送切换界面信号

}

//注销账户

void MyDialog::btnNoResClickedSlot()

{

QMessageBox::StandardButton result=QMessageBox::question(this,"question","你是否要注销该账户");

if(result==QMessageBox::Yes)

{

cmd="noregister";

QString text=cmd.append("\n").append(name).append("\n").append("b");

//创建文本流对象

QTextStream output(client);

output<

emit switchInterface();//发送切换界面信号

}

}

//清空私聊历史记录

void MyDialog::btnClearClickedSlot()

{

QMessageBox::StandardButton result=QMessageBox::question(this,"question","你是否要清空聊天记录");

if(result==QMessageBox::Yes)

{

cmd="SClear";

QString text=cmd.append("\n").append(name).append("\n").append("b");

//创建文本流对象

QTextStream output(client);

output<

ui->textBrowser->clear();

}

}

//关闭历史记录显示

void MyDialog::btnCloseDpClieckedSlot()

{

ui->textBrowser->clear();

}

7)sendthread.cpp文件

#include "sendthread.h"

SendThread::SendThread(QTcpSocket *client,QString readpth,QObject *parent) :

QThread(parent)

{

this->client=client;

this->readpth=readpth;

}

void SendThread::run()

{

qDebug()<<"子线程run函数";

QFile readFile(readpth);

readFile.open(QIODevice::ReadOnly);

qint64 totalSize=readFile.size();

qint64 hasRead=0;

int lastper=0;

QByteArray buffer;

while(!readFile.atEnd())

{

buffer=readFile.read(1024);

//qDebug()<

hasRead+=client->write(buffer);

int per=hasRead*100/totalSize;

if(per!=lastper)

{

emit sendValueSignal(per);

lastper=per;

}

}

//收尾

readFile.flush();//清空读缓存区

readFile.close();//关闭

}

8)ui文件

登录界面设计

主界面

3.2服务器端

1).pro文件

一定要加上sql(数据库模块)和network(网络模块)

#-------------------------------------------------

#

# Project created by QtCreator 2023-07-22T09:02:38

#

#-------------------------------------------------

QT += core gui network sql

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

TARGET = UdpChatMyServer

TEMPLATE = app

SOURCES += main.cpp\

dialog.cpp \

resivethread.cpp

HEADERS += dialog.h \

resivethread.h

FORMS += dialog.ui

QMAKE_CXXFLAGS += -std=c++11

RESOURCES += \

res.qrc

OTHER_FILES += \

icoConfig.rc

RC_FILE += icoConfig.rc

2)dialog.h

#ifndef DIALOG_H

#define DIALOG_H

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include"resivethread.h"

#include

#include

namespace Ui {

class Dialog;

}

class Dialog : public QDialog

{

Q_OBJECT

public:

explicit Dialog(QWidget *parent = 0);

~Dialog();

private:

Ui::Dialog *ui;

QTcpServer *server;//服务器管理类对象

QList clients;//连接类容器对象

QTcpSocket *socket;//一个新连接对象

QSqlDatabase db; //数据库对象

void connect2DB(); //连接数据库

void createTable(); //建表

void insertResgisterData(QString,QString); //插入注册表

void insertLongonData(QString,QString,quint16); //插入登录表

void insertHisQData(QString,QString,QString); //插入群历史聊天记录表

void insertHisSData(QString name,QString resiveuser,QString msg,QString time);//插入私聊记录表

void deleteRegisterUser(QString name);//删除注册信息

void deleteHistorySChat(QString name);//删除私聊历史记录

void creatFolder(); //创建目录

void sendFolderContent(QString folderpath);//发送文件列表给客户端

void resiveFile(QString writeFilename,QString ip);

void selectChatUsr(); //查在已注册的用户

private slots:

void newConnSlot();//新链接来了

void disconntedSlot();//链接断开

void readyreadSlot();//接受数据

void readyreadResgisterSlot(QString,QString);//注册

void readyreadLogonSlot(QString,QString);//登录

int isDataRNamePwdExists(QString,QString);//查注册表

int isDataLNameIpPortExists(QString,QString,quint16);//查登录表

void updateData(QString name,QString ip,quint16 port);//更新登录表

void readreadChatQSlot(QString,QString);//聊天(群里)

void readreadHisQSlot(); //查询历史记录表

int isDataLNameIpPortExistsS(QString name,QString& ip,quint16& port);//私聊专用查登录表(需要用到参数返回接受者的ip和端口)

void readreadChatSSlot(QString,QString,QString); //私聊

void readreadHisSSlot(QString name); //查询私聊历史记录表

// void resiveFile(QString writeFilename,QString ip);

void fileWriteFinishSlot();

};

#endif // DIALOG_H

3)resivethread.h

#ifndef RESIVETHREAD_H

#define RESIVETHREAD_H

#include

#include

#include

#include

#include

#include

#include

#include

class ResiveThread : public QThread

{

Q_OBJECT

public:

explicit ResiveThread(QTcpSocket *client,QString,QObject *parent = 0);

protected:

void run();

private:

QTcpSocket *client;

int port;

QString resivename; //接受文件路径

signals:

void fileWriteFinish();

public slots:

};

#endif // RESIVETHREAD_H

  • 斧钺森森显威仪——中国古代长兵器之斧钺
Copyright © 2088 橄榄球世界杯_1990世界杯阿根廷 - liuweiqing95511.com All Rights Reserved.
友情链接