QT day5 作业

服务器头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QTcpServer>   //服务器类
#include <QTcpSocket>   //客户端类
#include <QList>        //链表类
#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_start_clicked();void newConnect_slot();void readyRead_slot();
private:Ui::Widget *ui;QTcpServer *ser;                //定义服务器指针QList<QTcpSocket *> cliList;    //客户端容器链表
};
#endif // WIDGET_H

服务器源代码

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//给服务器指针实例化对象ser = new QTcpServer(this);
}Widget::~Widget()
{delete ui;
}//启动按钮对应的槽函数
void Widget::on_start_clicked()
{if(ui->start->text() == "启动"){//获取ui界面上的端口号quint16 port = ui->port->text().toUInt();//启动服务器//将服务器设置为被动监听状态if(ser->listen(QHostAddress::Any,port) == true){QMessageBox::information(this,"成功","服务器启动成功");}else{QMessageBox::information(this,"成功","服务器启动失败");}//当启动服务器后,如果有客户端发来的连接请求,那么服务器就会自动发射一个newConnect信号//我们可以将该信号,连接到对应的槽函数中处理相关逻辑connect(ser,&QTcpServer::newConnection,this,&Widget::newConnect_slot);//将文本内容改成关闭ui->start->setText("关闭");}else{//关闭服务器ser->close();//将文本内容改成启动ui->start->setText("启动");}
}//处理newConnection信号的槽函数实现
void Widget::newConnect_slot()
{qDebug () << "有客户端发来连接请求了,请尽快处理";//获取最新链接的客户端套接字,并将最新连接的套接字地址返回QTcpSocket* socket = ser->nextPendingConnection();//将该客户端套接字放入到客户端容器中cliList.append(socket);//当有客户端向服务器发来数据时,当前这个客户端套接字就会自动发射一个readyRead信号//我们可以将该信号连接到对应的信号处理函数中,处理相关数据connect(socket,&QTcpSocket::readyRead,this,&Widget::readyRead_slot);}void Widget::readyRead_slot()
{//判断客户端容器汇中,是否有已经退出的客户端,或者无效的客户端,如果有将其移除for(int i = 0;i<cliList.length();i++){if(cliList[i]->state() == QTcpSocket::UnconnectedState){//功能:判断当前套接字状态//参数:无//返回值:readyRead_slot表示无效的套接字cliList.removeAt(i);    //将下标为i的客户端套接字从容器中移除}}//再将客户端容器遍历一遍,判断哪个客户端中有数据待读for(int i = 0;i<cliList.length();i++){//功能:获取当前套接字中待读取数据的个数//参数:无//返回值:返回套接字中待读取数据的个数,如果为0,表示没有数据可读//如果不等于0,表示有数据可读,可以使用readAll读取数据QByteArray msg = cliList[i]->readAll();//将该信息,展示到ui界面上ui->msg->addItem(msg);//将该消息转发到所有客户端for(int j = 0;j<cliList.length();j++){if(i != j){cliList[j]->write(msg);}}}
}

客户端头文件

#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:Widget(QWidget *parent = nullptr);~Widget();private slots:void on_connectBtn_clicked();void connected_slot();void on_sendBtn_clicked();void readyRead_slot();void disconnectes_slot();private:Ui::Widget *ui;QTcpSocket *cli;QString username;
};
#endif // WIDGET_H

客户端源文件

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//实例化一个客户端对象cli = new QTcpSocket(this);//将客户端的connected信号连接到自定义的槽函数中connect(cli,&QTcpSocket::connected,this,&Widget::connected_slot);
}Widget::~Widget()
{delete ui;
}//连接服务器按钮对应的槽函数
void Widget::on_connectBtn_clicked()
{if(ui->connectBtn->text() == "连接服务器"){//执行连接服务器的工作//获取ui界面上的数据username = ui->userEdit->text();QString ip = ui->ipEdit->text();quint16 port = ui->portEdit->text().toUInt();//向服务器发送连接请求cli->connectToHost(ip,port);//功能:向指定的服务器发送连接请求//参数1:服务器ip地址//参数2:服务器端口号//当成功连接到服务器后,当前客户端会自动发射一个connected信号,我们可以将该信号连接到服务器//由于该操作只需进行一次即可,所以写在构造函数中即可//将按钮内容更改为断开服务器ui->connectBtn->setText("断开服务器");}else{//执行断开服务器工作//将按钮内容更改成连接服务器ui->connectBtn->setText("连接服务器");}
}//自定义处理connected信号的槽函数的实现
void Widget::connected_slot()
{QMessageBox::information(this,"连接","连接服务器成功");
}//信息发送按钮对应的槽函数
void Widget::on_sendBtn_clicked()
{//将ui界面上的文本信息获取下来QString msg = username + ":" + ui->msgEdit->text();//将该消息发送给服务器cli->write(msg.toLocal8Bit());//清空行编辑器中的内容ui->msgEdit->clear();//将消息放入ui界面中QListWidgetItem *item = new QListWidgetItem(msg);item->setTextAlignment(Qt::AlignRight);ui->listWidget->addItem(item);
}//处理readyRead信号对应的槽函数的实现
void Widget::readyRead_slot()
{//将客户端套接字中的消息读取出来QByteArray msg = cli->readAll();//将该消息展示到ui界面ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}//disconnected信号对应的槽函数
void Widget::disconnectes_slot()
{QMessageBox::information(this,"断开","断开服务器成功");
}

sql头文件

#ifndef WIDGET_H
#define WIDGET_H#include <QWidget>
#include <QSqlDatabase> //数据库管理类
#include <QSqlQuery>    //数据库查询类
#include <QSqlRecord>   //记录类
#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_searchBtn_clicked();private:Ui::Widget *ui;//实例化一个数据库操作对象QSqlDatabase db;
};
#endif // WIDGET_H

sql源文件

#include "widget.h"
#include "ui_widget.h"Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget)
{ui->setupUi(this);//判断当前数据库操作对象中,是否包含了要处理的数据库if(!db.contains("mydb.db")){//添加一个数据库到当前的数据库对象中db = QSqlDatabase::addDatabase("QSQLITE");  //表示使用的是sqlite3数据库//给数据库设置名字db.setDatabaseName("mydb.db");}//此时已经创建了该数据库但是还没有打开if(!db.open()){QMessageBox::information(this,"失败","数据库打开失败");return;}//程序执行至此,说明数据库打开成功//准备sql语句QString sql = "create table if not exists Stu(name char,numb int,sex char,score double)";//实例化一个sql语句的执行者QSqlQuery query;if(!query.exec(sql)){QMessageBox::information(this,"提示","创建数据表失败");return;}
}Widget::~Widget()
{delete ui;
}//添加学员信息按钮对应的槽函数
void Widget::on_addBtn_clicked()
{//将ui界面上的相关信息获取下来QString ui_name = ui->nameEdit->text();int ui_number = ui->numberEdit->text().toUInt();QString ui_sex = ui->sexEdit->text();double ui_score = ui->scoreEdit->text().toDouble();//判断是否有空的没有填写的数据if(ui_name == NULL || ui_number == 0 || ui_sex == NULL || ui_score == 0){QMessageBox::information(this,"提示","有内容没有填写");return;}//准备sql语句QString sql = QString("insert into Stu values('%1',%2,'%3',%4)").arg(ui_name).arg(ui_number).arg(ui_sex).arg(ui_score);//实例化一个sql语句的执行者QSqlQuery query;if(!query.exec(sql)){QMessageBox::information(this,"提示","添加数据失败");return;}else{QMessageBox::information(this,"提示","添加数据成功");return;}
}//查找按钮对应的槽函数
void Widget::on_searchBtn_clicked()
{QString sql;//准备sql语句if(ui->nameEdit->text() == NULL){sql = "select * from Stu";}else{sql = QString("select '%1' from Stu").arg(ui->nameEdit->text());}//执行sql语句//实例化一个sql语句的执行者QSqlQuery query;if(!query.exec(sql)){QMessageBox::information(this,"提示","查询数据失败");return;}//将查询结果展示到ui界面上int i = 0;while(query.next()){//这里面是一个任意的查询结果,query对象中保存的是当前的一个记录//可以通过成员函数:QSqlRecord QSqlQuery::record() const//通过QSqlRecord类的成员函数:count,来获取当前记录中的列数//通过调用QSqlRecord类的成员函数:value(i),来获取下标为i列的那一项的数据值for(int j = 0;j < query.record().count();j++){qDebug() << query.record().value(j).toString();//将数据库中的数据,依次存放到ui界面中ui->tableWidget->setItem(i, j, new QTableWidgetItem(query.record().value(j).toString()));}i++;}
}

思维导图

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

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

相关文章

论文阅读_RAG融合现有知识树_T-RAG

英文名称: T-RAG: LESSONS FROM THE LLM TRENCHES 中文名称: T-RAG&#xff1a;来自LLM战壕的经验教训 链接: https://arxiv.org/abs/2402.07483 作者: Masoomali Fatehkia, Ji Kim Lucas, Sanjay Chawla 机构: 卡塔尔计算研究所, 哈马德本哈利法大学 日期: 2024-02-12 引用次数…

零基础HTML教程(32)--HTML5语义化标签

文章目录 1. div时代2. div的缺点3. 语义化标签4. 语义化标签有哪些5. 实战演练6. 小结 1. div时代 我是2009年开始学习网页开发的&#xff0c;那时候HTML里面到处是div。 这么说吧&#xff0c;那时候div就是网页的骨架&#xff0c;支撑着网页的主结构。 2. div的缺点 div作…

conan2 基础入门(02)-安装

conan2 基础入门(02)-安装 文章目录 conan2 基础入门(02)-安装⭐前言⭐安装python安装安装包安装自行操作 ⭐验证配置环境变量命令行验证conan配置文件 END ⭐前言 Conan 2.0: C and C Open Source Package Manager 官方提供三种安装conan的方式。分别为&#xff1a; Recommen…

Raspberry Pi Connect 官方树莓派远程连接新方式

系列文章目录 前言 2024 年 5 月 7 日 戈登-霍林沃思 今天&#xff0c;我们很高兴地宣布 Raspberry Pi Connect 测试版发布&#xff1a;这是一种安全、易用的方法&#xff0c;只需使用网络浏览器&#xff0c;就能从地球上的任何地方远程访问您的 Raspberry Pi。 远程访问 Rasp…

数据结构----二叉树

博主主页: 码农派大星. 关注博主带你了解更多数据结构知识 1. 树型结构 1.1 概念 树是一种非线性的数据结构&#xff0c;它是由n&#xff08;n>0&#xff09;个有限结点组成一个具有层次关系的集合。把它叫做树是因为它看起来像一棵倒挂的树&#xff0c;也就是说它是根朝上…

Git克隆仓库报错:HTTP/2 stream 1 was not closed

报错及原因 fatal: unable to access ‘https://github.com/xxx/’: HTTP/2 stream 1 was not closed cleanly before end of the underlying stream http/2 和 http/1.1之间有个区别是“HTTP2 基于 SPDY&#xff0c;专注于性能&#xff0c;最大的一个目标是在用户和网站间只…

[leetcode] 68. 文本左右对齐

文章目录 题目描述解题方法贪心java代码复杂度分析 题目描述 给定一个单词数组 words 和一个长度 maxWidth &#xff0c;重新排版单词&#xff0c;使其成为每行恰好有 maxWidth 个字符&#xff0c;且左右两端对齐的文本。 你应该使用 “贪心算法” 来放置给定的单词&#xff…

第五十八节 Java设计模式 - 适配器模式

Java设计模式 - 适配器模式 我们在现实生活中使用适配器很多。例如&#xff0c;我们使用存储卡适配器连接存储卡和计算机&#xff0c;因为计算机仅支持一种类型的存储卡&#xff0c;并且我们的卡与计算机不兼容。 适配器是两个不兼容实体之间的转换器。适配器模式是一种结构模…

Linux进程——进程地址空间

前言&#xff1a;在讲完环境变量后&#xff0c;相信大家对Linux有更进一步的认识&#xff0c;而Linux进程概念到这也快接近尾声了&#xff0c;现在我们了解Linux进程中的地址空间&#xff01; 本篇主要内容&#xff1a; 了解程序地址空间 理解进程地址空间 探究页表和虚拟地址空…

具备教学意义的实操(用队列实现栈)

225. 用队列实现栈 - 力扣&#xff08;LeetCode&#xff09;https://leetcode.cn/problems/implement-stack-using-queues/description/ 实现逻辑 一个是先进先出&#xff08;队列&#xff09;&#xff0c;一个是后进先出&#xff08;栈&#xff09; 这里用两个队列导入一下数据…

实体同城商家短视频获客,3天直播课,玩转实体商家私域,引爆门店增长

课程内容&#xff1a; 实体同城3天直播课【资料】 实体商家获客第一天 .mp4 实体商家获客第二天上.mp4 实体商家获客第二天,mp4 实体商家获客第三天.mp4 实体商家获客第4天.mp4 网盘自动获取 链接&#xff1a;https://pan.baidu.com/s/1lpzKPim76qettahxvxtjaQ?pwd0b8x…

什么是翘尾因素

在有关CPI 的分析文章和新闻稿件中&#xff0c;经常会出现“翘尾因素”或“翘尾影响” 等词汇&#xff0c;这是分析同比价格指数变动幅度时所特有的概念。那么什么是“翘尾因素” 或“翘尾影响”呢&#xff1f; 一、什么是翘尾因素 “翘尾因素”是指上年价格上涨&#xff08;…