QT day5 作业

news2024/11/17 14:24:45

服务器头文件

#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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    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_NAMESPACE

class Widget : public QWidget
{
    Q_OBJECT

public:
    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.coloradmin.cn/o/1665212.html

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

相关文章

建筑、室内设计师如何利用AI绘画辅助完成一套设计工作流?超长干货深度好文建议收藏!

2023年是AI人工智能突然大爆发的元年 所有行业都受到了AI的冲击 对设计师来说也迎来了新一轮的效率革命 新事物的到来 有人热情学习和接受 也有人担忧害怕和拒绝 担心自己被取代 其实 取代你的并不是AI 而是会使用AI的设计师 常用的AI工具有哪些&#xff1f; 对于设…

基于单片机的直流电机控制方法研究

摘要&#xff1a;分析表明&#xff0c;我国用电设备应用数量的持续增加&#xff0c;单片机在电力领域的应用范围也在不断扩大。基 于对电动机运行转速的有效控制&#xff0c;成为自动控制系统关注的重点。研究单片机控制直流电机运行状态的 方法。 关键词&#xff1a;单片机&a…

KAN网络最全解析——比肩MLP和Transformer?

1 基本思路 1.1 MLP与Spline的优缺点 多层感知器 (MLP)是深度学习的基础理论模块&#xff0c;是目前可用于逼近非线性函数的默认模型&#xff0c;其表征能力已由通用逼近定理证明。但MLP也有明显的缺点&#xff0c;例如在 Transformer中&#xff0c;MLP 的参数量巨大&#xf…

VSCode:隐藏工程中的文件和目录

VSCode&#xff1a;设置搜索时的排除目录_vscode全局搜索排除掉某些目录-CSDN博客 介绍了如何排除搜索目录 有时也需要隐藏工程中不必关注的文件和目录。 假设工程中的文件结构如下 $ tree . ├── doc │ └── readme.txt ├── m.cpp └── user_guide 可以通过如下方…

关于Matplotlib如何在网页中使用?

目录 一、如何在网页中使用matplotlib 二、如何使用mpld3在网页中显示图表 三、如何使用matplotlibflask在网页中显示图表 一、如何在网页中使用matplotlib Matplotlib是Python中一个非常流行的可视化库。然而&#xff0c;Matplotlib主要是为桌面应用程序设计的&#xff0c;…

llm.c的Makefile

源码 CC ? clang CFLAGS -Ofast -Wno-unused-result -Wno-ignored-pragmas -Wno-unknown-attributes LDFLAGS LDLIBS -lm INCLUDES CFLAGS_COND -marchnative# Find nvcc SHELL_UNAME $(shell uname) REMOVE_FILES rm -f OUTPUT_FILE -o $ CUDA_OUTPUT_FILE -o $# N…

洁净环境微生物监测的解决方案

药品污染控制 Manufacturing 无菌药品生产污染控制意义 01 CCS策略 无菌药品生产污染控制策略&#xff08;CCS) &#xff1a;来自于现行产品和工艺理解&#xff0c;为确保工艺性能和产品质量&#xff0c;所计划的一套体系&#xff0c;针对微生物、热原/内毒素和微粒的控制方…

文本提取新技能:学会按行数批量提取,轻松应对各种需求

在数字化时代&#xff0c;文本处理成为我们日常生活和工作中不可或缺的一部分。无论是从网页、文档还是数据库中提取信息&#xff0c;文本提取技能都显得尤为重要。而按行数批量提取文本内容&#xff0c;更是文本处理中的一项高效且实用的技能。本文将介绍办公提效工具如何按行…

工业机器人应用实践之玻璃涂胶(篇一)

工业机器人 工业机器人&#xff0c;即面向工业领域的机器人。工业机器人是广泛用于工业领域的多关节机械手或多自由度的机器装置&#xff0c;具有一定的自动性&#xff0c;可依靠自身的动力能源和控制能力实现各种工业加工制造功能。工业机器人被广泛应用于电子、物流、化工等…

Verlog-流水灯-FPGA

Verlog-流水灯-FPGA 引言&#xff1a; ​ 随着电子技术的飞速发展&#xff0c;现场可编程门阵列&#xff08;FPGA&#xff09;已成为电子设计自动化&#xff08;EDA&#xff09;领域中不可或缺的组件。FPGA以其高度的灵活性和可定制性&#xff0c;广泛应用于通信、图像处理、工…

【系统分析师】软件架构设计

文章目录 1、构件与软件复用1.1 主流构件标准1.2 构件获取与管理1.3 构件复用的方法 2、软件架构概述3、软件架构建模4、软件架构风格4.1 经典架构风格4.2 层次架构风格4.3 富互联网应用-RIA 5、面向服务的架构5.1 SOA概述5.2 SOA的关键技术5.3 SOA的实现方法 6、软件架构评估6…

ARM时钟树结构(GD32)

时钟树的简易框图 初始化配置系统时钟 配置系统初始化时钟&#xff08;参考手册&#xff09; 对应hal库函数 使用72MHz的系统时钟 do -----------while&#xff08;0&#xff09;的使用方法 系统时钟 #include <stdint.h> #include "gd32f30x.h"int main(void)…

实现MYSQL8.3.0 版本流量抓取

实现MYSQL8.3.0 版本流量抓取 根据测试需求&#xff0c;需要抓取MYSQL8.3.0流量包&#xff0c;使用wireshark 数据库客户端实现 安装数据库服务端 这里就不给详细操作方法&#xff0c; 网上教程一大堆&#xff0c;小编这里是最新的MYSQL 8.3.0版本 安装成功后&#xff0c;创…

PyQt6--Python桌面开发(7.QTextEdit多行富文本框控件)

QTextEdit多行富文本框控件 保存文件到本地QLine多行文本框.ui import sys import time from PyQt6.QtGui import QValidator,QIntValidator from PyQt6.QtWidgets import QApplication,QLabel,QLineEdit,QTextEdit from PyQt6 import uic,QtGuiif __name__ __main__:appQApp…

管道液位传感器可以应用在哪些领域

管道液位传感器是一种利用光学原理来检测水管液位的传感器&#xff0c;其工作原理基于光线在水和空气中折射率不同的特性。通过光电管道传感器&#xff0c;可以有效解决传统机械式传感器存在的低精度、卡死失效等问题&#xff0c;同时也避免了电容式传感器因感度衰减而导致的不…

差分信号的前世今生

网上搜索到一篇简洁文章&#xff0c;描述差分信号&#xff0c;我觉得挺好&#xff0c;和大家一起分享&#xff0c;同时也发表个人的浅浅想法。 一、原文摘录 所谓差分方式传输&#xff0c;就是发送端在两条信号线上传输的幅值是相等的&#xff0c;相位是相反的电信号&#xff…

30年赚1000亿美元--“量化之王”和他最传奇的基金“大奖章”的秘密

文艺复兴是华尔街最成功、最神秘的机构之一。从1988-2018年的30年里&#xff0c;文艺复兴仅向内部员工开放的旗舰基金“大奖章”累计创造了超过1000亿美元的收益&#xff0c;年均回报率高达39%。作为对比&#xff0c;同期“股神”巴菲特的年均回报率为20.5%。 而且&#xff0c;…

怎么将一张包含多个帧的精灵图分割成一帧一帧的小图

工具 图片分割 - 图文工具箱 - imgtool.net 设置行列 下载即可

【6大模型让你的沟通汇报更有条理】项目管理常见问题大揭秘 03

6大模型让你的沟通汇报更有条理 虽然头脑中构思众多&#xff0c;一开口却发现空白一片&#xff1f; 工作表现出色&#xff0c;汇报时却总是支支吾吾不知从何说起&#xff1f; 生性腼腆&#xff0c;却难以避免需要站在众人面前发言&#xff1f; 阿道掐指一算&#xff1a;你需…

短剧APP开发,为短剧市场提供更多活力

近年来&#xff0c;短剧一直是一个大热赛道&#xff0c;不仅各大视频平台刮起了一股短剧热潮&#xff0c;各大品牌也纷纷开始进军短剧市场。短剧作为当下的流量密码&#xff0c;深受各大短剧观众与创业者的关注。吸引了大量的资本、制作方涌入到市场中&#xff0c;短剧行业发展…