• 基于qt软件的网上聊天室软件


    1.服务器:

            1).功能:

    用于创建一个客户端,通过文本编辑器来获得端口号,根据获得的端口号创建服务器,等待客户端连接

    创建成功会提示服务器创建成功

    在收到客户端发送的信息时,把这条信息发送给其他所有客户端,实现群聊功能

            2).代码:

    1. -------------------------------------------------------------------
    2. .pro
    3. -------------------------------------------------------------------
    4. QT += core gui network
    5. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    6. CONFIG += c++11
    7. # The following define makes your compiler emit warnings if you use
    8. # any Qt feature that has been marked deprecated (the exact warnings
    9. # depend on your compiler). Please consult the documentation of the
    10. # deprecated API in order to know how to port your code away from it.
    11. DEFINES += QT_DEPRECATED_WARNINGS
    12. # You can also make your code fail to compile if it uses deprecated APIs.
    13. # In order to do so, uncomment the following line.
    14. # You can also select to disable deprecated APIs only up to a certain version of Qt.
    15. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
    16. SOURCES += \
    17. main.cpp \
    18. widget.cpp
    19. HEADERS += \
    20. widget.h
    21. FORMS += \
    22. widget.ui
    23. # Default rules for deployment.
    24. qnx: target.path = /tmp/$${TARGET}/bin
    25. else: unix:!android: target.path = /opt/$${TARGET}/bin
    26. !isEmpty(target.path): INSTALLS += target
    27. -------------------------------------------------------------------
    28. widget.h
    29. -------------------------------------------------------------------
    30. #ifndef WIDGET_H
    31. #define WIDGET_H
    32. #include
    33. #include
    34. #include
    35. #include
    36. #include
    37. #include
    38. #include
    39. #include
    40. #include
    41. QT_BEGIN_NAMESPACE
    42. namespace Ui { class Widget; }
    43. QT_END_NAMESPACE
    44. class Widget : public QWidget
    45. {
    46. Q_OBJECT
    47. public:
    48. Widget(QWidget *parent = nullptr);
    49. ~Widget();
    50. public slots:
    51. void connectbtn_slot();
    52. void connected_slot();
    53. void readyread_slot();
    54. private:
    55. Ui::Widget *ui;
    56. //定义服务器
    57. QTcpServer *server;
    58. //定义一个链表存放连接的客户端数据
    59. QList client;
    60. };
    61. #endif // WIDGET_H
    62. -------------------------------------------------------------------
    63. main.cpp
    64. -------------------------------------------------------------------
    65. #include "widget.h"
    66. #include
    67. int main(int argc, char *argv[])
    68. {
    69. QApplication a(argc, argv);
    70. Widget w;
    71. w.show();
    72. return a.exec();
    73. }
    74. -------------------------------------------------------------------
    75. widget.cpp
    76. -------------------------------------------------------------------
    77. #include "widget.h"
    78. #include "ui_widget.h"
    79. Widget::Widget(QWidget *parent)
    80. : QWidget(parent)
    81. , ui(new Ui::Widget)
    82. {
    83. ui->setupUi(this);
    84. //实例化服务器
    85. server = new QTcpServer(this);
    86. //连接按钮与对应槽函数
    87. connect(ui->connectbtn,&QPushButton::clicked,this,&Widget::connectbtn_slot);
    88. }
    89. Widget::~Widget()
    90. {
    91. delete ui;
    92. }
    93. //按下按钮后启动服务器
    94. void Widget::connectbtn_slot()
    95. {
    96. //读取端口号
    97. quint16 port = ui->portedit->text().toInt();
    98. //设置为监听状态
    99. if(!server->listen(QHostAddress::Any,port))
    100. {
    101. QMessageBox::critical(this,"失败","服务器启动失败");
    102. return ;
    103. }
    104. QMessageBox::information(this,"成功","服务器启动成功");
    105. //连接客户端信号与槽函数
    106. connect(server,&QTcpServer::newConnection,this,&Widget::connected_slot);
    107. }
    108. //客户端连接槽函数
    109. void Widget::connected_slot()
    110. {
    111. //获取客户端套接字
    112. QTcpSocket *cli = server->nextPendingConnection();
    113. //将得到的套接字写入链表
    114. client.push_back(cli);
    115. //把新套接字与接收信号连接
    116. connect(cli,&QTcpSocket::readyRead,this,&Widget::readyread_slot);
    117. }
    118. //有信息写入准备读取
    119. void Widget::readyread_slot()
    120. {
    121. //删除已经断开的客户端
    122. for(int i = 0;i < client.size();i++)
    123. {
    124. if(client.at(i)->state() == 0)
    125. {
    126. client.removeAt(i);
    127. }
    128. }
    129. //遍历发送数据的客户端
    130. for(int i = 0;i < client.size();i++)
    131. {
    132. if(client.at(i)->bytesAvailable() != 0)
    133. {
    134. //读取客户端数据
    135. QByteArray msg = client.at(i)->readAll();
    136. //将数据写到ui界面中
    137. ui->listWidget->addItem(QString::fromLocal8Bit(msg));
    138. //将数据发送给所有客户端
    139. for(int j = 0;j < client.size();j++)
    140. {
    141. client.at(j)->write(msg);
    142. }
    143. }
    144. }
    145. }

    2.客户端:

    登陆界面 :

            1).功能:

    输入账号密码,如果点击注册按钮,会将输入的账号密码存入数据库中

    且对输入的账号密码进行判断(没输入账号会提示请输入账号,没输入密码会提示请输入密码),输入的账号不能重复,但是密码可以重复;

    如果点击登录按钮,会读取数据库中注册的账号密码,与输入的账号密码进行对比,

    如果一致则提示登录成功并跳转到聊天室界面,如果在数据库中找不到账号则提示账号不存在,如果存在账号但是密码不正确,则输出密码错误

            2).代码:

    1. -------------------------------------------------------------------
    2. .pro
    3. -------------------------------------------------------------------
    4. QT += core gui network sql
    5. greaterThan(QT_MAJOR_VERSION, 4): QT += widgets
    6. CONFIG += c++11
    7. # The following define makes your compiler emit warnings if you use
    8. # any Qt feature that has been marked deprecated (the exact warnings
    9. # depend on your compiler). Please consult the documentation of the
    10. # deprecated API in order to know how to port your code away from it.
    11. DEFINES += QT_DEPRECATED_WARNINGS
    12. # You can also make your code fail to compile if it uses deprecated APIs.
    13. # In order to do so, uncomment the following line.
    14. # You can also select to disable deprecated APIs only up to a certain version of Qt.
    15. #DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
    16. SOURCES += \
    17. chat.cpp \
    18. main.cpp \
    19. widget.cpp
    20. HEADERS += \
    21. chat.h \
    22. widget.h
    23. # Default rules for deployment.
    24. qnx: target.path = /tmp/$${TARGET}/bin
    25. else: unix:!android: target.path = /opt/$${TARGET}/bin
    26. !isEmpty(target.path): INSTALLS += target
    27. RESOURCES += \
    28. Icon.qrc
    29. FORMS += \
    30. chat.ui
    31. -------------------------------------------------------------------
    32. widget.h
    33. -------------------------------------------------------------------
    34. #ifndef WIDGET_H
    35. #define WIDGET_H
    36. #include
    37. #include
    38. #include
    39. #include
    40. #include
    41. #include
    42. #include
    43. #include
    44. #include
    45. class Widget : public QWidget
    46. {
    47. Q_OBJECT
    48. public:
    49. Widget(QWidget *parent = nullptr);
    50. ~Widget();
    51. signals:
    52. void loginsuccess_signal(QString account);
    53. public slots:
    54. void loginbtn_slot();
    55. void signinbtn_slot();
    56. private:
    57. //组件
    58. QPushButton *login_btn;
    59. QPushButton *signin_btn;
    60. QLineEdit *account_edit;
    61. QLineEdit *pwd_edit;
    62. QLabel *main_lab;
    63. QLabel *account_lab;
    64. QLabel *pwd_lab;
    65. //数据库初始化
    66. QSqlDatabase db;
    67. };
    68. #endif // WIDGET_H
    69. -------------------------------------------------------------------
    70. main.cpp
    71. -------------------------------------------------------------------
    72. #include "widget.h"
    73. #include "chat.h"
    74. #include
    75. int main(int argc, char *argv[])
    76. {
    77. QApplication a(argc, argv);
    78. Widget w;
    79. chat c;
    80. w.show();
    81. QObject::connect(&w,&Widget::loginsuccess_signal,&c,&chat::openchatroom_slot);
    82. return a.exec();
    83. }
    84. -------------------------------------------------------------------
    85. widget.cpp
    86. -------------------------------------------------------------------
    87. #include "widget.h"
    88. Widget::Widget(QWidget *parent)
    89. : QWidget(parent)
    90. {
    91. //---------------------------------窗口设置---------------------------------
    92. //设置窗口为固定大小
    93. this->setFixedSize(540,410);
    94. //设置窗口icon
    95. this->setWindowIcon(QIcon(":/icon/wodepeizhenshi.png"));
    96. //设置窗口名
    97. this->setWindowTitle("鹏哥快聊");
    98. //---------------------------------标签设置---------------------------------
    99. //=====创建界面标签=====
    100. main_lab = new QLabel(this);
    101. //修改标签大小
    102. main_lab->resize(540,200);
    103. //在标签中插入图片
    104. main_lab->setPixmap(QPixmap(":/icon/logo.png"));
    105. //设置为自适应
    106. main_lab->setScaledContents(1);
    107. //=====创建账号标签=====
    108. account_lab = new QLabel(this);
    109. //修改标签大小
    110. account_lab->resize(50,40);
    111. //在标签中插入图片
    112. account_lab->setPixmap(QPixmap(":/icon/userName.jpg"));
    113. //移动到合适位置
    114. account_lab->move(90,220);
    115. //设置为自适应
    116. account_lab->setScaledContents(1);
    117. //=====创建密码标签=====
    118. pwd_lab = new QLabel(this);
    119. //修改标签大小
    120. pwd_lab->resize(account_lab->size());
    121. //在标签中插入图片
    122. pwd_lab->setPixmap(QPixmap(":/icon/passwd.jpg"));
    123. //移动到合适位置
    124. pwd_lab->move(account_lab->x(),account_lab->y()+80);
    125. //设置为自适应
    126. pwd_lab->setScaledContents(1);
    127. //---------------------------------按钮设置---------------------------------
    128. //=====创建登录按钮=====
    129. login_btn = new QPushButton(this);
    130. //设置按钮大小
    131. login_btn->resize(100,40);
    132. //在按钮上插入图片
    133. login_btn->setIcon(QIcon(":/icon/login.png"));
    134. //在按钮上输入文本
    135. login_btn->setText("登录");
    136. //移动到合适位置
    137. login_btn->move(270,360);
    138. connect(login_btn,&QPushButton::clicked,this,&Widget::loginbtn_slot);
    139. //=====创建注册按钮=====
    140. signin_btn = new QPushButton(this);
    141. //设置按钮大小
    142. signin_btn->resize(100,40);
    143. //在按钮上插入图片
    144. signin_btn->setIcon(QIcon(":/icon/cancel.png"));
    145. //在按钮上输入文本
    146. signin_btn->setText("注册");
    147. //移动到合适位置
    148. signin_btn->move(login_btn->x()+120,login_btn->y());
    149. connect(signin_btn,&QPushButton::clicked,this,&Widget::signinbtn_slot);
    150. //---------------------------------输入设置---------------------------------
    151. //=====创建账号输入=====
    152. account_edit = new QLineEdit(this);
    153. //设置占位文本
    154. account_edit->setPlaceholderText("QQ号码/手机/邮箱");
    155. //设置大小
    156. account_edit->resize(200,40);
    157. //移动到适合位置
    158. account_edit->move(account_lab->x()+100,account_lab->y());
    159. //=====创建密码输入=====
    160. pwd_edit = new QLineEdit(this);
    161. //设置占位文本
    162. pwd_edit->setPlaceholderText("密码");
    163. //设置大小
    164. pwd_edit->resize(account_edit->size());
    165. //移动到合适位置
    166. pwd_edit->move(pwd_lab->x()+100,pwd_lab->y());
    167. //设置回文显示模式
    168. pwd_edit->setEchoMode(QLineEdit::Password);
    169. //--------------------------------数据库设置--------------------------------
    170. //判断数据库是否存在
    171. if(!db.contains("user.db"))
    172. {
    173. //不存在
    174. //创建一个数据库
    175. db = QSqlDatabase::addDatabase("QSQLITE");
    176. //命名为user.db
    177. db.setDatabaseName("user.db");
    178. }
    179. //存在
    180. //打开数据库
    181. if(!db.open())
    182. {
    183. //打开失败
    184. QMessageBox::critical(this,"error","数据库打开失败");
    185. return;
    186. }
    187. //打开成功
    188. //创建一个表
    189. //准备sql语句
    190. QString sql = "create table if not exists usertab("
    191. "account char primary key,"
    192. "passwd char)";
    193. //创建一个数据库指令执行者
    194. QSqlQuery commend;
    195. //执行sql语句
    196. if(!commend.exec(sql))
    197. {
    198. //创建表失败
    199. QMessageBox::critical(this,"error","表格创建失败");
    200. return;
    201. }
    202. }
    203. Widget::~Widget()
    204. {
    205. }
    206. //登录按钮槽函数
    207. void Widget::loginbtn_slot()
    208. {
    209. //获取账号和密码
    210. QString account = account_edit->text();
    211. QString passwd = pwd_edit->text();
    212. //从数据库中读取账号和密码
    213. QString sql = "select * from usertab";
    214. //创建执行者并执行sql语句
    215. QSqlQuery commend;
    216. if(!commend.exec(sql))
    217. {
    218. //查找失败
    219. QMessageBox::critical(this,"error","获取注册表失败");
    220. return;
    221. }
    222. //查找成功,循环比较数据库信息与输入的信息
    223. while (commend.next())
    224. {
    225. if(commend.value(0).toString() == account)
    226. {
    227. //账号正确
    228. if(commend.value(1).toString() == passwd)
    229. {
    230. QMessageBox::information(this,"success","登录成功");
    231. emit loginsuccess_signal(account);
    232. this->close();
    233. return;
    234. }
    235. //密码错误
    236. QMessageBox::critical(this,"failed","登录失败,密码错误");
    237. pwd_edit->clear();
    238. return;
    239. }
    240. }
    241. //账号错误
    242. QMessageBox::critical(this,"failed","登录失败,账号不存在");
    243. pwd_edit->clear();
    244. }
    245. //注册按钮槽函数
    246. void Widget::signinbtn_slot()
    247. {
    248. //判断是否填写完整信息
    249. if(account_edit->text() == "")
    250. {
    251. QMessageBox::critical(this,"error","请输入账号");
    252. return;
    253. }
    254. if(pwd_edit->text() == "")
    255. {
    256. QMessageBox::critical(this,"error","请输入密码");
    257. return;
    258. }
    259. //获取界面上的账号和密码
    260. QString account = account_edit->text();
    261. QString passwd = pwd_edit->text();
    262. //将注册的账号密码写入数据库中
    263. //准备sql语句
    264. QString sql = QString("insert into usertab values(\"%1\",\"%2\")")
    265. .arg(account).arg(passwd);
    266. //创建执行者并执行sql语句
    267. QSqlQuery commend;
    268. if(!commend.exec(sql))
    269. {
    270. //注册失败,账号重复
    271. QMessageBox::critical(this,"error","重复注册");
    272. return;
    273. }
    274. //注册成功
    275. QMessageBox::information(this,"success","注册成功");
    276. }

    聊天室界面:

            1).功能:

    进入时,显示登录时的账号,且发送按钮、断开按钮和发送的文本编辑器不可用

    通过主机的IP和端口号进行连接至主机后,给服务器发送xxx : 进入聊天室,发送按钮、断开按钮和发送的文本编辑器重新可用,使IP和端口号的文本编辑器以及连接聊天室按钮不可用

    在发送的文本编辑器中写入信息并按下发送按钮后,会整合发送信息然后发送信息给服务器,发送后清空文本内容,

    点击断开聊天室按钮,重新使发送按钮、断开按钮和发送的文本编辑器不可用,使IP和端口号的文本编辑器以及连接聊天室按钮可用

    并会给服务器发送一条xxx : 离开聊天室的信息

            2).代码:

    1. -------------------------------------------------------------------
    2. chat.h
    3. -------------------------------------------------------------------
    4. #ifndef CHAT_H
    5. #define CHAT_H
    6. #include
    7. #include
    8. #include
    9. #include
    10. #include
    11. #include
    12. #include
    13. namespace Ui {
    14. class chat;
    15. }
    16. class chat : public QWidget
    17. {
    18. Q_OBJECT
    19. public:
    20. explicit chat(QWidget *parent = nullptr);
    21. ~chat();
    22. public slots:
    23. void openchatroom_slot(QString account);
    24. void connectbtn_slot();
    25. void connected_slot();
    26. void readyread_slot();
    27. void sndbtn_slot();
    28. void disconbtn_slot();
    29. void disconnect_slot();
    30. private:
    31. Ui::chat *ui;
    32. //定义一个客户端套接字
    33. QTcpSocket *client;
    34. //定义一个用户名
    35. QString username;
    36. };
    37. #endif // CHAT_H
    38. -------------------------------------------------------------------
    39. chat.cpp
    40. -------------------------------------------------------------------
    41. #include "chat.h"
    42. #include "ui_chat.h"
    43. chat::chat(QWidget *parent) :
    44. QWidget(parent),
    45. ui(new Ui::chat)
    46. {
    47. //将用户名居中显示
    48. //ui->usernamelab_2->setAlignment(Qt::AlignCenter);
    49. ui->setupUi(this);
    50. //为客户端套接字实例化空间
    51. client = new QTcpSocket(this);
    52. //连接按钮与对应槽函数连接
    53. connect(ui->connectbtn,&QPushButton::clicked,this,&chat::connectbtn_slot);
    54. //已连接信号与对应槽函数连接
    55. connect(client,&QTcpSocket::connected,this,&chat::connected_slot);
    56. //服务器发送信息信号与对应槽函数连接
    57. connect(client,&QTcpSocket::readyRead,this,&chat::readyread_slot);
    58. //发送按钮与对应槽函数连接
    59. connect(ui->sndbtn,&QPushButton::clicked,this,&chat::sndbtn_slot);
    60. //断开按钮与对应槽函数
    61. connect(ui->disconbtn,&QPushButton::clicked,this,&chat::disconbtn_slot);
    62. //断开连接信号与对应槽函数
    63. connect(client,&QTcpSocket::disconnected,this,&chat::disconnect_slot);
    64. //设置按钮与编辑框可用
    65. ui->disconbtn->setEnabled(0);
    66. ui->sndbtn->setEnabled(0);
    67. ui->msgedit->setEnabled(0);
    68. }
    69. chat::~chat()
    70. {
    71. delete ui;
    72. }
    73. void chat::openchatroom_slot(QString account)
    74. {
    75. username = account;
    76. qDebug() << account;
    77. qDebug() << username;
    78. ui->usernamelab_2->setText(username);
    79. this->show();
    80. }
    81. //连接按钮槽函数
    82. void chat::connectbtn_slot()
    83. {
    84. //从ui界面读取IP与port
    85. QString IP = ui->IPedit->text();
    86. quint16 port = ui->portedit->text().toUInt();
    87. //连接服务器
    88. client->connectToHost(IP,port);
    89. }
    90. //已连接槽函数
    91. void chat::connected_slot()
    92. {
    93. //连接完成提示信息
    94. QMessageBox::information(this,"成功","成功进入聊天室");
    95. //发送xx进入聊天室提示给服务器
    96. QString sndmsg = username + " : 进入聊天室";
    97. client->write(sndmsg.toLocal8Bit());
    98. //设置按钮与编辑框可用
    99. ui->IPedit->setEnabled(0);
    100. ui->portedit->setEnabled(0);
    101. ui->connectbtn->setEnabled(0);
    102. ui->sndbtn->setEnabled(1);
    103. ui->msgedit->setEnabled(1);
    104. ui->disconbtn->setEnabled(1);
    105. }
    106. //读取服务器发送信息
    107. void chat::readyread_slot()
    108. {
    109. //读取信息
    110. QByteArray msg = client->readAll();
    111. //将读取的信息发送到信息框内
    112. ui->listWidget->addItem(QString::fromLocal8Bit(msg));
    113. }
    114. //发送按钮对应槽函数
    115. void chat::sndbtn_slot()
    116. {
    117. //读取ui界面发送框内信息
    118. QString msg = ui->msgedit->text();
    119. msg = username + " : " + msg;
    120. //将数据发送给服务器
    121. client->write(msg.toLocal8Bit());
    122. ui->msgedit->clear();
    123. }
    124. //断开连接按钮对应槽函数
    125. void chat::disconbtn_slot()
    126. {
    127. //准备发送离开信息
    128. QString msg = username + " : 离开聊天室";
    129. client->write(msg.toLocal8Bit());
    130. //断开连接
    131. client->disconnectFromHost();
    132. }
    133. //断开连接信号槽函数
    134. void chat::disconnect_slot()
    135. {
    136. QMessageBox::information(this,"断开连接","成功退出聊天室");
    137. //设置按钮与编辑框可用
    138. ui->IPedit->setEnabled(1);
    139. ui->portedit->setEnabled(1);
    140. ui->connectbtn->setEnabled(1);
    141. ui->disconbtn->setEnabled(0);
    142. ui->sndbtn->setEnabled(0);
    143. ui->msgedit->setEnabled(0);
    144. }

  • 相关阅读:
    java 批量更改
    GET,POST,PUT,DELETE
    极限多标签分类-评价指标
    并行多核体系结构基础 Yan Solihin 第4章 针对链式数据结构的并行 摘录
    ZGC关键技术分析
    Jmeter接口自动化生成测试报告html格式
    第十届MathorCup高校数学建模挑战赛-A题:无车承运人平台线路定价问题
    PyTorch入门学习(十一):神经网络-线性层及其他层介绍
    文本自动粘贴编辑器:支持自动粘贴并筛选手机号码,让信息处理更轻松
    浅谈java中的String
  • 原文地址:https://blog.csdn.net/m0_64146298/article/details/132722887