当前位置: 首页 > news >正文

QT--day5(网络聊天室、学生信息管理系统)

 服务器:

#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;
}//启动服务器按钮对应的槽函数
void Widget::on_startBtn_clicked()
{//获取ui界面上的端口号quint16 port=ui->portEdit->text().toInt();//将服务器设置成监听状态//函数原型: bool listen(const QHostAddress &address = QHostAddress : :Any,quintl6 port = 0);//功能:监听客户端发来的连接请求//参数1:要监听的主机地址,any表示监听任意主机地址,也可以给定特定主机地址//参数2:提供的端口号,如果是0,表示让系统自动分配端口号//返回值: bool,成功监听返回true,失败返回falseif(server->listen(QHostAddress::Any,port)){QMessageBox::information(this,"","服务器启动成功");}else{QMessageBox::information(this,"","服务器启动失败");}//此时服务器已经进入监听状态,如果有客户端发来连接请求,那么该服务器就会自动发射一个newConnection信号//我们可以将该信号连接到自定义的槽函数中处理新连接的套接字connect(server,&QTcpServer::newConnection,this,&Widget::newConnect_slot);
}//处理newConnection信号的槽函数
void Widget::newConnect_slot()
{qDebug()<<"有新客户连接";//获取最新连接的客户端套接字//函数原型:virtual QTcpSocket *nextPendingConnection() ;//功能:获取最新连接客户端的套接字//参数:无//返回值:套接字指针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++){// socketList.at(i)->state();     //任意一个客户端的状态//函数原型: Socketstate state() const;//功能:返回套接字的状态//参数:无//返回值:套接字状态,是个枚举值,如果为o,表示无效连接if(socketList.at(i)->state()==0){//移除该客户端socketList.removeAt(i);  //将下标为i的套接字从链表中移除}}//遍历客户端套接字,寻找是哪个客户端有数据待读for(int i=0;i<socketList.count();i++){//判断当前套接字是否有数据待读//函数原型: qint64 bytesAvailable() const override;//功能:求出当前套接字中待读数据的个数//参数:无//返回值:待读数据的个数if(socketList.at(i)->bytesAvailable()!=0){//说明当前套接字中有数据//读取当前套接字中的数据//函数原型:QByteArray readAll();//功能:读取套接字中的所有数据//参数:无//返回值:QByteArray读取下来的数据QByteArray msg=socketList.at(i)->readAll();//将数据展示到ui界面ui->msgWidgit->addItem(QString::fromLocal8Bit(msg));//将数据发送给所有客户端for(int j=0;j<socketList.count();j++){//将数据写入到所有客户端套接字中socketList.at(j)->write(msg);}}}}

客户端:

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//初始化界面ui->sendBtn->setEnabled(false);ui->msgEdit->setEnabled(false);ui->disconnectBtn->setEnabled(false);//给客户端指针实例化空间socket=new QTcpSocket(this);//如果成功连接了服务器,那么该客户端就会自动发射一个connected的信号//我们可以将该信号连接到自定义槽函数中处理相关逻辑,由于只需连接一次,所以定义在构造函数中connect(socket,&QTcpSocket::connected,this,&Widget::connected_slot);//如果服务器有数据发送给该客户端,那么该套接字就会自动发射一个readyRead信号//我们可以将该信号连接到自定义的槽函数中,处理发来的数据,由于只需要连接一次,可以放在构造函数中connect(socket,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);//当成功与服务器断开连接后,该客户端就会自动发射一个disconnected的信号//我们可以在该信号对应的槽函数中处理后续操作。由于只需要连接一次,可以放在构造函数中connect(socket,&QTcpSocket::disconnected,this,&Widget::disconnect_slot);}Widget::~Widget()
{delete ui;
}//连接服务器按钮对应的槽函数
void Widget::on_connectBtn_clicked()
{//获取ui界面上的主机地址和端口号QString ip=ui->ipEdit->text();quint16 port=ui->portEdit->text().toInt();//将客户端连接到主机//函数原型: virtual void connectToHost(const Qstring &hostName,quint16 port)//功能:将客户端连接到服务器//参数1:服务器主机地址//参数2:服务器端口号//返回值:无socket->connectToHost(ip,port);//如果成功连接了服务器,那么该客户端就会自动发射一个connected的信号//我们可以将该信号连接到自定义槽函数中处理相关逻辑,由于只需连接一次,所以定义在构造函数中
}//关于connected信号对应槽函数的实现
void Widget::connected_slot()
{QMessageBox::information(this,"","连接服务器成功");//告诉服务器谁连接了userName=ui->useNameEdit->text();    //获取ui界面上用户名QString msg=userName + ":进入聊天室";//将信息发送给服务器socket->write(msg.toLocal8Bit());//将ui界面上的相关组件设置ui->msgEdit->setEnabled(true);ui->sendBtn->setEnabled(true);ui->disconnectBtn->setEnabled(true);ui->useNameEdit->setEnabled(false);ui->ipEdit->setEnabled(false);ui->portEdit->setEnabled(false);ui->connectBtn->setEnabled(false);//此时客户端与服务器已经成功建立起来连接//如果服务器有数据发送给该客户端,那么该套接字就会自动发射一个readyRead信号//我们可以将该信号连接到自定义的槽函数中,处理发来的数据,由于只需要连接一次,可以放在构造函数中}//处理readyRead信号的槽函数
void Widget::readyRead_slot()
{//将客户端的数据读取出来QByteArray msg=socket->readAll();//将数据展示到自己ui界面上ui->msgWidget->addItem(QString::fromLocal8Bit(msg));
}//发送按钮对应的槽函数
void Widget::on_sendBtn_clicked()
{//获取ui界面中要发送的数据QString msg=ui->msgEdit->text();//整合数据msg = userName+ ": "+msg;//将数据发送给服务器socket->write(msg.toLocal8Bit());//清空发送框的数据ui->msgEdit->clear();}//断开服务器按钮对应的槽函数
void Widget::on_disconnectBtn_clicked()
{//告诉谁离开聊天室QString msg=userName +":离开聊天室";socket->write(msg.toLocal8Bit());//断开连接//函数原型: virtual void disconnectFromHost( ) ;//功能:断开该客户端的连接//参数:返回值:无socket->disconnectFromHost();//当成功与服务器断开连接后,该客户端就会自动发射一个disconnected的信号//我们可以在该信号对应的槽函数中处理后续操作。由于只需要连接一次,可以放在构造函数中}void Widget::disconnect_slot()
{//将ui界面上的相关组件设置ui->msgEdit->setEnabled(false);ui->sendBtn->setEnabled(false);ui->disconnectBtn->setEnabled(false);ui->useNameEdit->setEnabled(true);ui->ipEdit->setEnabled(true);ui->portEdit->setEnabled(true);ui->connectBtn->setEnabled(true);
}

学生信息管理系统(头文件):

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QSqlDatabase>//数据库管理类
#include <QSqlQuery>//执行sql语句的类
#include <QSqlRecord>//数据库记录类
#include <QSqlError>//错误类
#include <QMessageBox>
#include <QDebug>
QT_BEGIN_NAMESPACE
namespace Ui { class Widget; }
QT_END_NAMESPACEclass Widget : public QWidget
{Q_OBJECTpublic:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_addBtn_clicked();void on_showBtn_clicked();private:Ui::Widget *ui;//实例化一个数据库对象QSqlDatabase db;
};
#endif // WIDGET_H

学生信息管理系统(源文件):

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//判断是否包含所需的数据库文件//函数原型: static bool contains(const QString& connectionName = QLatin1String(defaultConnection));//功能:判断该对象中是否包含给定的数据库//参数:数据库的名字//返回值: bool类型,包含返回真,不包含返回假if(!db.contains("stuInfo.db")){//添加一个数据库db=QSqlDatabase::addDatabase("QSQLITE");  //添加一个数据库,数据库的驱动为sqlite 3//给刚刚添加的数据库设置名称db.setDatabaseName("stuInfo.db");}//打开数据库if(!db.open()){QMessageBox::information(this,"","数据库打开失败");return;}//程序运行至此,则表明数据库已经打开,就可以使用sql语句进行创建表的相关操作了//想要执行sql语句,需要实例化一个QSqlQuerry的类对象,通过该类对象执行sql语句QSqlQuery querry;//准备sql语句QString sql="create table if not exists stu_info_table(""id integer primary key autoincrement,""numb integer,""name varchar(20),""sex varchar(4),""score integer)";//执行sql语句if(querry.exec(sql)){QMessageBox::information(this,"","数据表创建成功");}else{QMessageBox::information(this,"","数据表创建失败");return;}
}Widget::~Widget()
{delete ui;
}//添加数据按钮对应的槽函数
void Widget::on_addBtn_clicked()
{//将ui界面中要获取的数据取出int numb=ui->numEdit->text().toInt();QString name=ui->nameEdit->text();QString sex=ui->sexEdit->text();int score=ui->scoreEdit->text().toInt();//判断用户是否漏填数据if(numb==0||name.isEmpty()||sex.isEmpty()||score==0){QMessageBox::information(this,"","请将数据填写完整");return ;}//数据完整,可以将该数据存放入数据库中QSqlQuery querry;//定义语句执行者//准备sql语句QString sql=QString("insert into stu_info_table(numb,name,sex,score)""values(%1,'%2','%3',%4)").arg(numb).arg(name).arg(sex).arg(score);//执行sql语句if(querry.exec(sql)){QMessageBox::information(this,"","添加成功");}else{QMessageBox::information(this,"","添加失败");}
}//show按钮对应的槽函数
void Widget::on_showBtn_clicked()
{//准备sql语句QString sql="select *from stu_info_table";//定义一个执行者QSqlQuery querry;//执行sql语句if(!querry.exec(sql)){QMessageBox::information(this,"","查询失败");return ;}//此时将查询的结果都放入该对象内部了,可以使用next进行遍历查询后的内容int i=0;while(querry.next()){//querry.value(i):表示的是当前记录的第i+1项内容(从0开始)//querry.record()::返回的是当前的一整条记录//querry.record().count():返回的是当前记录的键的个数·//qDebug()<<querry.record().count();//qDebug()<<querry.value(2);for(int j=0;j<querry.record().count();j++){// querry.value(j):表示第i行的第j列的元素值ui->tableWidget->setItem(i,j,new QTableWidgetItem(querry.value(j+1).toString()));}i++;  //继续遍历下一条记录}
}

相关文章:

QT--day5(网络聊天室、学生信息管理系统)

服务器&#xff1a; #include "widget.h" #include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setupUi(this);//给服务器指针实例化空间servernew QTcpServer(this); }Widget::~Widget() {delete ui; …...

【用IDEA基于Scala2.12.18开发Spark 3.4.1 项目】

目录 使用IDEA创建Spark项目设置sbt依赖创建Spark 项目结构新建Scala代码 使用IDEA创建Spark项目 打开IDEA后选址新建项目 选址sbt选项 配置JDK debug 解决方案 相关的依赖下载出问题多的话&#xff0c;可以关闭idea&#xff0c;重启再等等即可。 设置sbt依赖 将sbt…...

HEVC 速率控制(码控)介绍

视频编码速率控制 速率控制&#xff1a; 通过选择一系列编码参数&#xff0c;使得视频编码后的比特率满足所有需要的速率限制&#xff0c;并且使得编码失真尽量小。速率控制属于率失真优化的范畴&#xff0c;速率控制算法的重点是确定与速率相关的量化参数&#xff08;Quantiz…...

四大软件测试策略的特点和区别(单元测试、集成测试、确认测试和系统测试)

四大软件测试策略分别是单元测试、集成测试、确认测试和系统测试。 一、单元测试 单元测试也称为模块测试&#xff0c;它针对软件中的最小单元&#xff08;如函数、方法、类、模块等&#xff09;进行测试&#xff0c;以验证其是否符合预期的行为和结果。单元测试通常由开发人…...

ingress-nginx controller安装

文章目录 一、ingress-nginx controller安装环境 1.1 部署yaml1.2 镜像1.3 安装操作 一、ingress-nginx controller安装 环境 kubernetes版本&#xff1a;1.27.1操作系统&#xff1a;CentOS7.9 1.1 部署yaml deploy.yaml apiVersion: v1 kind: Namespace metadata:labels:…...

开源快速开发平台:做好数据管理,实现流程化办公!

做好数据管理&#xff0c;可以提升企业的办公协作效率&#xff0c;实现数字化转型。开源快速开发平台是深受企业喜爱的低代码开发平台&#xff0c;拥有多项典型功能&#xff0c;是可以打造自主可控快速开发平台&#xff0c;实现一对一框架定制的软件平台。在快节奏的社会中&…...

基于深度学习的裂纹图像分类研究(Matlab代码实现)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…...

TypeScript入门学习汇总

1.快速入门 1.1 简介 TypeScript 是 JavaScript 的一个超集&#xff0c;支持 ECMAScript 6 标准。 TypeScript 由微软开发的自由和开源的编程语言。 TypeScript 设计目标是开发大型应用&#xff0c;它可以编译成纯 JavaScript&#xff0c;编译出来的 JavaScript 可以运行在…...

Vue3使用vxetable进行表格的编辑、删除与新增

效果图如下: vxetable4传送门 一、引入插件 package.json中加入"vxe-table": "4.0.23",终端中执行npm i导入import {VXETable, VxeTableInstance...

JUC 并发编程之JMM

目录 1. 内存模型JMM 1. 1 主内存和工作内存 1.2 重排序 1. 内存模型JMM Java内存模型是Java虚拟机&#xff08;JVM&#xff09;规范中定义的一组规则&#xff0c;用于屏蔽各种硬件和操作系统的内存访问差异&#xff0c;保证多线程情况下程序的正确执行。Java内存模型规定了…...

k8s集群中安装kibana 7.x 踩坑

1. FATAL ValidationError: child "server" fails because [child "port" fails because ["port" must be a number]] 解决办法&#xff1a; 在环境变量中指定端口&#xff1a; - name: SERVER_PORTvalue: 5601 2. Kibana FATAL Error: [elast…...

CSS的一些基础知识

选择器&#xff1a; 选择器用于选择要应用样式的HTML元素。常见的选择器包括标签选择器&#xff08;如 div、p&#xff09;、类选择器&#xff08;如 .class&#xff09;、ID选择器&#xff08;如 #id&#xff09;和伪类选择器&#xff08;如 :hover&#xff09;。选择器可以根…...

解决多线程环境下单例模式同时访问生成多个实例

如何满足单例&#xff1a;1.构造方法是private、static方法、if语句判断 ①、单线程 Single类 //Single类&#xff0c;定义一个GetInstance操作&#xff0c;允许客户访问它的唯一实例。GetInstance是一个静态方法&#xff0c;主要负责创建自己的唯一实例 public class LazySi…...

转转闲鱼交易猫源码搭建

后台一键生成链接&#xff0c;独立后台管理 教程&#xff1a;修改数据库config/Conn.php 不会可以看源码里有教程 下载程序&#xff1a;https://pan.baidu.com/s/16lN3gvRIZm7pqhvVMYYecQ?pwd6zw3...

设计模式精华版汇总

以下是个人整理的设计模式汇总&#xff0c;将会持续更新工作和面试中经常用到的设计模式。 设计模式-装饰者模式&#xff08;包装模式&#xff09;- 案例分析和源码分析​​​​​​ 设计模式-代理模式&#xff1a;控制访问的设计模式 - 案例分析 设计模式-门面模式&#xf…...

uniapp实现带参数二维码

view <view class"canvas"><!-- 二维码插件 width height设置宽高 --><canvas canvas-id"qrcode" :style"{width: ${qrcodeSize}px, height: ${qrcodeSize}px}" /></view> script import uQRCode from /utils/uqrcod…...

金融行业软件测试面试题及其答案

下面是一些常见的金融行业软件测试面试题及其答案&#xff1a; 1. 什么是金融行业软件测试&#xff1f; 金融行业软件测试是针对金融领域的软件系统进行验证和确认的过程&#xff0c;旨在确保软件在安全、稳定、可靠和符合法规要求的条件下运行。 2. 解释一下金融软件中的风险…...

强化学习QLearning 进行迷宫游戏和代码

强化学习是机器学习里面的一个分支。它强调基于环境而探索行动、学习&#xff0c;以取得最大化的预期收益。其灵感来源于心理学中的行为主义理论&#xff0c;既有机体如何在环境给予的奖励或者惩罚的刺激下&#xff0c;逐步形成对刺激的预期&#xff0c;产生能够最大利益的习惯…...

Vue2 第九节 过滤器

&#xff08;1&#xff09;定义&#xff1a;对要显示的数据进行特定格式化后再显示 &#xff08;2&#xff09;语法&#xff1a; ① 注册过滤器 1&#xff09;Vue.filter(name, callback) 全局过滤器 2&#xff09; new Vue({filters:{}}) 局部过滤器 ② 使用过滤器 1&…...

Swift 对象数组去重

使用 reduce 方法去重 使用 reduce 方法结合 contains 方法可以实现去重。reduce 方法用于将数组的元素进行累积计算&#xff0c;而 contains 方法用于检查元素是否已经存在于结果数组中。 struct SearchRecord: Equatable {let id: Intlet name: String }let records [Sear…...

8051仿真器OMF转SIG格式的实战指南

1. Signum 8051 仿真器符号转换器使用指南在嵌入式开发领域&#xff0c;Signum Systems 的 8051 仿真器是一个常用的调试工具。很多开发者在使用 Vision 开发环境时&#xff0c;经常遇到需要将链接器生成的绝对目标模块(OMF)转换为仿真器专用格式的需求。本文将详细介绍这个转换…...

调查研究-142 全球机器人产业深度调研报告【04篇】机器人产业利润池全景:谁最容易赚钱与十大判断指标

TL;DR 场景&#xff1a;关注机器人产业投资、创业、就业方向的投资者、从业者、分析师结论&#xff1a;医疗机器人耗材/服务>高端核心零部件>系统集成>物流RaaS>工业本体>软件AI平台&#xff1b;人形机器人长期空间大但短期商业化仍早产出&#xff1a;三档利润池…...

注意力的几何本质:一个空间与两个算子的统一框架

1. 项目概述&#xff1a;这不是又一篇讲Attention机制的“科普文”如果你最近翻过几篇顶会论文&#xff0c;或者在GitHub上扫过几个热门Transformer库的源码&#xff0c;大概率会在某个角落撞见“The Geometry of Attention: One Space, Two Operators”这个标题。它不像“Atte…...

AI学习 Newsletter 的手工感设计:从断点驱动到可追溯实践

1. 项目概述&#xff1a;这不是一份 newsletter&#xff0c;而是一份 AI 社区共建的实践手记 “Learn AI Together — Towards AI Community Newsletter #14”——看到这个标题&#xff0c;你第一反应可能是&#xff1a;又一份 AI 领域的资讯汇总&#xff1f;点开看看最新论文…...

技术人的英语能力如何影响薪资?数据说话

打开任何一个招聘平台&#xff0c;搜索“软件测试工程师”&#xff0c;你会发现一个越来越普遍的现象。对于那些薪资范围宽、技术描述详尽、公司名号响亮的岗位&#xff0c;末尾往往会附上一句&#xff1a;“英语可作为工作语言”、“英文读写能力优异”、“CET-6以上优先”。这…...

Logback 日志框架使用与配置指南

1. Logback 核心概念与架构 Logback 是 Java 生态中最主流的日志框架之一&#xff0c;其配置体系主要围绕以下三个核心概念展开&#xff1a; Logger&#xff08;日志记录器&#xff09;&#xff1a;负责捕获日志事件。它通过 name 属性&#xff08;通常是包名或类名&#xff09…...

成都制造企业供应链价格波动频繁,AI智能体该先预警哪些信号?

一、价格波动不是采购一个部门能扛住的问题很多制造企业谈供应链价格波动&#xff0c;第一反应是让采购去谈价、催报价、找替代供应商。但在真实经营里&#xff0c;价格风险很少只停留在采购单价上。铜、铝、钢材、塑料、电子元器件、包装材料、运费、汇率和供应商产能变化&…...

AI时代中小企业还要不要上ERP?2026年最新思考

最近DeepSeek爆火&#xff0c;AI Agent层出不穷&#xff0c;不少老板问我&#xff1a;都2026年了&#xff0c;AI这么厉害&#xff0c;中小企业还有必要上ERP吗&#xff1f;我的答案是&#xff1a;不仅要上&#xff0c;而且要上得更聪明。一、AI再强&#xff0c;也替代不了ERP的…...

测试工程师如何进行测试计划制定?这5个步骤让你的计划更合理

对于软件测试从业者而言&#xff0c;一份合理可行的测试计划是项目测试工作的核心纲领&#xff0c;它不仅决定了测试活动的范围、方向与资源分配&#xff0c;更直接影响着项目的交付质量与进度管控。很多初级测试工程师常常将测试计划等同于测试时间列表&#xff0c;要么写得过…...

NotebookLM移动端体验全拆解(iOS/Android双端对比报告·仅限内测用户知晓的性能阈值)

更多请点击&#xff1a; https://kaifayun.com 第一章&#xff1a;NotebookLM移动端体验全景概览 NotebookLM 作为 Google 推出的基于用户自有文档构建的 AI 助手&#xff0c;其移动端&#xff08;iOS/Android&#xff09;已正式开放下载。该应用并非简单将网页版界面缩放适配…...