复习 --- QT服务器客户端
服务器:
头文件:
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QTcpServer>
#include<QTcpSocket>
#include<QMessageBox>
#include<QDebug>
#include<QList>
#include<QListWidget>
#include<QLabel>
#include<QLineEdit>
#include<QPushButton>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;//客户端指针QTcpSocket *client;//存储用户名QString uname;//聊天框QListWidget *text;//消息发送框QLineEdit *msg;//发送按钮QPushButton *send;//用户名、QLabel *userLab;//IPQLabel *ipLab;//PORTQLabel *portLab;//用户输入框QLineEdit *unameEdit;//IP输入框QLineEdit *ipEdit;//端口输入框QLineEdit *portEdit;//连接服务器按钮QPushButton *bconnect;//断开服务器按钮QPushButton *bdisconnect;public slots://连接按钮槽函数void connectBtn_clicked();//声明自定义处理connected信号的槽函数void connected_slot();//声明自定义处理readyRead信号的槽函数void readyRead_slot();//声明自定义处理disconnected信号的槽函数void disconnected_slot();//发送按钮槽函数void sendBtn_clicked();//断开连接槽函数void disconnectBtn_clicked();
};
#endif // WIDGET_H
widget.cpp文件
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setFixedSize(720,680);//聊天框text = new QListWidget(this);text->setFixedSize(720,400);//消息发送框msg = new QLineEdit(this);msg->resize(500,50);msg->move(10,420);//发送按钮send = new QPushButton(this);send->setText("发送");send->resize(150,50);send->move(520,420);//用户名userLab = new QLabel(this);userLab->setText("用户名:");userLab->setAlignment(Qt::AlignCenter);userLab->resize(100,30);userLab->move(30,500);//IPipLab = new QLabel(this);ipLab->setText("IP:");ipLab->setAlignment(Qt::AlignCenter);ipLab->resize(100,30);ipLab->move(30,550);//PORTportLab = new QLabel(this);portLab->setText("Port:");portLab->setAlignment(Qt::AlignCenter);portLab->resize(100,30);portLab->move(30,600);//用户输入框unameEdit = new QLineEdit(this);unameEdit->resize(300,30);unameEdit->move(140,500);//IP输入框ipEdit = new QLineEdit(this);ipEdit->resize(300,30);ipEdit->move(140,550);//端口输入框portEdit = new QLineEdit(this);portEdit->resize(300,30);portEdit->move(140,600);//连接服务器按钮bconnect = new QPushButton(this);bconnect->resize(120,50);bconnect->setText("连接");bconnect->move(520,500);//断开服务器按钮bdisconnect = new QPushButton(this);bdisconnect->resize(120,50);bdisconnect->setText("断开连接");bdisconnect->move(520,580);client = new QTcpSocket(this);//连接按钮信号connect(bconnect,&QPushButton::clicked,this,&Widget::connectBtn_clicked);//连接上后客户端自动发送一个connected信号,只需要连接一次connect(client,&QTcpSocket::connected,this,&Widget::connected_slot);//如果服务器有数据发送给该客户端,那么该套接字就会自动发射一个readyRead信号connect(client, &QTcpSocket::readyRead, this, &Widget::readyRead_slot);//发送按钮connect(send,&QPushButton::clicked,this,&Widget::sendBtn_clicked);//当成功与服务器断开连接后,该客户端就会自动发射一个disconnected的信号connect(client, &QTcpSocket::disconnected, this, &Widget::disconnected_slot);
}Widget::~Widget()
{delete ui;}//连接按钮槽函数
void Widget::connectBtn_clicked()
{//获取ip和端口QString ip = ipEdit->text();quint16 port = portEdit->text().toUInt();//连接主机client->connectToHost(ip,port);
}
//声明自定义处理connected信号的槽函数
void Widget::connected_slot()
{QMessageBox::information(this,"","连接服务器成功");uname = unameEdit->text();QString msgs = uname+":进入聊天室";client->write(msgs.toLocal8Bit());msg->setEnabled(true);send->setEnabled(true);bdisconnect->setEnabled(true);unameEdit->setEnabled(false);ipEdit->setEnabled(false);portEdit->setEnabled(false);bconnect->setEnabled(false);}
//声明自定义处理readyRead信号的槽函数
void Widget::readyRead_slot()
{//接收到服务器消息后QByteArray msgbox = client->readAll();//显示text->addItem(QString::fromLocal8Bit(msgbox));
}
//声明自定义处理disconnected信号的槽函数
void Widget::disconnected_slot()
{QString msgbox = uname+":离开聊天室";client->write(msgbox.toLocal8Bit());//断开后客户端会发送一个disconnected信号client->disconnectFromHost();
}
//发送按钮槽函数
void Widget::sendBtn_clicked()
{QString msgbox = msg->text();msgbox = uname+":"+msgbox;//发送client->write(msgbox.toLocal8Bit());msg->clear();}
//断开连接槽函数
void Widget::disconnectBtn_clicked()
{QMessageBox::information(this,"","成功断开");msg->setEnabled(false);send->setEnabled(false);bdisconnect->setEnabled(false);unameEdit->setEnabled(true);ipEdit->setEnabled(true);portEdit->setEnabled(true);bconnect->setEnabled(true);
}
客户端
头文件
#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include<QTcpServer>
#include<QTcpSocket>
#include<QMessageBox>
#include<QDebug>
#include<QList>
#include<QListWidget>
#include<QLabel>
#include<QLineEdit>
#include<QPushButton>QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private:Ui::Widget *ui;//定义服务器指针QTcpServer *server;//定义客户端容器QList<QTcpSocket*> socketList;//对话框QListWidget *text;//端口号QLabel * l_port;//端口输入框QLineEdit *edit_port;//启动按钮QPushButton *bstart;private slots://按键槽函数void start_clicked();//连接槽函数void newConnection_slot();//readyRead信号处理槽函数void readyRead_slot();};
#endif // WIDGET_H
widget.cpp
#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);this->setFixedSize(680,500);//对话框text = new QListWidget(this);text->setFixedSize(680,350);//端口号l_port = new QLabel(this);l_port->setText("端口号:");l_port->resize(50,30);l_port->move(50,400);//端口输入框edit_port = new QLineEdit(this);edit_port->resize(380,30);edit_port->move(120,400);//启动按钮bstart = new QPushButton(this);bstart->setText("启动服务器");bstart->resize(100,30);bstart->move(520,400);server = new QTcpServer(this);connect(bstart,&QPushButton::clicked,this,&Widget::start_clicked);
}Widget::~Widget()
{delete ui;
}void Widget::start_clicked()
{qDebug()<<"ok"; //测试//判断输入框中是否有内容if(edit_port->text() == NULL){QMessageBox::information(this,"错误","端口号为空!");}else{//获取输入框中的内容quint16 port = edit_port->text().toUInt();qDebug()<<port;QString ip = "192.168.1.2";QHostAddress address(ip);//将服务器设置成监听状态,监听客户段发来的连接请求if(server->listen(QHostAddress::Any,port)){QMessageBox::information(this,"","服务器启动成功");}else{QMessageBox::information(this,"","服务器启动失败");}//此时服务器已经进入监听状态,客户段发来连接请求,服务器就会自动发射一个newConnext信号connect(server,&QTcpServer::newConnection,this,&Widget::newConnection_slot);}
}void Widget::newConnection_slot()
{qDebug()<<"有客户连接";//获取最新连接的客户段套接字QTcpSocket *client = server->nextPendingConnection();//将套接字放入客户端容器socketList.push_back(client);//监听套接字,有数据则客户端会发送一个readyRead信号connect(client,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
}void Widget::readyRead_slot()
{//移除无效客户端for (int i = 0;i<socketList.count();i++){//套接字状态为0表示无效客户端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();text->addItem(QString::fromLocal8Bit(msg));for (int j = 0;j<socketList.count();j++){socketList.at(j)->write(msg);}}}
}相关文章:
复习 --- QT服务器客户端
服务器: 头文件: #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include<QTcpServer> #include<QTcpSocket> #include<QMessageBox> #include<QDebug> #include<QList> #include<QListWidget> #in…...
Godot 官方2D游戏笔记(1):导入动画资源和添加节点
前言 Godot 官方给了我们2D游戏和3D游戏的案例,不过如果是独立开发者只用考虑2D游戏就可以了,因为2D游戏纯粹,我们只需要关注游戏的玩法即可。2D游戏的美术素材简单,交互逻辑简单,我们可以把更多的时间放在游戏的玩法…...
leetcode 热题 100
数组和字符串匹配 子串和子序列 原串:“abcabc” 子串:“abc”, 连续但不大于原串的字符串 子序列:“acc”, 字符来自原串且保持在原串中顺序不变的字符串 子排列: “aabbcc”, 字符来自原串且只能用1次,但可有不同排列顺序的字…...
Ae 效果:CC Lens
扭曲/CC Lens Distort/CC Lens CC Lens (CC 镜头)主要用于添加或移除摄像机镜头扭曲,比如桶形失真 Barrel、枕形失真 Pincushion以及鱼眼失真 Fisheye等。或者,用它来创建一些特殊的动画效果。 ◆ ◆ ◆ 效果属性说明 Center 中…...
【Redis】基础数据结构-quicklist
Redis List 在Redis3.2版之前,Redis使用压缩列表和双向链表作为List的底层实现。当元素个数比较少并且元素长度比较小时,Redis使用压缩列表实现,否则Redis使用双向链表实现。 ziplist存在问题 不能保存过多的元素,否则查找复杂度…...
QT 实现服务器客户端搭建
1. 服务器头文件 #ifndef SER_H #define SER_H#include <QWidget> #include<QTcpServer> //服务器头文件 #include<QTcpSocket> //客户端头文件 #include<QMessageBox> //消息对话框 #include<QList> //链表头文件QT_BEGIN_NAM…...
Javascript - 轮播图
轮播图也称banner图、广告图、焦点图、滑片。是指在一个模块或者窗口,通过鼠标点击或手指滑动后,可以看到多张图片。这些图片统称为轮播图,这个模块叫做轮播模块。可以通过运用 javascript去实现定时自动转换图片。以下通过一个小Demo演示如何运用Javascript实现。 <!DOCTYP…...
MATLAB中syms函数使用
目录 语法 说明 示例 创建符号标量变量 创建符号标量变量的向量 创建符号标量变量矩阵 管理符号标量变量的假设 创建和评估符号函数 syms函数的作用是创建符号标量和函数,以及矩阵变量和函数。 语法 syms var1 ... varN syms var1 ... varN [n1 ... nM] …...
竞赛选题 深度学习 opencv python 实现中国交通标志识别_1
文章目录 0 前言1 yolov5实现中国交通标志检测2.算法原理2.1 算法简介2.2网络架构2.3 关键代码 3 数据集处理3.1 VOC格式介绍3.2 将中国交通标志检测数据集CCTSDB数据转换成VOC数据格式3.3 手动标注数据集 4 模型训练5 实现效果5.1 视频效果 6 最后 0 前言 🔥 优质…...
Qt 关于mouseTracking鼠标追踪和tabletTracking平板追踪的几点官方说明
mouseTracking属性用于保存是否启用鼠标跟踪,缺省情况是不启用的。 没启用的情况下,对应部件只接收在鼠标移动同时至少一个鼠标按键按下时的鼠标移动事件。 启用鼠标跟踪的情况下,任何鼠标移动事件部件都会接收。 部件方法hasMouseTrackin…...
基于springboot的论坛网站
目录 前言 一、技术栈 二、系统功能介绍 用户信息管理 普通管理员管理 交流论坛 交流论坛评论 三、核心代码 1、登录模块 2、文件上传模块 3、代码封装 前言 随着信息技术在管理上越来越深入而广泛的应用,管理信息系统的实施在技术上已逐步成熟。本文介绍了…...
分库分表理论总结
一、概述 分库分表是在面对高并发、海量数量时常见的数据库层面的解决方案。通过把数据分散到不同的数据库中,使得单一数据库的数据量变小来缓解单一数据库的性能问题,从而达到提升数据库性能的目的。比如:将电商数据库拆分为若干独立的数据…...
RK3568平台开发系列讲解(外设篇)AP3216C 三合一环境传感器驱动
🚀返回专栏总目录 文章目录 一、AP3216C 简介二、AP3216C驱动程序2.1、设备树修改2.2、驱动程序沉淀、分享、成长,让自己和他人都能有所收获!😄 📢在本篇将介绍AP3216C 三合一环境传感器的驱动。 一、AP3216C 简介 AP3216C 是由敦南科技推出的一款传感器,其支持环境光…...
ES 关于 remote_cluster 的一记小坑
最近有小伙伴找到我们说 Kibana 上添加不了 Remote Cluster,填完信息点 Save 直接跳回原界面了。具体页面,就和没添加前一样。 我们和小伙伴虽然隔着网线但还是进行了深入、详细的交流,梳理出来了如下信息: 两个集群:…...
第五章:最新版零基础学习 PYTHON 教程—Python 字符串操作指南(第四节 - Python 中的字符串反转6种不同的方式方法)
Python 字符串库不支持内置的“ reverse() ”,就像其他 python 容器(如 list)所做的那样,因此了解其他反转字符串的方法可能会很有用。本文讨论了在Python中实现它的几种方法。 目录 Python 中使用循环反转字符串 在Python中使用递归反转字符串...
el-date-picker增加默认值 修改样式
预期效果 默认是这样的 但希望是直接有一个默认的当天日期,并且字体颜色啥的样式也要修改(在这里假设今天是2023/10/6 功能实现 踩了坑挺多坑的,特此记录 官方文档 按照官方的说明,给v-model绑定一个字符串就可以了 在j…...
Hive中生成自增序列的常用方法
在日常业务开发过程中,通常遇到需要hive数据表中生成一列唯一ID,当然连续递增的更好。 最近在结算业务中,需要在hive表中生成一列连续且唯一的账单ID,于是就了解生成唯一ID的方法 1. 利用row_number函数 语法:row_n…...
4.MySql安装配置(更新版)
MySql安装配置 无论计算机是否有安装其他mysql,都不要卸载。 只要确定大版本是8即可,8.0.33 8.0.34 差别不大即可。 MySql下载安装适合电脑配置属性有关,一次性安装成功当然是非常好的,因为卸载步骤是非常麻烦的 如果第一次安装…...
使用opencv及FFmpeg编辑视频
使用opencv及FFmpeg编辑视频 1.融合两个视频2.为视频添加声音2.1 安装ffmpy Python包2.2 下载ffmpeg2.3 代码实现 3.效果参考文献 帮朋友做了一个小作业,具体实现分为几个过程: 将两个mp4格式视频融合到一起为新视频添加声音 1.融合两个视频 其中一个…...
Python3 Selenium4 chromedriver Pycharm闪退的问题
Python3版本:3.11.5 Pycharm版本:2023.2.1 Chrome版本:117.0.5938.150(正式版本) 在使用最新版的Selenium4版本时,chromedriver可以驱动Chrome但是闪退,Selenium目前最新版本是4.13.0&#…...
使用VSCode开发Django指南
使用VSCode开发Django指南 一、概述 Django 是一个高级 Python 框架,专为快速、安全和可扩展的 Web 开发而设计。Django 包含对 URL 路由、页面模板和数据处理的丰富支持。 本文将创建一个简单的 Django 应用,其中包含三个使用通用基本模板的页面。在此…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
MFC内存泄露
1、泄露代码示例 void X::SetApplicationBtn() {CMFCRibbonApplicationButton* pBtn GetApplicationButton();// 获取 Ribbon Bar 指针// 创建自定义按钮CCustomRibbonAppButton* pCustomButton new CCustomRibbonAppButton();pCustomButton->SetImage(IDB_BITMAP_Jdp26)…...
Vue3 + Element Plus + TypeScript中el-transfer穿梭框组件使用详解及示例
使用详解 Element Plus 的 el-transfer 组件是一个强大的穿梭框组件,常用于在两个集合之间进行数据转移,如权限分配、数据选择等场景。下面我将详细介绍其用法并提供一个完整示例。 核心特性与用法 基本属性 v-model:绑定右侧列表的值&…...
Mac软件卸载指南,简单易懂!
刚和Adobe分手,它却总在Library里给你写"回忆录"?卸载的Final Cut Pro像电子幽灵般阴魂不散?总是会有残留文件,别慌!这份Mac软件卸载指南,将用最硬核的方式教你"数字分手术"࿰…...
sqlserver 根据指定字符 解析拼接字符串
DECLARE LotNo NVARCHAR(50)A,B,C DECLARE xml XML ( SELECT <x> REPLACE(LotNo, ,, </x><x>) </x> ) DECLARE ErrorCode NVARCHAR(50) -- 提取 XML 中的值 SELECT value x.value(., VARCHAR(MAX))…...
Spring Boot+Neo4j知识图谱实战:3步搭建智能关系网络!
一、引言 在数据驱动的背景下,知识图谱凭借其高效的信息组织能力,正逐步成为各行业应用的关键技术。本文聚焦 Spring Boot与Neo4j图数据库的技术结合,探讨知识图谱开发的实现细节,帮助读者掌握该技术栈在实际项目中的落地方法。 …...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Python Ovito统计金刚石结构数量
大家好,我是小马老师。 本文介绍python ovito方法统计金刚石结构的方法。 Ovito Identify diamond structure命令可以识别和统计金刚石结构,但是无法直接输出结构的变化情况。 本文使用python调用ovito包的方法,可以持续统计各步的金刚石结构,具体代码如下: from ovito…...
基于SpringBoot在线拍卖系统的设计和实现
摘 要 随着社会的发展,社会的各行各业都在利用信息化时代的优势。计算机的优势和普及使得各种信息系统的开发成为必需。 在线拍卖系统,主要的模块包括管理员;首页、个人中心、用户管理、商品类型管理、拍卖商品管理、历史竞拍管理、竞拍订单…...
