QT 系统学习 day04 事件(鼠标,键盘), UDP 通信, TCP 通信,多个定时器,重写绘画事件

1. 事件  (有 键盘按下, 鼠标按下, 鼠标双击等)

 1.重写键盘按下事件,

  函数: void keyPressEvent(QKeyEvent *event)    /*** 按键按下事件 ***/

   代码:

 void keyPressEvent(QKeyEvent *event) /*** 按键按下事件 ***/
    {
        qDebug() << "按下的按键个数:" << event->count() << endl;
        qDebug() << "按下的按键码:" << event->key() << endl; // 按键码需要参考 Qt:Key 按键枚举表
        qDebug() << "按下的按键字符:" << event->text() << endl; // 按下按键的字符
    }

   2.重写键盘 按键松开事件

函数: void keyReleaseEvent(QKeyEvent *event) /*** 按键松开事件 ***/

 void keyReleaseEvent(QKeyEvent *event) /*** 按键松开事件 ***/
    {
        qDebug() << "松开的按键个数:" << event->count() << endl;
        qDebug() << "松开的按键码:" << event->key() << endl; // 按键码需要参考 Qt:Key 按键枚举表
        qDebug() << "松开的按键字符:" << event->text() << endl; // 按下按键的字符
    }

3.重写 鼠标按下事件

函数:void mousePressEvent(QMouseEvent *event) /*** 鼠标按下事件 ***/

代码:

void mousePressEvent(QMouseEvent *event) /*** 鼠标按下事件 ***/
    {
        /***** 案例:我的鼠标有 左键,右键,前进键和后退键 ****/
        switch ((unsigned int)event->button()) { // 获取按下的按键
        case Qt::LeftButton:
                mouse_flag = true;
                qDebug() << "鼠标左键按下" << endl;
            break;
        case Qt::RightButton:
                qDebug() << "鼠标右键按下" << endl;

                //Menu->exec(QCursor::pos());         //QCursor::pos()获取鼠标的全局坐标
                //Menu->exec(event->globalPos());       //event->globalPos()获取鼠标的全局坐标
            break;
        case Qt::BackButton:
                qDebug() << "鼠标后退键按下" << endl;
            break;
        case Qt::ForwardButton:
                qDebug() << "鼠标前进键按下" << endl;
            break;
        case Qt::MiddleButton:
                qDebug() << "鼠标中间滚轮键按下" << endl;
            break;
        }
    }

4.重写 鼠标松开事件

函数: void mouseReleaseEvent(QMouseEvent *event)     /*** 鼠标松开事件 ***/

代码:

void mouseReleaseEvent(QMouseEvent *event)     /*** 鼠标松开事件 ***/
    {
        /***** 案例:我的鼠标有 左键,右键,前进键和后退键 ****/
        switch ((unsigned int)event->button()) { // 获取松开的按键
        case Qt::LeftButton:
                mouse_flag = false;
                qDebug() << "鼠标左键松开" << endl;
            break;
        }
    }

5.重写鼠标双击事件

函数:void mouseDoubleClickEvent(QMouseEvent *event); /*** 鼠标双击事件 ***/

代码:

void mouseDoubleClickEvent(QMouseEvent *event)//鼠标双击事件
    {
        qDebug()<<"鼠标双击事件";
    }

6.重写鼠标移动事件

函数:void mouseMoveEvent(QMouseEvent *event);        /*** 鼠标移动事件 ***/

代码:

因为要用到 this 所以我们在 .h 文件里面声明,.cpp 文件里面实现 .


void Widget::mouseMoveEvent(QMouseEvent *event)
{
    /***** 思考:为什么需要按键按下并鼠标移动才触发时间 ? ****
     * QWidget 默认关闭焦点,所以需要打开焦点
     * 使用这个函数:this->setMouseTracking(true); // 设置鼠标焦点使能
     * ***********************************************/
    if(this->mouse_flag)
    {
        qDebug() << "全局坐标:" << event->globalPos() << endl;//全局变量是整个电脑屏幕 处在的位置
        qDebug() << "局部坐标:" << event->localPos() << endl;//局部变量是自己打开的窗口的处在的位置
        
    }
}

7.重写鼠标中间/滚轮事件

函数:  void wheelEvent(QWheelEvent *event)            /*** 鼠标中间/滚轮事件 ***/

代码:

 void wheelEvent(QWheelEvent *event)            /*** 鼠标中间/滚轮事件 ***/
    {
        /**** 获取滚动的距离 ******
         * QPoint angleDelta()
         * ******************************************************/
        QPoint point = event->angleDelta(); //获取距离
        qDebug() << "距离:" << point.y() << endl;
        qDebug() << "方向:" << (point.y() >= 0 ? "向前" : "向后") << endl;
    }

8.重写定时器事件 

函数:  void timerEvent(QTimerEvent *)

代码:

#include <QTimerEvent>//定时器事件
public: /*** 定时器事件 ****/
    void timerEvent(QTimerEvent *)
    {
        static int count = 0;
        //qDebug() << "闹钟的数量:" << ++count << endl;
    }

启动定时器事件的 代码

   /***** 定时器事件 *******/
    this->startTimer(1000); // 1000 毫秒 = 1秒钟 , 计数到1秒则触发事件 timerEvent

9. 重写绘图事件  (画圆,画点,画线,)

函数:  void paintEvent(QPaintEvent *) /**** 绘图事件 ***/

代码:

void paintEvent(QPaintEvent *) /**** 绘图事件 ***/
    {
        QPainter p(this);
        /***** 画刷 ********************************/
        QBrush Brush = p.brush(); // 获取画家手上的刷子
        Brush.setColor(QColor(255,0,0));
        p.setBrush(Brush);

        /***** 画笔 ********************************/
        QPen Pen = p.pen();
        Pen.setColor(QColor(0,255,0)); //设置画笔颜色
        Pen.setWidth(4); //设置画笔大小
        Pen.setStyle(Qt::DashLine); //设置画笔样式
        p.setPen(Pen);
        p.setFont(QFont("宋体",16));
        /**** 绘制形状 ****/
        p.drawPoint(200,200); //画点
        p.drawLine(QPoint(100,100),QPoint(200,200)); //画线
        p.drawRect(100,100,100,100); //画矩形 drawRect(int x, int y, int w, int h)
        p.drawEllipse(QPoint(150,150),50,50); //画圆 (const QPoint &center, int rx, int ry)
        p.drawImage(QPoint(200,200),QImage("://QQ图片20221125090254.png"));//画一张图片

        Pen.setColor(QColor(0,0,255)); //设置画笔颜色
        p.setPen(Pen);
        p.setFont(QFont("宋体",16));
        p.drawText(QPoint(300,20),"老师的牛逼");//形成一个文本框,里面写了 文字
    }


2.多个定时器

#include <QTimer> //定时器类

#include <QTime> //时间类

1. 定义指针的变量     QTimer *Timer1;//定时器类对象

2.实列化对象    Timer1 = new QTimer(this);

3.建立信号连接 等定时器到了时间就, 发出信号     connect(Timer1,SIGNAL(timeout()),this,SLOT(slot_Timer1()));

4. 打开定时器  Timer1->start(100); // 100毫秒 = 0.1 毫秒 , 计数到0.1秒则触发 timeout() 信号


3.   将控件安装事件过滤器  (就是发生了事件  上面的事件都算, 重新交给一个人来处理,。  本来是交给他的父类的!! )

1.给控件加上  一个捕获事件的能力,(本来捕获事件的能力都是 widget 界面的)

  ui->progressBar->grabKeyboard();//设置键盘捕获事件

2.给控件安装事件过滤器

  /*** 将控件安装事件过滤器 ***/
    ui->progressBar->installEventFilter(this);;; //ui->progressBar 进度条控件的事件交给 Widget 去处理

   3.设置控件获取焦点 (因为平时焦点都是在 界面上 ,而我们需要让 控件获取焦点的能力)

焦点窗口

所谓的焦点窗口,指的是当前时刻拥有键盘输入的窗口。

补充两个概念,活动窗口和前景窗口。活动窗口,指的是当前时刻与用户进行交互的窗口;前景窗口,指的是显示器最顶层窗口,前景窗口永远在其他窗口上方,不被遮挡。
设置焦点可以让应用更便捷。比如当你打开百度主页或其他带有编辑框的页面时,不需要先用鼠标点击编辑框就可以直接输入文字等信息到其中。这就是由于 搜索框设置了焦点。
这就是说 有了焦点,我们把鼠标放到控件上,窗口就知道我们操作的是 控件,假如没有焦点,那么窗口就不知道。
  ui->progressBar->setFocus();//控件获取焦点

4.重写 事件过滤器

函数:bool eventFilter(QObject *watched, QEvent *event); /**** 事件过滤 ****/

代码:


#include <QDebug> /*** 调试类 ***/
#include <QProgressBar> /*** 进度条类 ***/
#include <QKeyEvent>    /*** 按键事件类 ****/
/*** 注意事项:没有处理就返回false,处理了就返回true   完成了也可以返回 false 可以让下一级来操作  ***/
bool Widget::eventFilter(QObject *watched, QEvent *event)
{
    if(watched == ui->progressBar) // 说明是我的 进度条控件 发出的事件
    {
        QProgressBar *ProgressBar = (QProgressBar *)watched;//把类型强转
        /*** QEvent 事件基类中有一个 type() 函数获取事件的类型,可以参考 QEvent::Type 枚举表 ****/
        if(event->type() == QEvent::KeyPress) /*** 按键事件 ****/
        {
            qDebug() << "进度条控件发出事件" << endl;
            QKeyEvent *KeyEvent = (QKeyEvent *)event;
            qDebug() << "按下的按键:" << KeyEvent->text() << endl;
            int x = ProgressBar->x();
            int y = ProgressBar->y();

            switch ((unsigned int)KeyEvent->key()) {
            case Qt::Key_Up:
                    ProgressBar->move(x,y-10);return true;
            case Qt::Key_Down:
                    ProgressBar->move(x,y+10);return true;
            case Qt::Key_Left:
                    ProgressBar->move(x-10,y);return true;
            case Qt::Key_Right:
                    ProgressBar->move(x+10,y);return true;
            }
        }
    }

    return false; /*** 没有处理 ***/
}


4.UDP 网络连接

1.在学习UDP的时候,我们需要在

 2. 学习UDP  的建立步骤

1.头文件 : #include <QUdpSocket> /*** 网络模块 ***/
                        #include <QMessageBox> /** 标准对话框 ***/

 2. 建立UDP 网络套接字对象   QUdpSocket *UdpSocket; 

3.实列话对象  UdpSocket = new QUdpSocket(this);

4. 知道 UDP 的函数 并且运用 


/******************* QUdpSocket 类 ******************
 * 绑定:
 *      ip地址和端口号 : bool bind(const QHostAddress &address, quint16 port = 0, BindMode mode = DefaultForPlatform);

 *      默认本地ip:     bool bind(quint16 port = 0, BindMode mode = DefaultForPlatform);
 * 发送:qint64 writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port)

 * 接收:qint64 readDatagram(char *data, qint64 maxlen, QHostAddress *host = Q_NULLPTR, quint16 *port = Q_NULLPTR);
 * 

信号函数:
 *      套接字有数据可读 : void readyRead()
 * **************************************************/

5. UDP 绑定 IP  和端口号 

我才用的 是 默认本地ip  的绑定


void Udp::slot_pushButton_bind()
{
    QString ip = ui->lineEdit_ip_bind->text();//获取自己写的 ip 地址
    int port = ui->lineEdit_port_bind->text().toInt();//获取端口号

    bool ok = false;//判断自己是否写了 ip 地址
    if(ip.isEmpty() == true)
    {
        ok = UdpSocket->bind(port);//采用默认 IP地址绑定。
    }else
    {
        ok = UdpSocket->bind(QHostAddress(ip),port);//采取 自己写的 ip 地址和 端口号 来绑定
    }

    if(ok == true)
    {
        ui->pushButton_bind->setText("绑定成功");
        ui->pushButton_bind->setEnabled(false);
    }
    else
    {
        QMessageBox::warning(this,"绑定警告","绑定失败,端口号以被使用");//警告消息对话框
    }
}

  6. UDP 发送数据

函数: writeDatagram(参数1,参数2,参数3) 

参数1,数据。 (类型需要转 UTF-8)

参数2 , 目标用户的 ip  

参数3   , 目标用户的port 

代码:

void Udp::slot_pushButton_send()
{
    QString ip = ui->lineEdit_ip_send->text();//获取  目标 的IP
    int port = ui->lineEdit_port_send->text().toInt();获取 目标的port 
    QString text = ui->textEdit_write->toPlainText();// 获取发送的内容

    UdpSocket->writeDatagram(text.toUtf8(),QHostAddress(ip),port);//发送数据
}

7.UDP 接收信息,

1. 首先建立连接 

connect(UdpSocket,SIGNAL(readyRead()),this,SLOT(slot_UdpSocket_readyRead()));

参数1 : UDP 的指针, 参数2  有数据可以接收的信号,  

参数3   界面指针             参数4  自己写的槽函数,接收数据

2.直接接收数据


void Udp::slot_UdpSocket_readyRead()
{
    char *buf = new char[1024]; /*** 申请空间 ***/
    memset(buf,0,1024);//清除空间,防止有脏数据
    QHostAddress host; //对方的主机
    quint16 port;      //对方的端口

    UdpSocket->readDatagram(buf,1024,&host,&port);//我这里有一个疑问,接收的空间 ,没有数据大咋办,一次接收后,还会有第二次接收吗??
    ui->textEdit_read->append(buf);

    delete buf; /*** 释放空间 ***/
}


5.TCP 网络传输数据  (服务器部分)

1.头文件

#include <QTcpServer>   /** TCP 服务器类 ***/
#include <QTcpSocket>   /** TCP 套接字类 ***/

2. 建立TCP  网络套接字对象   QTcpServer *sevser

3.实列话对象   sevser = new QTcpServer(this);

4. 知道 TCP 服务器  的函数 并且运用 


/********** QTcpServer 服务器类 *******
 * ①绑定监听 : bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
 * ②等待响应|用户连入信号 : void newConnection()
 * ③接入已挂起的客户端 : QTcpSocket *QTcpServer::nextPendingConnection()
 * **********************************************************************************/
/********** QTcpSocket 套接字类 ********
 * 连接: void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)
 * 断开: void disconnectFromHost()
 * 读取:
 *      QByteArray read(qint64 maxSize)     指定读取长度
 *      QByteArray readAll()                读取全部内容
 * 写入:
 *      qint64 write(const char *data)              发送字符串内容
 *      qint64 write(const QByteArray &byteArray)   发送QByteArray内容
 * 信号:
 *      void readyRead() 有数据可读发出信号
 *      void connected() 连接成功信号
 *      void disconnected() 断开连接信号
 * 数据函数:
 *      qint64 QAbstractSocket::readBufferSize() 缓存区大小
 *                              ***** 缓冲区可读内容长度
 *
 * 获取IP地址:QHostAddress peerAddress() const
 * 获取端口号:quint16 peerPort() const
 * ***************************************************************************************/
/********************* QHostAddress 类 ***************************************************
 * QHostAddress::Any 枚举值,双栈协议
 * QString QHostAddress::toString() const 的ip地址转字符串
 * **************************************************************************************/

5. 申请服务器TCP类空间 QTcpServer*  TcpServer = new QTcpServer(this);


6. TCP  绑定 ip 和端口号 

函数 :listen(QHostAddress::Any,port); 

参数1    QHostAddress类提供一个IP地址。

QHostAddress类  这个类提供一种独立于平台和协议的方式来保存IPv4和IPv6地址。

参数2  这个电脑可以绑定的 端口号 

代码:

void TCPsever::slot_pushButton_bind()
{
    QString ip = ui->lineEdit_ip->text();
    int port = ui->lineEdit_port->text().toInt();

    TcpServer->listen(QHostAddress::Any,port); //双栈绑定
}

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

7.为客户的连接 建立信号连接 (目的 当有客户连接的时候,我们可以知道并且获取 客户的 ip 和 端口号 )

  connect(TcpServer,SIGNAL(newConnection()),this,SLOT(slot_TcpServer()));

void TCPsever::slot_TcpServer()
{
    QTcpSocket *TcpSocket = TcpServer->nextPendingConnection(); //去读已连接客户端挂起的第一个

    TcpSockets.push_back(TcpSocket); //同步插入
    {//获取套接字内部的IP地址和端口号
        QHostAddress hostaddr = TcpSocket->peerAddress(); /** 获取主机信息 **/

        QString ip = hostaddr.toString();
        int port = TcpSocket->peerPort();

        QString PORT = QString::number(port);
        ui->listWidget->addItem(ip + " - " + PORT);//同步插入
    }


    connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(slot_TcpSocket_readyRead()));
}

参数1    TCP类空间的指针 , 参数2  用户连接信号

8.读取数据 建立连接  

connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(slot_TcpSocket_readyRead()));

参数1   TCP类空间的指针      参数2  有数据可以读取的信号函数

9.发送过来的数据读取

代码:

void TCPsever::slot_TcpSocket_readyRead()
{
    QTcpSocket *TcpSocket = (QTcpSocket *)sender();
    QByteArray buf = TcpSocket->readAll();

    ui->textEdit->append(buf);
}


代码:

头文件:

#ifndef TCPSEVER_H
#define TCPSEVER_H

#include <QWidget>
#include <QTcpServer>   /** TCP 服务器类 ***/
#include <QTcpSocket>   /** TCP 套接字类 ***/
#include <QList> /*** 列表容器 ***/
namespace Ui {
class TCPsever;
}

class TCPsever : public QWidget
{
    Q_OBJECT

public:
    explicit TCPsever(QWidget *parent = nullptr);
    ~TCPsever();

private:
    Ui::TCPsever *ui;
    QTcpServer *TcpServer; // 服务器对象指针
    QList<QTcpSocket*> TcpSockets;/*** 存储连入的客户端套接字 ***/
public slots:
    void slot_TcpServer();
    void slot_TcpSocket_readyRead();
    void slot_pushButton_bind();
};

#endif // TCPSEVER_H

.cpp 文件

#include "tcpsever.h"
#include "ui_tcpsever.h"

/********** QTcpServer 服务器类 *******
 * ①绑定监听 : bool listen(const QHostAddress &address = QHostAddress::Any, quint16 port = 0)
 * ②等待响应|用户连入信号 : void newConnection()
 * ③接入已挂起的客户端 : QTcpSocket *QTcpServer::nextPendingConnection()
 * **********************************************************************************/
/********** QTcpSocket 套接字类 ********
 * 连接: void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)
 * 断开: void disconnectFromHost()
 * 读取:
 *      QByteArray read(qint64 maxSize)     指定读取长度
 *      QByteArray readAll()                读取全部内容
 * 写入:
 *      qint64 write(const char *data)              发送字符串内容
 *      qint64 write(const QByteArray &byteArray)   发送QByteArray内容
 * 信号:
 *      void readyRead() 有数据可读发出信号
 *      void connected() 连接成功信号
 *      void disconnected() 断开连接信号
 * 数据函数:
 *      qint64 QAbstractSocket::readBufferSize() 缓存区大小
 *                              ***** 缓冲区可读内容长度
 *
 * 获取IP地址:QHostAddress peerAddress() const
 * 获取端口号:quint16 peerPort() const
 * ***************************************************************************************/
/********************* QHostAddress 类 ***************************************************
 * QHostAddress::Any 枚举值,双栈协议
 * QString QHostAddress::toString() const 的ip地址转字符串
 * **************************************************************************************/
TCPsever::TCPsever(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TCPsever)
{
    ui->setupUi(this);

    /***** 申请服务器TCP类空间 ****/
    TcpServer = new QTcpServer(this);
    /***** 连接信号槽 ************/
    connect(TcpServer,SIGNAL(newConnection()),this,SLOT(slot_TcpServer()));
    connect(ui->pushButton,SIGNAL(clicked(bool)),this,SLOT(slot_pushButton_bind()));
}


void TCPsever::slot_pushButton_bind()
{
    QString ip = ui->lineEdit_ip->text();
    int port = ui->lineEdit_port->text().toInt();

    TcpServer->listen(QHostAddress::Any,port); //双栈绑定
}

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

void TCPsever::slot_TcpServer()
{
    QTcpSocket *TcpSocket = TcpServer->nextPendingConnection(); //去读已连接客户端挂起的第一个

    TcpSockets.push_back(TcpSocket); //同步插入
    {//获取套接字内部的IP地址和端口号
        QHostAddress hostaddr = TcpSocket->peerAddress(); /** 获取主机信息 **/

        QString ip = hostaddr.toString();
        int port = TcpSocket->peerPort();

        QString PORT = QString::number(port);
        ui->listWidget->addItem(ip + " - " + PORT);//同步插入
    }


    connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(slot_TcpSocket_readyRead()));
}

void TCPsever::slot_TcpSocket_readyRead()
{
    QTcpSocket *TcpSocket = (QTcpSocket *)sender();
    QByteArray buf = TcpSocket->readAll();

    ui->textEdit->append(buf);
}




6.TCP 网络传输数据  (客户端部分)

这里只有函数可以讲

1.建立对象,并且实列化对象   QTcpSocket *TcpSocket; /*** TCP套接字类指针 **/ 

                                                     TcpSocket = new QTcpSocket(this);  

2.关于客户端的函数, 

/********** QTcpSocket 套接字类 ********
 * 连接: void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)
 * 断开: void disconnectFromHost()
 * 读取:
 *      QByteArray read(qint64 maxSize)     指定读取长度
 *      QByteArray readAll()                读取全部内容
 * 写入:
 *      qint64 write(const char *data)              发送字符串内容
 *      qint64 write(const QByteArray &byteArray)   发送QByteArray内容
 * 信号:
 *      void readyRead() 有数据可读发出信号
 *      void connected() 连接成功信号
 *      void disconnected() 断开连接信号
 * 数据函数:
 *      qint64 QAbstractSocket::readBufferSize() 缓存区大小
 *                              ***** 缓冲区可读内容长度
 * ***************************************************************************************/

3.连接服务端 

函数:void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)

参数1  IP   参数2  端口号

代码:

void TCPclient::slot_pushButton_connect()
{
    QString ip = ui->lineEdit_ip->text();//获取要连接的服务器的 ip 
    int port = ui->lineEdit_port->text().toInt();//获取要连接的服务器的 端口号

    TcpSocket->connectToHost(QHostAddress(ip),port);//连接服务器
}

4. 为连接服务器成功做准备, 主要是建立一个信号连接,来知道,与服务器连接成功了

 connect(TcpSocket,SIGNAL(connected()),this,SLOT(slot_TcpSocket_connected()));

第二个参数 是 一个连接服务器成功的信号, 

代码:


void TCPclient::slot_TcpSocket_connected()
{
    ui->pushButton_connect->setText("连接成功");
    ui->pushButton_send->setEnabled(true); //使能发送按钮
}

5.为服务器断开连接做准备, 主要是建立一个信号连接,来知道,与服务器服务器断开连接了

 connect(TcpSocket,SIGNAL(disconnected()),this,SLOT(slot_TcpSocket_disconnected()));

代码:

void TCPclient::slot_TcpSocket_disconnected()
{
    ui->pushButton_connect->setText("已断开连接");
    ui->pushButton_send->setEnabled(false); //使能发送按钮
}

6.客户端向服务端发送数据 

函数:write(text.toUtf8());

代码:


void TCPclient::slot_pushButton_send()
{
    QString text = ui->textEdit_send->toPlainText();//读取要发送的数据
    TcpSocket->write(text.toUtf8());//向服务器发送数据
}

7.客户端 读取 服务端发送的数据 

建立连接

 connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(slot_TcpSocket_readyRead()));//和之前一样

代码:

void TCPclient::slot_TcpSocket_readyRead()
{
    QByteArray buf = TcpSocket->readAll();//读取数据
    ui->textEdit_read->append(buf);
}


头文件:

#ifndef TCPCLIENT_H
#define TCPCLIENT_H

#include <QWidget>
#include <QTcpSocket> /*** TCP套接字类 ***/
namespace Ui {
class TCPclient;
}

class TCPclient : public QWidget
{
    Q_OBJECT

public:
    explicit TCPclient(QWidget *parent = nullptr);
    ~TCPclient();

private:
    Ui::TCPclient *ui;
    QTcpSocket *TcpSocket; /*** TCP套接字类指针 **/

public slots:
    void slot_TcpSocket_readyRead();
    void slot_pushButton_connect();
    void slot_TcpSocket_connected();
    void slot_TcpSocket_disconnected();
    void slot_pushButton_send();
};

#endif // TCPCLIENT_H

.cpp 文件

#include "tcpclient.h"
#include "ui_tcpclient.h"
/********** QTcpSocket 套接字类 ********
 * 连接: void connectToHost(const QHostAddress &address, quint16 port, OpenMode openMode = ReadWrite)
 * 断开: void disconnectFromHost()
 * 读取:
 *      QByteArray read(qint64 maxSize)     指定读取长度
 *      QByteArray readAll()                读取全部内容
 * 写入:
 *      qint64 write(const char *data)              发送字符串内容
 *      qint64 write(const QByteArray &byteArray)   发送QByteArray内容
 * 信号:
 *      void readyRead() 有数据可读发出信号
 *      void connected() 连接成功信号
 *      void disconnected() 断开连接信号
 * 数据函数:
 *      qint64 QAbstractSocket::readBufferSize() 缓存区大小
 *                              ***** 缓冲区可读内容长度
 * ***************************************************************************************/
TCPclient::TCPclient(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::TCPclient)
{
    ui->setupUi(this);

    TcpSocket = new QTcpSocket(this);

    /****** 连接信号槽 *******/
    connect(TcpSocket,SIGNAL(readyRead()),this,SLOT(slot_TcpSocket_readyRead()));
    connect(ui->pushButton_connect,SIGNAL(clicked(bool)),this,SLOT(slot_pushButton_connect()));
    connect(TcpSocket,SIGNAL(connected()),this,SLOT(slot_TcpSocket_connected()));
    connect(TcpSocket,SIGNAL(disconnected()),this,SLOT(slot_TcpSocket_disconnected()));
    connect(ui->pushButton_send,SIGNAL(clicked(bool)),this,SLOT(slot_pushButton_send()));
}

#include <QHostAddress>
void TCPclient::slot_pushButton_connect()
{
    QString ip = ui->lineEdit_ip->text();
    int port = ui->lineEdit_port->text().toInt();

    TcpSocket->connectToHost(QHostAddress(ip),port);
}

void TCPclient::slot_TcpSocket_connected()
{
    ui->pushButton_connect->setText("连接成功");
    ui->pushButton_send->setEnabled(true); //使能发送按钮
}

void TCPclient::slot_TcpSocket_disconnected()
{
    ui->pushButton_connect->setText("已断开连接");
    ui->pushButton_send->setEnabled(false); //使能发送按钮
}

void TCPclient::slot_pushButton_send()
{
    QString text = ui->textEdit_send->toPlainText();
    TcpSocket->write(text.toUtf8());
}


void TCPclient::slot_TcpSocket_readyRead()
{
    QByteArray buf = TcpSocket->readAll();
    ui->textEdit_read->append(buf);
}







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

  • 1
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值