Qt 0821作业

一、思维导图

二、优化聊天室代码

服务器 头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>
#include <QMessageBox>
#include <QTcpSocket>
#include <QList>
#include <QNetworkInterface>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();public slots:void newConnection_slot();void readyRead_slot();private slots:void on_startBtn_clicked();private:Ui::Widget *ui;QTcpServer *server; //实例化服务器对象QList<QTcpSocket *> socketList; //定义容器存放客户端
};
#endif // WIDGET_H

服务器源文件

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), server(new QTcpServer(this))
{ui->setupUi(this);QString ip_address;QList<QHostAddress> ipAddressesList = QNetworkInterface::allAddresses(); //获取所有ipfor(int i = 0; i < ipAddressesList.size(); i++){QHostAddress ipAddr = ipAddressesList.at(i);if(ipAddr.protocol() == QAbstractSocket::IPv4Protocol){  //筛选ipv4if(!ipAddr.toString().startsWith("169")){   //过滤网卡、路由器ipip_address = ipAddr.toString();break;}}}if(ip_address.isEmpty()){ip_address = QHostAddress(QHostAddress::LocalHost).toString();}ui->ipNetLab->setText(ip_address);
}Widget::~Widget()
{delete ui;
}void Widget::newConnection_slot()
{//newConnection信号对应槽函数//获取套接字QTcpSocket *s = server->nextPendingConnection();socketList.push_back(s);    //尾插connect(s, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);
}void Widget::readyRead_slot()
{//readyRead信号对应槽函数//读取数据for(int i = 0; i < socketList.count(); i++){if(socketList.at(i)->state() == 0){//移除无效客户端socketList.removeAt(i);}}for(int i = 0; i < socketList.count(); i++){if(socketList.at(i)->bytesAvailable() != 0){//读取有待读数据QByteArray msg = socketList.at(i)->readAll();ui->listWidget->addItem(QString::fromLocal8Bit(msg));//广播给所有客户端for(int j = 0; j < socketList.count(); j++){socketList.at(j)->write(msg);}}}
}void Widget::on_startBtn_clicked()
{//启动//获取端口号quint16 port = ui->portEdit->text().toUInt();//设置监听if(server->listen(QHostAddress::Any, port)){QMessageBox::information(this, "", "启动服务器成功");} else {QMessageBox::warning(this, "", "启动服务器失败");return;}connect(server, &QTcpServer::newConnection, this, &Widget::newConnection_slot);
}

客户端头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpSocket>
#include <QMessageBox>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic slots:void connected_slot();      //connected()信号void readyRead_slot();      //readyRead()信号void disconnected_slot();   //disconnected()信号public:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_connectBtn_clicked();void on_sendBtn_clicked();void on_disconnectBtn_clicked();private:Ui::Widget *ui;QTcpSocket *socket;     //实例化一个客户端指针对象QString userName;       //定义一个存储用户信息的变量
};
#endif // WIDGET_H

客户端源文件

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget), socket(new QTcpSocket(this))
{ui->setupUi(this);//初始化界面ui->msgEdit->setEnabled(false);ui->sendBtn->setEnabled(false);ui->disconnectBtn->setEnabled(false);//客户端连接服务器connect(socket, &QTcpSocket::connected, this, &Widget::connected_slot);//接收数据connect(socket, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);//断开连接connect(socket, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
}Widget::~Widget()
{delete ui;
}void Widget::on_connectBtn_clicked()
{//连接按钮对应槽函数//获取ip和portQString ip = ui->ipEdit->text();quint16 port = ui->portEdit->text().toUInt();//客户端连接服务器socket->connectToHost(ip, port);
}void Widget::connected_slot()
{userName = ui->userNameEdit->text();QString msg = userName + " 进入聊天室";//将信息发送到服务器socket->write(msg.toLocal8Bit());//连接服务器成功QMessageBox::information(this, "提示", "链接服务器成功", QMessageBox::Ok);//组件可用的相关设置ui->msgEdit->setEnabled(true);ui->sendBtn->setEnabled(true);ui->disconnectBtn->setEnabled(true);ui->userNameEdit->setEnabled(false);ui->ipEdit->setEnabled(false);ui->portEdit->setEnabled(false);ui->connectBtn->setEnabled(false);
}void Widget::readyRead_slot()
{//读取服务器发来的数据QByteArray msg = socket->readAll();QString s = QString::fromLocal8Bit(msg);//截取用户名QString user_Name = s.mid(0, userName.size());if(user_Name == userName){if(s.mid(userName.size(), 1) == " "){QListWidgetItem *item = new QListWidgetItem(s);item->setTextAlignment(Qt::AlignCenter);ui->listWidget->addItem(item);}else{//如果是本机用户则右对齐QListWidgetItem *item = new QListWidgetItem(s);item->setTextAlignment(Qt::AlignRight);ui->listWidget->addItem(item);}}else{//将数据放入ui界面上ui->listWidget->addItem(QString::fromLocal8Bit(msg));}}void Widget::disconnected_slot()
{//组件可用的相关设置ui->msgEdit->setEnabled(false);ui->sendBtn->setEnabled(false);ui->disconnectBtn->setEnabled(false);ui->userNameEdit->setEnabled(true);ui->ipEdit->setEnabled(true);ui->portEdit->setEnabled(true);ui->connectBtn->setEnabled(true);
}void Widget::on_disconnectBtn_clicked()
{//发送断开信息给服务器QString msg = userName + " 离开聊天室";//发送给服务器socket->write(msg.toLocal8Bit());//断开与服务器的连接socket->disconnectFromHost();
}void Widget::on_sendBtn_clicked()
{//获取ui界面的信息QString msg = ui->msgEdit->toPlainText();msg = userName + ": " + msg;//发送给服务器socket->write(msg.toLocal8Bit());//清空编辑器ui->msgEdit->clear();
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/52364.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

系统编程-lvgl

带界面的MP3播放器 -- lvgl 目录 带界面的MP3播放器 -- lvgl 一、什么是lvgl&#xff1f; 二、简单使用lvgl 在工程中编写代码 实现带界面的mp3播放器 main.c events_init.c events_init.h 补充1&#xff1a;glob函数 补充2&#xff1a;atexit函数 一、什么是lvgl&a…

Axios 中的相关参数

在 Axios 中&#xff0c;发起 HTTP 请求时你可以使用多种参数来配置请求的行为。以下是一些主要的参数&#xff1a; 1. url 描述&#xff1a;请求的 URL。示例&#xff1a;axios.get(/api/users) 2. method 描述&#xff1a;HTTP 请求的方法&#xff0c;可以是 GET, POST, …

通过C# 读取PDF页面大小、方向、旋转角度

在处理PDF文件时&#xff0c;了解页面的大小、方向和旋转角度等信息对于PDF的显示、打印和布局设计至关重要。本文将介绍如何使用免费.NET 库通过C#来读取PDF页面的这些属性。 文章目录 C# 读取PDF页面大小&#xff08;宽度、高度&#xff09;C# 判断PDF页面方向C# 检测PDF页面…

31套科技风PPT模版免费下载

目录 资源名称&#xff1a;31套科技风PPT模板合集资源简介&#xff1a;部分展示&#xff1a;适用人群&#xff1a;资源内容&#xff1a;使用指南&#xff1a;资源下载链接&#xff08;免费&#xff0c;已设置0个积分下载&#xff09; 资源名称&#xff1a;31套科技风PPT模板合集…

Spring + Boot + Cloud + JDK8 + Elasticsearch 单节点 模式下实现全文检索高亮-分页显示 快速入门案例

1. 安装elasticsearchik分词器插件 sudo wget https://release.infinilabs.com/analysis-ik/stable/elasticsearch-analysis-ik-8.13.4.zip sudo mkdir -p ./es_plugins/analysis-ik sudo mkdir ./es_data sudo unzip elasticsearch-analysis-ik-8.13.4.zip -d ./es_plugins/a…

7-zip常见问题

7-Zip作为一款广受欢迎的免费压缩工具&#xff0c;以其高效、稳定的特点赢得了众多用户的青睐。然而&#xff0c;在使用过程中&#xff0c;用户也可能会遇到一些常见问题。以下是一些常见问题及其解决方法&#xff1a; 一、无法打开压缩文件 问题描述&#xff1a; 用户尝试打…

WIFI 频段及信道简介

一、WiFi 三频AP规划信道时&#xff0c;建议分别采用2.4G、5.2G、5.8G频段可用信道。 2.4G频段&#xff1b;5.2G频段&#xff1b;5.8G频段。 1、中国5G WiFi频段 5.8GHz频段&#xff0c;中国开放只有149、153、157、161、165这5个信道&#xff1b; 其中可支持一组80MHz信道…

【ACM出版,高录用EI快检索】第七届计算机信息科学与人工智能国际学术会议(CISAI 2024,9月6-8)

第七届计算机信息科学与人工智能国际学术会议(CISAI 2024) 将于2024年09月6-8日在中国浙江-绍兴举行。 计算机信息科学与人工智能国际学术会议的主题主要围绕“信息科学”与“人工智能”的最新研究展开&#xff0c;旨在荟聚世界各地该领域的专家、学者、研究人员及相关从业人员…

C++—八股文总结(25秋招期间一直更新)

1、const 1.1 指针常量和常量指针 说说const int *a, int const *a, const int a, int *const a, const int *const a分别是什么&#xff0c;有什么特点。 const int *aint const *a; //可以通过 a 访问整数值&#xff0c;但不能通过 a 修改该整数的值&#xff0c;指针本身是…

前端工作常用知识

1. JS为什么单线程 一个简单的原因就是&#xff0c;js在设计之初只是进行一些简单的表单校验&#xff0c;这完全不需要多线程&#xff0c;单线程完全可以胜任这项工作。即便后来前端发展迅速&#xff0c;承载的能力越来越多&#xff0c;也没有发展到非多线程不可的程度。 而且…

Rustrover、IDEA 的 Rust 类型不显示(已解决)

关键词&#xff1a;rustrover 类型不显示&#xff0c;rustrover 不显示类型&#xff0c;IntelliJ IDEA Rust 类型不显示&#xff0c;IntelliJ IDEA Rust 不显示类型 若移动端访问不佳&#xff0c;请使用 –> Github版 背景 博主手欠&#xff0c;使用 IntelliJ IDEA 时&am…

教程:如何搜索社交媒体

文章目录 一、使用 Python 搜索 Telegram1.1. 第 1 步 - 设置代理1.2. 第 2 步 - 安装 Telethon 库1.3. 第 3 步 - 创建数据库文件并登录1.4. 第 4 步 - 创建结果列表1.5. 第 5 步 - 选择要搜索成员的组1.6. 第 6 步 - 导出所有成员的详细信息1.7. 第 7 步 - 将导出的数据存储到…

mysql中出现错误1138-Invalid use of NULL value

问题&#xff1a;1138-Invalid use of NULL value 解决&#xff1a; 问题是当前字段中&#xff0c;有null的值&#xff0c;简单来说就是&#xff0c;你表里有空值&#xff0c;不能设置不为空&#xff01;&#xff01;&#xff01; 把空的值删掉重新设计就好了

LaTex插入图片

LaTeX 提供了许多定制化图片的功能。这篇文章将会介绍如何用最常见的格式插入图片、缩放图片以及如何在文档中引用这些图片。 1.基本使用 效果图如图所示。 \documentclass{article} \usepackage{graphicx} \graphicspath{ {./figure/} }\begin{document}\begin{figure}[!t]…

大数据环境下的数据提取挑战

在大数据环境下&#xff0c;数据提取面临着多方面的挑战。这些挑战不仅源于数据本身的特性和复杂性&#xff0c;还涉及到技术、资源、法律等多个层面。以下是对这些挑战的具体分析&#xff1a; 1. 数据质量与准确性 数据质量问题&#xff1a;大数据环境下&#xff0c;数据来源…

JUC-Synchronized原理进阶

轻量级锁 轻量级锁的使用场景&#xff1a;如果一个对象虽然有多线程要加锁&#xff0c;但加锁的时间是错开的&#xff08;也就是没有竞争&#xff09;&#xff0c;那么可以使用轻量级锁来优化。轻量级锁对使用者是透明的&#xff0c;即语法仍然是 synchronized 假设有两个方法同…

opencv处理图片(实战指南)

一、OpenCV简介 OpenCV&#xff08;Open Source Computer Vision Library&#xff09;是一个开源的计算机视觉和机器学习软件库。它拥有众多的图像处理和计算机视觉功能&#xff0c;包括各种常用的图像处理技术&#xff0c;如滤波、边缘检测、特征提取等。OpenCV支持多种编程语…

UDP 和TCP的应用

一、网络模型 &#xff08;一&#xff09;C/S 模型 客户端 / 服务器&#xff08;Client/Server&#xff0c;C/S&#xff09;模型是一种常见的网络架构。在这种模型中&#xff0c;客户端是主动的角色&#xff0c;向服务器发起请求&#xff1b;服务器端是被动的角色&#xff0c;…

electron-vite封装UI级的消息提示

说明 Electron Vite Vue3 Element Plus Electron中写提示有两种方案&#xff1a; 系统级&#xff1a;electron带的dialog相关APIUI级&#xff1a;UI框架内部的提示&#xff0c;如ElMessage、ElMessageBox、ElNotification等 今天来封装一下UI级别的提示 代码 效果图 源…

Springboot 定时任务cron表达式

Cron表达式是一个强大的字符串&#xff0c;用于在Unix/Linux系统中配置cron job&#xff08;计划任务&#xff09;的时间表。然而&#xff0c;在Spring框架&#xff08;包括Spring Boot&#xff09;中&#xff0c;Cron表达式也被广泛使用于Scheduled注解中&#xff0c;以定义定…