qt day 5

2023-11-07

实现局域网的网络聊天室功能

 1>服务器代码

---------------------------------------------------------------
widget.h
---------------------------------------------------------------
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QMessageBox>
#include <QTcpServer>
#include <QTcpSocket>
#include <QPushButton>
#include <QLabel>
#include <QListWidget>
#include <QLineEdit>
#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 connectbtn_slot();
    void connected_slot();
    void readyread_slot();

private:
    Ui::Widget *ui;

    //定义服务器
    QTcpServer *server;

    //定义一个链表存放连接的客户端数据
    QList<QTcpSocket *> client;

};
#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);

    //实例化服务器
    server = new QTcpServer(this);


    //连接按钮与对应槽函数
    connect(ui->connectbtn,&QPushButton::clicked,this,&Widget::connectbtn_slot);

}

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

//按下按钮后启动服务器
void Widget::connectbtn_slot()
{
    //读取端口号
    quint16 port = ui->portedit->text().toInt();
    //设置为监听状态
    if(!server->listen(QHostAddress::Any,port))
    {
        QMessageBox::critical(this,"失败","服务器启动失败");
        return ;
    }
    QMessageBox::information(this,"成功","服务器启动成功");

    //连接客户端信号与槽函数
    connect(server,&QTcpServer::newConnection,this,&Widget::connected_slot);
}

//客户端连接槽函数
void Widget::connected_slot()
{
    //获取客户端套接字
    QTcpSocket *cli = server->nextPendingConnection();

    //将得到的套接字写入链表
    client.push_back(cli);
    //把新套接字与接收信号连接
    connect(cli,&QTcpSocket::readyRead,this,&Widget::readyread_slot);

}

//有信息写入准备读取
void Widget::readyread_slot()
{
    //删除已经断开的客户端
    for(int i = 0;i < client.size();i++)
    {
        if(client.at(i)->state() == 0)
        {
            client.removeAt(i);
        }
    }

    //遍历发送数据的客户端
    for(int i = 0;i < client.size();i++)
    {
        if(client.at(i)->bytesAvailable() != 0)
        {
            //读取客户端数据
            QByteArray msg = client.at(i)->readAll();
            //将数据写到ui界面中
            ui->listWidget->addItem(QString::fromLocal8Bit(msg));
            //将数据发送给所有客户端
            for(int j = 0;j < client.size();j++)
            {
                client.at(j)->write(msg);
            }
        }
    }

}

2>客户端代码

---------------------------------------------------------------
widget.h
---------------------------------------------------------------
#ifndef WIDGET_H
#define WIDGET_H

#include <QWidget>
#include <QTcpSocket>
#include <QPushButton>
#include <QLabel>
#include <QLineEdit>
#include <QListWidget>
#include <QMessageBox>

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 connectbtn_slot();
    void connected_slot();
    void readyread_slot();
    void sndbtn_slot();
    void disconbtn_slot();
    void disconnect_slot();

private:
    Ui::Widget *ui;

    //定义一个客户端套接字
    QTcpSocket *client;
    //定义一个用户名
    QString username;
};
#endif // WIDGET_H
---------------------------------------------------------------
widget.h
---------------------------------------------------------------
#include "widget.h"
#include "ui_widget.h"

Widget::Widget(QWidget *parent)
    : QWidget(parent)
    , ui(new Ui::Widget)
{
    ui->setupUi(this);
    //为客户端套接字实例化空间
    client = new QTcpSocket(this);
    //连接按钮与对应槽函数连接
    connect(ui->connectbtn,&QPushButton::clicked,this,&Widget::connectbtn_slot);
    //已连接信号与对应槽函数连接
    connect(client,&QTcpSocket::connected,this,&Widget::connected_slot);
    //服务器发送信息信号与对应槽函数连接
    connect(client,&QTcpSocket::readyRead,this,&Widget::readyread_slot);
    //发送按钮与对应槽函数连接
    connect(ui->sndbtn,&QPushButton::clicked,this,&Widget::sndbtn_slot);
    //断开按钮与对应槽函数
    connect(ui->disconbtn,&QPushButton::clicked,this,&Widget::disconbtn_slot);
    //断开连接信号与对应槽函数
    connect(client,&QTcpSocket::disconnected,this,&Widget::disconnect_slot);
    //设置按钮与编辑框可用
    ui->disconbtn->setEnabled(0);
    ui->sndbtn->setEnabled(0);
    ui->msgedit->setEnabled(0);

}

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

//连接按钮槽函数
void Widget::connectbtn_slot()
{
    //从ui界面读取IP与port
    QString IP = ui->IPedit->text();
    quint16 port = ui->portedit->text().toUInt();
    //连接服务器
    client->connectToHost(IP,port);
}

//已连接槽函数
void Widget::connected_slot()
{
    //连接完成提示信息
    QMessageBox::information(this,"成功","成功进入聊天室");
    //发送xx进入聊天室提示给服务器
    username = ui->usernameedit->text();
    QString sndmsg = username + " : 进入聊天室";
    client->write(sndmsg.toLocal8Bit());

    //设置按钮与编辑框可用
    ui->usernameedit->setEnabled(0);
    ui->IPedit->setEnabled(0);
    ui->portedit->setEnabled(0);
    ui->connectbtn->setEnabled(0);
    ui->sndbtn->setEnabled(1);
    ui->msgedit->setEnabled(1);
    ui->disconbtn->setEnabled(1);

}

//读取服务器发送信息
void Widget::readyread_slot()
{
    //读取信息
    QByteArray msg = client->readAll();
    //将读取的信息发送到信息框内
    ui->listWidget->addItem(QString::fromLocal8Bit(msg));
}

//发送按钮对应槽函数
void Widget::sndbtn_slot()
{
    //读取ui界面发送框内信息
    QString msg = ui->msgedit->text();
    msg = username + " : " + msg;
    //将数据发送给服务器
    client->write(msg.toLocal8Bit());
}

//断开连接按钮对应槽函数
void Widget::disconbtn_slot()
{
    //准备发送离开信息
    QString msg = username + " : 离开聊天室";
    client->write(msg.toLocal8Bit());
    //断开连接
    client->disconnectFromHost();
}

//断开连接信号槽函数
void Widget::disconnect_slot()
{
    QMessageBox::information(this,"断开连接","成功退出聊天室");
    //设置按钮与编辑框可用
    ui->usernameedit->setEnabled(1);
    ui->IPedit->setEnabled(1);
    ui->portedit->setEnabled(1);
    ui->connectbtn->setEnabled(1);
    ui->disconbtn->setEnabled(0);
    ui->sndbtn->setEnabled(0);
    ui->msgedit->setEnabled(0);
}

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

qt day 5 的相关文章

随机推荐

  • 分布式理论-拜占庭将军(译)

    作者 LESLIE LAMPORT ROBERT SHOSTAK and MARSHALL 1982 译者 phylips bmy 出处 http duanple blog 163 com blog static 7097176720112
  • springBoot 拦截器

    声明 代码是JavaEE开发的颠覆者 Spring Boot实战代码中的 我买了这书 并练习 public class DemoInterceptor extends HandlerInterceptorAdapter 1 Override
  • 笔录getResource() 与 getClassLoader().getResource()

    结论 1 Class getResource String path path路径的前缀不是 表示从此类所在的包下取资源文件 path路径的前缀是 则是从ClassPath根下获取资源文件 Class getResource和Class g
  • python seleium b站 自动投币脚本

    主要是给我的投币器做个铺垫 果然软件还是太容易了 难在硬件和外壳好吗 1 把edge的调试端口打开 添加以下参数 C Program Files x86 Microsoft Edge Application msedge exe remot
  • 在express项目里配置ejs模板引擎

    方法1 修改app js view engine setup app set views path join dirname views app set view engine ejs 在views中创建ejs模板文件 方法2 修改app
  • 老年人晕倒的几种原因

    晕倒是一种突发性 短暂性 一过性的意识丧失而昏倒 突然性的晕倒 跟大脑的神经有分不开关系 癫痫 脑供血不足 心脑血管疾病都是引起头晕倒的原因 大脑血液上不来 脑血液突然停止 就会产生放电波头晕的症状 患者会在一时间出现晕倒 很容易引起脑震荡
  • 在conda虚拟环境中的PyQt配置以及相关Pycharm设置

    文章目录 在conda虚拟环境中的PyQt配置 背景环境介绍 PyQt依赖包及PyQt tools的下载 Pycharm进行PyQt的相关配置 结语 在conda虚拟环境中的PyQt配置 作者 下龙湾 背景环境介绍 anaconda安装文件
  • Netty4简单认知

    Channel简介 在Netty中 Channel相当于一个Socket的抽象 它为用户提供了关于Socket状态 是连接还是断开 及对Socket的读 写等操作 每当Netty建立了一个连接 都创建一个与其对应的Channel实例 Cha
  • 各种排序算法的讲解与实现

    排序的分类 1 内部排序 内部排序 在整个排序过程中不需不访问外存便能完成 称这样的排序问题为内部排序 1 1 插入排序 插入排序 将无序序列中的一个或几个记录 插入 到有序的序列中 从而增加记录的有序序列的长度 主要思想是将第一个元素看做
  • 3D重建模的初步了解

    相关学习资料如下 cousera课程 https www coursera org learn robotics perception youtube课程 https www youtube com watch v RDkwklFGMfo
  • 什么是HTTPS

    首先 在参考 Tomcat内核设计剖析 大型网站技术架构 的基础上加了一些个人理解 如有错误或者不全面的地方 还请大家指出 在知道什么是HTTPS之前 我们首先要知道一下什么是HTTP HTTP是超文本传输协议的简称 工作在应用层 传输层基
  • linux上好玩的东西

    Figlet 想知道tmux安装与配置评论加点赞 想要我这个效果吗 安装figlet mac安装 brew install figlet brew 没有的可以看我之前的文章 ma配置 linux ubuntu deepin sudo apt
  • 最易上手的测试用例设计方法

    NO 1 lt lt 测试用例设计方法 gt gt 以下是八种常见的测试用例设计方法 包括等价类 边界值 判定表 因果图 正交实验 状态迁移图 场景法和错误推测 详述如下 等价类划分法 Equivalence Partitioning 策略
  • C++新特性16_写时拷贝(解决浅拷贝在某一个类对象中的资源进行修改,所有引用该资源的对象全部会被修改的问题;解决办法:在所有改变值的地方,重新分配内存,改变的是拷贝的值,而不影响原有对象中共享资源)

    C 新特性16 写时拷贝 1 问题 如果共享资源中的值发生了变化 那么其他使用该共享资源的值如何保持不变 2 解决思路 使用引用计数时 当发生共享资源值改变的时候 需要对其资源进行重新的拷贝 这样改变的是拷贝的值 而不影响原有的对象中的共享
  • 母版页禁用Enter提交表单

    在母版页里面由于使用了form 常常需要禁用enter提交表单 因为内容页或者母版页自身有如果有type submit 的button 当textbox聚焦时 按下enter都会触发表单的默认提交 不论是IE还是firefox 于是需要在o
  • python json串合并

    获取cookie def get login cookies self str1 str2 str3 str4 str5 str6 try 必须要有的cookie字段 var items bizuin data bizuin data ti
  • 1*1卷积核的作用及其应用举例

    1 降维和升维 通过使用 1x1 卷积核 可以改变输入张量的通道数 当输入张量的通道数较大时 使用 1x1 卷积核进行卷积操作可以将通道数减小 从而降低模型的计算复杂度 相反 如果需要增加通道数 也可以使用 1x1 卷积核进行升维操作 im
  • 标签href几种使用

    a标签的最重要功能是实现超链接和锚点 a标签里href属性是我们经常用的 其实它的值有很多种 可能我们往往会忽略 今天分享一下a标签的属性值及用法 1 href 这是一个比较常用的方法 是标签内置的一个方法 用于网页返回顶部较多 比如在底部
  • 深度学习------tensorflow2.0,keras实现CNN(mnist、cifar2、cifar10:ResNet-34、ResNet-18)

    1 ResNet 34卷积神经网络 cifar10 随着网络的加深 出现了训练集准确率下降 错误率上升的现象 就是所谓的 退化 问题 按理说更深的模型不应当比它浅的模型产生更高的错误率 这不是由于过拟合产生的 而是由于模型复杂时 SGD的优
  • qt day 5

    实现局域网的网络聊天室功能 1 gt 服务器代码 widget h ifndef WIDGET H define WIDGET H include