2.26 Qt day4+5 纯净窗口移动+绘画事件+Qt实现TCP连接服务+Qt实现连接数据库

news2024/9/30 3:36:26

思维导图

Qt实现TCP连接

服务器端:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTcpServer>//服务器端类
#include<QTcpSocket>//客户端类
#include<QMessageBox>//消息对话框类
#include<QList>//链表容器类--->存放客户端的容器

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

public slots:
    void newconnection_slot();//newconnect对应的槽函数声明
    void readyRead_slot();//readyRead对应的槽函数声明
private slots:
    void on_startBtn_clicked();

private:
    Ui::Widget *ui;
    QTcpServer *server;//实例化一个服务器指针
    QList<QTcpSocket *>socketList;//定义一个容器存放客户端
};
#endif // WIDGET_H

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //给服务器指针实例化空间
    server=new QTcpServer(this);
}

Widget::~Widget()
{
    delete ui;
}
//newconnection信号对应的槽函数实现
void Widget::newconnection_slot()
{
    //获取最新连接的客户端的套接字
    QTcpSocket *s=server->nextPendingConnection();
    //将客户端套接字存放到容器列表中
    socketList.push_back(s);
    //将readyRead信号连接到自定义的槽函数中
    connect(s,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
}
//readyRead对应的槽函数实现
void Widget::readyRead_slot()
{
    //读取客户端的数据
    //移除无效客户端
    for(int i=0;i<socketList.count();i++)
    {
        //判断客户端与服务器的连接状态 未连接UnconnectedState枚举值:0
        if(socketList.at(i)->state()==QTcpSocket::UnconnectedState)//==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界面上
            ui->msgWidget->addItem(QString::fromLocal8Bit(msg));//addItem==setText
            //将该数据内容广播给所有人
            for(int j=0;j<socketList.count();j++)
            {
                //将数据写入所有客户端的套接字中
                socketList.at(j)->write(msg);
            }
        }
    }
}

//启动按钮对应的槽函数处理
void Widget::on_startBtn_clicked()
{
    //获取UI界面的端口号 toUInt将字符串转换成整型
    quint16 port=ui->portEdit->text().toUInt();
    //设置监听
    if(server->listen(QHostAddress::Any,port))
    {
        //弹出消息对话框
        QMessageBox::information(this,"","启动服务器成功!");
        //设置启动按钮不可用
        ui->startBtn->setEnabled(false);
    }
    else
    {
        QMessageBox::information(this,"","启动服务器失败!");
        return;
    }
    //将客户端发来的newConnection信号连接到自定义的槽函数
    connect(server,&QTcpServer::newConnection,this,&Widget::newconnection_slot);
}

widget.ui

客户端:

widget.h

#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include<QTcpSocket>//客户端类、
#include<QMessageBox>//消息对话框类

QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    Widget(QWidget *parent = nullptr);
    ~Widget();

private slots:
    void on_connectBtn_clicked();
    void on_sendBtn_clicked();

    void on_disconnectBtn_clicked();

public slots:
    void connected_slot();//connected对应的槽函数声明
    void readyRead_slot();//readyRead对应的槽函数声明
    void disconnect_slot();//disconnected对应的槽函数声明

private:
    Ui::Widget *ui;
    //实例化一个客户端指针
    QTcpSocket *socket;
    QString userName;//存放用户名
};
#endif // WIDGET_H

main.cpp

#include "widget.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    Widget w;
    w.show();
    return a.exec();
}

widget.cpp

#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //给客户端指针申请空间
    socket=new QTcpSocket(this);
    //设置初始化界面 给msgEdit、sendEdit、disconnectBtn设置不可用
    ui->msgEdit->setEnabled(false);
    ui->sendBtn->setEnabled(false);
    ui->disconnectBtn->setEnabled(false);
    //将connected信号连接到自定义的槽函数
    connect(socket,&QTcpSocket::connected,this,&Widget::connected_slot);
}

Widget::~Widget()
{
    delete ui;
}

//连接按钮对应的槽函数处理
void Widget::on_connectBtn_clicked()
{
    //获取UI界面上的IP和端口号
    QString ip=ui->IPEdit->text();
    quint16 port=ui->portEdit->text().toUInt();//将字符串转换为整型
    //连接服务器
    socket->connectToHost(ip,port);
    //将readyRead信号和自定义槽函数连接
    connect(socket,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);
}
//connected对应的槽函数实现
void Widget::connected_slot()
{
    //弹出消息对话框 提示用户连接成功
    QMessageBox::information(this,"","连接服务器成功!");
    //将msgEdit、sendEdit、disconnectBtn设置可用
    ui->msgEdit->setEnabled(true);
    ui->sendBtn->setEnabled(true);
    ui->disconnectBtn->setEnabled(true);
    //将connectBtn、userNameEdit、IPEdit、portEdit设置不可用
    ui->connectBtn->setEnabled(false);
    ui->userNameEdit->setEnabled(false);
    ui->IPEdit->setEnabled(false);
    ui->portEdit->setEnabled(false);
    //告诉服务器xxx上线了
    userName=ui->userNameEdit->text();
    QString msg=userName+":进入聊天室!";
    //将msg发送给服务器
    socket->write(msg.toLocal8Bit());
}
//readyRead对应的槽函数实现
void Widget::readyRead_slot()
{
    //读取数据
    QByteArray msg=socket->readAll();
    //将读取的数据放入ui界面上
    ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
}
//disconnect对应的槽函数
void Widget::disconnect_slot()
{
    //将客户端与服务器端断开连接
    socket->disconnectFromHost();
}
//发送按钮对应的槽函数处理
void Widget::on_sendBtn_clicked()
{
    //将msgEdit文本发送给服务器
    QString msg=userName+":"+ui->msgEdit->text();
    socket->write(msg.toLocal8Bit());
    ui->msgEdit->clear();//清空msgEdit
}
//disconnectBtn按钮对应的槽函数处理
void Widget::on_disconnectBtn_clicked()
{
    //告诉服务器xxx下线了
    QString msg=userName+":离开聊天室";
    socket->write(msg.toLocal8Bit());
    //将msgEdit、sendEdit、disconnectBtn设置不可用
    ui->msgEdit->setEnabled(false);
    ui->sendBtn->setEnabled(false);
    ui->disconnectBtn->setEnabled(false);
    //将connectBtn、userNameEdit、IPEdit、portEdit设置可用
    ui->connectBtn->setEnabled(true);
    ui->userNameEdit->setEnabled(true);
    ui->IPEdit->setEnabled(true);
    ui->portEdit->setEnabled(true);
    QMessageBox::information(this,"","断开连接成功!");
}

widget.ui

运行结果:

服务器端初始状态:

 填写端口号启动服务器之后:

 客户端初始状态:

 输入用户名、IP地址、端口号、点击连接之后:

 客户端发送消息给服务器端:

客户端断开连接之后:

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

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

相关文章

2024-02-26(Spark,kafka)

1.Spark SQL是Spark的一个模块&#xff0c;用于处理海量结构化数据 限定&#xff1a;结构化数据处理 RDD的数据开发中&#xff0c;结构化&#xff0c;非结构化&#xff0c;半结构化数据都能处理。 2.为什么要学习SparkSQL SparkSQL是非常成熟的海量结构化数据处理框架。 学…

实践航拍小目标检测,基于轻量级YOLOv8n开发构建无人机航拍场景下的小目标检测识别分析系统

关于无人机相关的场景在我们之前的博文也有一些比较早期的实践&#xff0c;感兴趣的话可以自行移步阅读即可&#xff1a; 《deepLabV3Plus实现无人机航拍目标分割识别系统》 《基于目标检测的无人机航拍场景下小目标检测实践》 《助力环保河道水质监测&#xff0c;基于yolov…

掌握ChatGPT润色绝技:什么是人工智能写作以及如何使用它来完成写作任务

如对AI写论文感兴趣&#xff0c;欢迎添加作者wx讨论 : ryan_2982 人工智能 (AI) 的出现开创了技术进步的新时代&#xff0c;彻底改变了包括写作和内容创作在内的各个行业。人工智能写作和人工智能提示已成为可以简化和增强写作任务的强大工具。在这篇博文中&#xff0c;我们将…

C++多线程学习09:并发队列

参考 链接&#xff1a;恋恋风辰官方博客 并发队列&线程安全栈 代码结构&#xff1a; 并发队列ThreadSafeQueue.h&#xff1a; #pragma once#include <mutex> #include <queue>template<typename T> class threadsafe_queue { private:mutable std::m…

深入理解Python中的JSON模块:基础大总结与实战代码解析【第102篇—JSON模块】

深入理解Python中的JSON模块&#xff1a;基础大总结与实战代码解析 在Python中&#xff0c;JSON&#xff08;JavaScript Object Notation&#xff09;模块是处理JSON数据的重要工具之一。JSON是一种轻量级的数据交换格式&#xff0c;广泛应用于Web开发、API通信等领域。本文将…

linux操作系统期末练习题

背景&#xff1a; 一、远程登录 1&#xff0e;利用远程登录软件&#xff0c;以用户userManager(密码123456)&#xff0c;远程登录教师计算机&#xff08;考试现场给出IP地址&#xff09;&#xff0c;只有操作&#xff0c;没有命令。 2&#xff0e;以stu班级学生个人学号后3位…

goland配置新增文件头

参考&#xff1a; goland函数注释生成插件 goland函数注释生成插件_goland自动加函数说明-CSDN博客 GoLand 快速添加方法注释 GoLand 快速添加方法注释_goland批量注释-CSDN博客 goland 如何设置头注释&#xff0c;自定义author和data goland 如何设置头注释&#xff0c;自定…

spring boot 集成科大讯飞星火认知大模型

一、安装依赖 <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://maven.apache.org/POM/4.0.0" xmlns:xsi"http://www.w3.org/2001/XMLSchema-instance"xsi:schemaLocation"http://maven.apache.org/POM/…

springboot003图书个性化推荐系统的设计与实现(源码+调试+LW)

项目描述 临近学期结束&#xff0c;还是毕业设计&#xff0c;你还在做java程序网络编程&#xff0c;期末作业&#xff0c;老师的作业要求觉得大了吗?不知道毕业设计该怎么办?网页功能的数量是否太多?没有合适的类型或系统?等等。今天给大家介绍一篇基于SpringBoot的图书个…

SOLIDWORKS 查找并修复装配体配合错误

我们在SOLIDWORKS 正版软件进行装配体装配时&#xff0c;时常会出现一些报错&#xff0c;例如在配合、装配体特征或被装配体参考引用的零部件和子装配体中。一些常见的错误&#xff0c;如一个零部件的过定义会引发更多其他错误信息&#xff0c;并导致装配体停止解析配合关系。下…

RestTemplate启动问题解决

⭐ 作者简介&#xff1a;码上言 ⭐ 代表教程&#xff1a;Spring Boot vue-element 开发个人博客项目实战教程 ⭐专栏内容&#xff1a;个人博客系统 ⭐我的文档网站&#xff1a;http://xyhwh-nav.cn/ RestTemplate启动问题解决 问题&#xff1a;在SpringCloud架构项目中配…

汽车大灯尾灯划痕裂缝破洞破损掉角崩角等如何修复?根本没必要换车灯换总成,使用无痕修UV树脂胶液即可轻松搞定。

TADHE车灯无痕修复专用UV胶是一种经过处理的UV树脂胶&#xff0c;主要成份是改性丙烯酸UV树脂。应用在车灯的专业无痕修复领域。 车灯修复UV树脂有以下优点&#xff1a; 1. 快速修复&#xff1a;此UV树脂是一种用UV光照射在10秒内固化的材料。 2. 高强度&#xff1a;UV树脂固…

【npm下载包报错:CERT_HAS_EXPIRED,问题解决】

npm下载包报错&#xff1a;CERT_HAS_EXPIRED npm安装依赖的时候出现报错 根据第三行报错的提示得知报错原因是证书已过期 上网一查&#xff0c;原来常用的淘宝镜像早就换新域名了&#xff0c; 之前的镜像域名在2024年1月22日https证书到期了 替换为最新的地址就可以了 npm …

蛋白结构预测模型评价指标

欢迎浏览我的CSND博客&#xff01; Blockbuater_drug …点击进入 文章目录 前言一、蛋白结构预测模型评价指标TM-scorelDDT 二、Alphafold中的评价指标pLDDTpTMPAE 三、AlphaFold-multimer 蛋白结构的评价指标DockQipTM 总结参考资料 前言 本文汇总了AlphaFold和AlphaFold-mul…

线性表——单链表的增删查改(下)

本节继续上节未完成的链表增删查改接口的实现。这是上节的地址:线性表——单链表的增删查改&#xff08;上&#xff09;-CSDN博客 上节实现的接口如下&#xff1a; //申请链表节点函数接口 SLNode* BuySListNode(SLTDataType x); //单链表的打印函数接口 void SListPrint(SLNod…

探索比特币现货 ETF 对加密货币价格的潜在影响

撰文&#xff1a;Sean&#xff0c;Techub News 文章来源Techub News&#xff0c;搜Tehub News下载查看更多Web3资讯。 自美国比特币现货交易所交易基金&#xff08;ETF&#xff09;上市以来&#xff0c;比特币现货 ETF 的相关信息无疑成为了影响比特币价格及加密货币市场走向…

《Docker 简易速速上手小册》第10章 朝着 Docker Swarm 和 Kubernetes 迈进(2024 最新版)

文章目录 10.1 Docker Swarm 基础10.1.1 重点基础知识10.1.2 重点案例&#xff1a;Python Web 应用的 Docker Swarm 部署10.1.3 拓展案例 1&#xff1a;微服务架构的 Docker Swarm 部署10.1.4 拓展案例 2&#xff1a;使用 Docker Swarm 进行持续部署 10.2 Kubernetes 与 Docker…

nginx 从$http_x_forwarded_for 中获取第一个参数

在 Nginx 中&#xff0c;$http_x_forwarded_for 变量通常包含了客户端的原始 IP 地址以及可能经过的代理服务器的 IP 地址列表&#xff0c;这些地址由逗号分隔。如果你想从 $http_x_forwarded_for 中截取第一个参数&#xff08;即最左边的 IP 地址&#xff09;&#xff0c;你可…

C语言中的套娃——函数递归

目录 一、什么是递归 1.1.递归的思想 1.2.递归的限制条件 二、举例体会 2.1.求n的阶乘 2.2.顺序打印整数的每一位 2.3.斐波那契数列 三、递归与迭代 一、什么是递归 在学习C语言的过程中&#xff0c;我们经常会跟递归打交道&#xff0c;什么是递归呢&#xff1f;它其实…

用于自监督视觉预训练的屏蔽特征预测

Masked Feature Prediction for Self-Supervised Visual Pre-Training 一、摘要 提出了用于视频模型自监督预训练的掩模特征预测&#xff08;MaskFeat&#xff09;。首先随机屏蔽输入序列的一部分&#xff0c;然后预测屏蔽区域的特征。研究了五种不同类型的特征&#xff0c;发…