网络编程TCP/IP/UDP+Http和JSON解析+qt事件软键盘

原文:https://blog.csdn.net/m0_45463480/article/details/124049417

网络编程+Http和JSON解析+qt事件软键盘

  • 第一章 QT中的网络编程
    • 【1】涉及到的类
    • 【2】tcp协议的流程
      • 【2.1】服务器的流程 socket--》bind--》listen--》accept--》send/recv--》close
      • 【2.2】客户端的流程 socket--》bind--》connect--》send/recv--》close
    • 【3】多客户端连接同一个服务器
  • 第二章 QT中的udp通信
    • 【1】涉及到的类
    • 【2】udp流程
      • 【2.1】创建QUdpSocket对象
      • 【2.2】绑定
      • 【2.3】收发信息
  • 第三章 QT中的http协议
    • 【1】http协议的原理
    • 【2】QT提供的http有关的类和方法
      • 【2.1】函数和类
      • 【2.2】创建QNetworkRequest请求
      • 【2.3】发送http请求
      • 【2.4】读取服务器回复的应答信息
    • 【3】举例使用http协议
  • 第四章 JSON数据解析
    • 【1】什么是JSON数据
    • 【2】如何解析json数据(剥洋葱,从外到内,一层层剥皮)
    • 【3】解析json数据的一般思路:
  • 第五章 QT中的事件,事件实现软键盘
    • 【1】什么是事件
    • 【2】QT事件产生的流程
    • 【3】常用的事件类型和处理函数
    • 【4】利用移动事件的处理函数实现
  • 第六章 用QT按键事件实现软键盘
    • 【1】软键盘实现步骤
    • 【2】软键盘实现函数
    • 【3】QT编译最常见的问题
  • 第七章 代码编写,加深印象
    • 【1】tcp单向通信源码【半双工】
      • 【1.1】tcpclient客户端
        • 【1.1.1】tcpclient.pro
        • 【1.1.2】main.c
        • 【1.1.3】MainWindow.h
        • 【1.1.4】 MainWindow.c
        • 【1.1.4】 MainWindow.ui界面设计
      • 【1.2】tcpserver服务器
        • 【1.2.1】main.cpp
        • 【1.2.2】mainwindow.h
        • 【1.2.3】mainwindow.cpp
        • 【1.2.4】mainwindow.ui
    • 【2】tcp双向通信源码【全双工】
      • 【2.1】tcpclient客户端
        • 【2.1.1】main.cpp
        • 【2.1.2】mainwindow.h
        • 【2.1.3】mainwindow.cpp
        • 【2.1.4】mainwindow.ui
      • 【2.2】tcpserver服务器
        • 【2.2.1】main.cpp
        • 【2.2.2】mainwindow.h
        • 【2.2.3】mainwindow.cpp
        • 【2.2.4】mainwindow.ui
    • 【3】http获取天气信息,解析json数据源码
      • 【3.1】main.cpp
      • 【3.2】mainwindow.h
      • 【3.3】mainwindow.cpp
      • 【3.4】mainwindow.ui
    • 【4】事件实现软键盘源码
      • 【4.1】main.c
      • 【4.2】loginwin.h
      • 【4.3】loginwin.cpp
      • 【4.4】loginwin.ui
      • 【4.5】mybutton.h
      • 【4.6】mybutton.cpp
      • 【4.7】mysolfkey.h
      • 【4.8】mysolfkey.cpp
      • 【4.9】mysolfkey.ui
    • 【5】事件流程重写了事件处理函数
      • 【5.1】main.cpp
      • 【5.2】mainwindow.cpp
      • 【5.3】mainwindow.h
      • 【5.4】mainwindow.ui
    • 【6】所有源码分享
  • 第八章 往期内容回顾

第一章 QT中的网络编程

【1】涉及到的类

QTcpServer类  --》表示tcp服务器
QTcpSocket类 --》表示tcp套接字  

添加新的库-
绝大部分类都是在 core gui widgets这三个库里面(QT工程默认也是添加这三个库)-
有些类属于其它的内库,需要主动在pro文件中添加新的内库-
QT += core gui network //添加了network这个新的库

【2】tcp协议的流程

在这里插入图片描述

【2.1】服务器的流程 socket–》bind–》listen–》accept–》send/recv–》close

第一步:创建QTcpServer的对象

QTcpServer(QObject *parent = nullptr)

第二步:绑定和监听

bool QTcpServer::listen(const QHostAddress &address = QHostAddress::Any, quint16 port **加粗样式**= 0)
参数: address --》你要绑定的ip地址
QHostAddress(const QString &address)  //address是你的ip地址
port --》你要绑定的端口号

第三步(重点):如果有新的客户端连接服务器,QTcpServer的对象会自动触发:

[signal] void QTcpServer::newConnection();

程序员关联该信号,在槽函数中实现接下来的逻辑-
在槽函数中实现的逻辑如下:

调用QTcpSocket *QTcpServer::nextPendingConnection()产生新的套接字
返回值:QTcpSocket 就是产生的新套接字

第四步(重点):利用刚才第三步产生的套接字去跟对应的客户端通信–》收发信息

发送信息: qint64 QIODevice::write(const QByteArray &byteArray)
接收信息(要注意,不能直接调用read/readAll去接收信息):QByteArray QIODevice::read(qint64 maxSize)
 QByteArray QIODevice::readAll()

注意,注意,注意:如果对方有发送信息过来,QTcpSocket的对象会产生:

[signal] void QIODevice::readyRead()信号

程序员关联该信号,在槽函数中去接收信息即可-
第五步:关闭

close();

【2.2】客户端的流程 socket–》bind–》connect–》send/recv–》close

第一步:创建QTcpSocket的对象

QTcpSocket(QObject *parent = nullptr)

第二步:绑定自己的ip和端口号

bool QAbstractSocket::bind(const QHostAddress &address, quint16 port = 0)
参数: address --》你要绑定的ip地址
QHostAddress(const QString &address)  //address是你的ip地址
 port --》你要绑定的端口号

第三步:连接服务器

void QAbstractSocket::connectToHost(const QHostAddress &address, quint16 port)
参数: address --》 你要连接的服务器的ip地址
QHostAddress(const QString &address)  
port --》服务器的端口号

第四步:跟服务器通信–》收发信息

发送信息: qint64 QIODevice::write(const QByteArray &byteArray)
接收信息(要注意,不能直接调用read/readAll去接收信息):QByteArray QIODevice::read(qint64 maxSize)
=QByteArray QIODevice::readAll()

注意,注意,注意:如果对方有发送信息过来,QTcpSocket的对象会产生

[signal] void QIODevice::readyRead()信号

程序员关联该信号,在槽函数中去接收信息即可-
第五步:关闭

close();

【3】多客户端连接同一个服务器

(1)获取连接成功的客户端/服务器的ip和端口号

QHostAddress QAbstractSocket::peerAddress() const
返回值:连接成功的客户端/服务器的ip地址
QString QHostAddress::toString() const  //把返回值QHostAddress对象转换成我们熟悉的字符串格式ip地址
quint16 QAbstractSocket::peerPort() const
返回值:连接成功的客户端/服务器的端口号

4.判断客户端/服务器是否断开连接

[signal] void QAbstractSocket::disconnected() 
 //断开连接会自动触发该信号,程序员在槽函数中写代码判断

第二章 QT中的udp通信

【1】涉及到的类

QUdpSocket

【2】udp流程

发送端

【2.1】创建QUdpSocket对象

QUdpSocket::QUdpSocket(QObject *parent = nullptr)

【2.2】绑定

bool QAbstractSocket::bind(const QHostAddress &address, quint16 port = 0)
参数: address --》你要绑定的ip地址
QHostAddress(const QString &address)  //address是你的ip地址
port --》你要绑定的端口号    

【2.3】收发信息

发送:qint64 QUdpSocket::writeDatagram(const QByteArray &datagram, const QHostAddress &host, quint16 port)
返回值:发送的字节数   
参数:datagram --》存放你要发送的内容
           host --》对方的ip
           port --》对方的端口号
接收:qint64 QUdpSocket::readDatagram(char *data, qint64 maxSize)
返回值:成功收到的字节数
参数:data --》存放接收的内容
          maxSize --》你打算接收多少字节的数据

注意,注意,注意:如果对方有发送信息过来,QUdpSocket的对象会产生

[signal] void QIODevice::readyRead()信号

程序员关联该信号,在槽函数中去接收信息即可

第三章 QT中的http协议

在这里插入图片描述

【1】http协议的原理

学习前端的同学需要重点掌握的一种应用层的通信协议

http协议的底层就是tcp

比如:张同学通过360浏览器登录QQ的官方网站-
360浏览器:tcp客户端-
QQ的官网服务器: tcp服务器-
你在浏览器中输入:www.qq.com(域名或者URL地址) --》会被浏览器解析成QQ服务器的ip地址和端口号

【2】QT提供的http有关的类和方法

【2.1】函数和类

QNetworkRequest   --》表示http请求
QNetworkAccessManager  --》管理http请求(发送http请求)
QNetworkReply --》表示http的应答

【2.2】创建QNetworkRequest请求

QNetworkRequest(const QUrl &url)
参数:url --》你要访问的网址
               QUrl(const QString &url)  //url就是网址www.csdn.net

【2.3】发送http请求

QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)
参数:request --》你要发送的http请求

【2.4】读取服务器回复的应答信息

关键点:我如何得知服务器真的回复了应答信息 给我????-
方法:如果服务器应答成功QNetworkAccessManager对象会自动触发

[signal] void QNetworkAccessManager::finished(QNetworkReply *reply)信号

程序员主动关联该信号,在槽函数里面读取应答信息即可

QNetworkReply类中:  QByteArray QIODevice::readAll() 读取应答信息

【3】举例使用http协议

例子一:http请求下载网络上的图片

bool QPixmap::loadFromData(const QByteArray &data)
             参数:data --》从网上下载的图片原始数据

注意:图片的网址需要把https中的s去掉

 https  有加密
 http    没有加密

例子二:http请求获取网络上的天气预报-
http://www.weather.com.cn/data/cityinfo/101010100.html

第四章 JSON数据解析

在这里插入图片描述

【1】什么是JSON数据

json数据:一种人为制定的数据格式,在计算机前端开发中经常使用这种格式的数据,保存信息很方便-
json数据只能由数组,对象,键值对三种构成-
对象:用{}来表示,可以嵌套其他两种数据 { {},{}} {键值对} {[数组]} {{},[]}-
数组:用[]来表示,数组里面只能存放相同类型的数据 [1,2,3] [{},{},{}] [键值对,键值对,键值对]-
键值对:用键:值表示, 键只能是字符串,值可以是任意合法类型-
星期一:1-
星期二:2-
张三:123456-
李四:789456

【2】如何解析json数据(剥洋葱,从外到内,一层层剥皮)

json数据在解析之前,程序员必须要提前知道json数据的构成,否则无法解析-
QT提供了如下几个类帮助大家解析json数据:

QJsonDocument --》把json数据标准化存储
QJsonObject   --》对象
QJsonArray    --》数组
QJsonValue    --》值
QJsonParseError --》保存出错信息

【3】解析json数据的一般思路:

第一步:把json数据标准化存储

[static] QJsonDocument QJsonDocument::fromJson(const QByteArray &json, QJsonParseError *error = Q_NULLPTR)
返回值:QJsonDocument对象存放标准化之后的json数据
参数:json --》你要存储的原始json数据
error --》存放出错信息

第二步:严格按照你看到的json数据的结构一步步解析json数据(从整体到局部,一层层剥洋葱)

QJsonObject QJsonDocument::object() const   //获取json数据中的对象
QJsonArray QJsonDocument::array() const     //获取json数据中的数组
QJsonValue QJsonObject::value(const QString &key) const  //通过键得到对应的值
返回值:跟键对应的值
参数:key --》键
QJsonObject QJsonValue::toObject() const   //把键值对中的值进行转换,转换成对象
int QJsonValue::toInt() const                          //把键值对中的值进行转换,转换成整数
QJsonArray QJsonValue::toArray() const       //把键值对中的值进行转换,转换成数组

总结:QJsonValue类中提供了大量的toxxxxx()方法,原因是键值对中的值可以是任意合法的数据类型,需要我们去转换

第五章 QT中的事件,事件实现软键盘

在这里插入图片描述

【1】什么是事件

用户对于QT程序所做的一切行为动作–>都称之为事件-
比如:用户用鼠标把窗口拉大,拉小 --》窗口大小改变事件-
用户用鼠标拖动窗口 --》移动事件-
用户按了键盘 --》按键事件-
用户鼠标点击窗口 --》鼠标事件-
用户关闭窗口 --》关闭事件

QEvent:  所有事件类的父类

【2】QT事件产生的流程

详情见截图

【3】常用的事件类型和处理函数

事件类型                         枚举值                                             事件处理函数
QCloseEvent  --》     QEvent::Close                                --》void QWidget::closeEvent(QCloseEvent *event)        //关闭窗口对应的处理函数
QFocusEvent --》     QEvent::FocusIn                             --》void QWidget::focusInEvent(QFocusEvent *event)   //键盘输入光标进入对应的处理函数
QMouseEvent --》   QEvent::MouseButtonDblClick     --》void QWidget::mouseDoubleClickEvent(QMouseEvent *event)  //鼠标双击事件的处理函数
 QEvent::MouseButtonPress                 void QWidget::mouseMoveEvent(QMouseEvent *event)   //鼠标移动对应的处理函数
 QEvent::MouseButtonRelease             void QWidget::mousePressEvent(QMouseEvent *event)   //鼠标按下对应的处理函数
 QEvent::MouseMove                            void QWidget::mouseReleaseEvent(QMouseEvent *event)  //鼠标松开对应的处理函数
QKeyEvent --》         QEvent::KeyPress                           --》 void QWidget::keyPressEvent(QKeyEvent *event)     //按键按下去
 QEvent::KeyRelease                              void QWidget::keyReleaseEvent(QKeyEvent *event) //按键松开   
                                                                              int QKeyEvent::key()  //获取按键的键值(QT助手有详细介绍)
                                                                              QString QKeyEvent::text()  //返回按键的字面值  
QMoveEvent--》       QEvent::Move                                --》 void QWidget::moveEvent(QMoveEvent *event)    //移动窗口对应的处理函数

【4】利用移动事件的处理函数实现

当我用鼠标拖动窗口的时候,窗口背景色的颜色会随机变换-
QT中产生随机数

int qrand()                --》类似rand()
void qsrand(uint seed)     --》类似srand()

第六章 用QT按键事件实现软键盘

【1】软键盘实现步骤

第一步: 【设计好软键盘的ui(模板选择QWidget,原因是软键盘等会要嵌套到主窗口中)】

在ui把按钮的focusPolicy属性设置成Nofocus

第二步:在主窗口中拖一个QWidget容器过来,然后右键点击QWidget,选择提升为你刚才创建的那个软键盘类型-
第三步:写代码实现软键盘可以正常使用

思路一:传统思路,利用信号与槽实现软键盘的功能 (把所有的信号关联槽函数,一个个去判断)-
思路二:使用按键事件来实现软键盘的功能

【2】软键盘实现函数

在QT工程中新建一个自定义的按钮类,继承QPushButton,然后右键把你的软键盘上所有的按钮都提升为这个类

QKeyEvent::QKeyEvent(QEvent::Type type, int key, Qt::KeyboardModifiers modifiers, const QString &text = QString())
参数:   type --》事件类型 QEvent::KeyPress 
key --》按键的键值   字母的键值就是大写字面的ASCII码值
modifiers --》有没有使用组合键  
                        Qt::NoModifier          没有使用组合键
                        Qt::ShiftModifier       使用了shift
                        Qt::ControlModifier  使用了ctrl
                        Qt::AltModifier          使用了alt
text --》按键的字面值

获取鼠标光标停留的组件(鼠标光标停留在哪个组件上,该函数就返回这个组件的地址指针)

[static] QWidget *QApplication::focusWidget()
返回值:鼠标停留的组件地址

【3】QT编译最常见的问题

在这里插入图片描述

第七章 代码编写,加深印象

【1】tcp单向通信源码【半双工】

【1.1】tcpclient客户端

【1.1.1】tcpclient.pro

QT       += core gui network

greaterThan(QT_MAJOR_VERSION, 4): QT += widgets

CONFIG += c++11

# The following define makes your compiler emit warnings if you use
# any Qt feature that has been marked deprecated (the exact warnings
# depend on your compiler). Please consult the documentation of the
# deprecated API in order to know how to port your code away from it.
DEFINES += QT_DEPRECATED_WARNINGS

# You can also make your code fail to compile if it uses deprecated APIs.
# In order to do so, uncomment the following line.
# You can also select to disable deprecated APIs only up to a certain version of Qt.
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000    # disables all the APIs deprecated before Qt 6.0.0

SOURCES += \
    main.cpp \
    mainwindow.cpp

HEADERS += \
    mainwindow.h

FORMS += \
    mainwindow.ui

# Default rules for deployment.
qnx: target.path = /tmp/$${TARGET}/bin
else: unix:!android: target.path = /opt/$${TARGET}/bin
!isEmpty(target.path): INSTALLS += target

【1.1.2】main.c

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

【1.1.3】MainWindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_linkbt_clicked();

    void on_sendbt_clicked();

private:
    Ui::MainWindow *ui;
    QTcpSocket *mysock;
};
#endif // MAINWINDOW_H

【1.1.4】 MainWindow.c

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //设置窗口标题
    setWindowTitle("我是客户端");
    //初始化套接字对象
    mysock=new QTcpSocket(this);
    //绑定客户端自己的ip和端口号
    mysock->bind(QHostAddress("192.168.24.2"),20000);
}

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

//连接服务器
void MainWindow::on_linkbt_clicked()
{
    //获取输入的服务器ip和端口号
    QString str1=ui->iple->text();
    QString str2=ui->portle->text();
    //连接服务器
    mysock->connectToHost(QHostAddress(str1),str2.toInt());
}
//发送信息
void MainWindow::on_sendbt_clicked()
{
    //获取客户端输入的信息
    QString buf=ui->textEdit_2->toPlainText();
    //发送给服务器
    mysock->write(buf.toUtf8());
}

【1.1.4】 MainWindow.ui界面设计

把这段代码赋值进你创建的ui文件,编译之后会自动生成图标的

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLineEdit" name="iple">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>10</y>
      <width>211</width>
      <height>41</height>
     </rect>
    </property>
    <property name="placeholderText">
     <string>服务器ip</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="portle">
    <property name="geometry">
     <rect>
      <x>240</x>
      <y>10</y>
      <width>141</width>
      <height>41</height>
     </rect>
    </property>
    <property name="placeholderText">
     <string>服务器端口号</string>
    </property>
   </widget>
   <widget class="QPushButton" name="linkbt">
    <property name="geometry">
     <rect>
      <x>390</x>
      <y>10</y>
      <width>111</width>
      <height>41</height>
     </rect>
    </property>
    <property name="text">
     <string>连接服务器</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>120</y>
      <width>311</width>
      <height>411</height>
     </rect>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit_2">
    <property name="geometry">
     <rect>
      <x>410</x>
      <y>120</y>
      <width>311</width>
      <height>411</height>
     </rect>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>90</y>
      <width>241</width>
      <height>21</height>
     </rect>
    </property>
    <property name="text">
     <string>显示收到的信息</string>
    </property>
   </widget>
   <widget class="QPushButton" name="sendbt">
    <property name="geometry">
     <rect>
      <x>410</x>
      <y>80</y>
      <width>171</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>发送信息</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

ui界面设计:-
在这里插入图片描述

【1.2】tcpserver服务器

【1.2.1】main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

【1.2.2】mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void newClientLink();
    void recvclientmsg();

private:
    Ui::MainWindow *ui;
    QTcpServer *myserver;
    QTcpSocket *sock;
};
#endif // MAINWINDOW_H

【1.2.3】mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //设置标题
    setWindowTitle("我是服务器");
    //初始化QTcpServer的对象
    myserver=new QTcpServer(this);
    //绑定和监听
    myserver->listen(QHostAddress("192.168.24.2"),10000);
    //关联newConnection信号
    connect(myserver,SIGNAL(newConnection()),this,SLOT(newClientLink()));
}

MainWindow::~MainWindow()
{
    delete ui;
}
//如果有新的客户端连接成功,该槽函数会被自动调用
void MainWindow::newClientLink()
{
    qDebug()<<"有新的客户端连接成功了";
    //产生新的套接字
    sock=myserver->nextPendingConnection();
    //反面教材,直接接收信息
    //QByteArray buf=sock->readAll();  错误错误错误

    //关联readyRead()信号
    connect(sock,SIGNAL(readyRead()),this,SLOT(recvclientmsg()));
}

//专门用来接收某个客户端信息的槽函数
void MainWindow::recvclientmsg()
{
    //接收信息
    QByteArray buf=sock->readAll();
    //在文本编辑框中显示出来
    //ui->textEdit->setText(buf);  setText会自动清空覆盖原来显示的信息
    ui->textEdit->append(buf);
}

【1.2.4】mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QTextEdit" name="textEdit">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>90</y>
      <width>321</width>
      <height>461</height>
     </rect>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>50</y>
      <width>311</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>显示收到的信息</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit_2">
    <property name="geometry">
     <rect>
      <x>400</x>
      <y>90</y>
      <width>341</width>
      <height>461</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>400</x>
      <y>50</y>
      <width>201</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>发送信息</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

ui界面设计-
在这里插入图片描述

【2】tcp双向通信源码【全双工】

【2.1】tcpclient客户端

【2.1.1】main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

【2.1.2】mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_linkbt_clicked();

    void on_sendbt_clicked();
    void recvservermsg();

private:
    Ui::MainWindow *ui;
    QTcpSocket *mysock;
};
#endif // MAINWINDOW_H

【2.1.3】mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //设置窗口标题
    setWindowTitle("我是客户端");
    //初始化套接字对象
    mysock=new QTcpSocket(this);
    //绑定客户端自己的ip和端口号
    mysock->bind(QHostAddress("192.168.24.2"),20000);
    //关联readyRead()信号
    connect(mysock,SIGNAL(readyRead()),this,SLOT(recvservermsg()));
}

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

//连接服务器
void MainWindow::on_linkbt_clicked()
{
    //获取输入的服务器ip和端口号
    QString str1=ui->iple->text();
    QString str2=ui->portle->text();
    //连接服务器
    mysock->connectToHost(QHostAddress(str1),str2.toInt());
}
//发送信息
void MainWindow::on_sendbt_clicked()
{
    //获取客户端输入的信息
    QString buf=ui->textEdit_2->toPlainText();
    //发送给服务器
    mysock->write(buf.toUtf8());
}
//专门接收服务器发送过来的信息
void MainWindow::recvservermsg()
{
    QByteArray buf=mysock->readAll();
    //在文本编辑框中显示出来
    ui->textEdit->append(buf);
}

【2.1.4】mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLineEdit" name="iple">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>10</y>
      <width>211</width>
      <height>41</height>
     </rect>
    </property>
    <property name="placeholderText">
     <string>服务器ip</string>
    </property>
   </widget>
   <widget class="QLineEdit" name="portle">
    <property name="geometry">
     <rect>
      <x>240</x>
      <y>10</y>
      <width>141</width>
      <height>41</height>
     </rect>
    </property>
    <property name="placeholderText">
     <string>服务器端口号</string>
    </property>
   </widget>
   <widget class="QPushButton" name="linkbt">
    <property name="geometry">
     <rect>
      <x>390</x>
      <y>10</y>
      <width>111</width>
      <height>41</height>
     </rect>
    </property>
    <property name="text">
     <string>连接服务器</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>120</y>
      <width>311</width>
      <height>411</height>
     </rect>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit_2">
    <property name="geometry">
     <rect>
      <x>410</x>
      <y>120</y>
      <width>311</width>
      <height>411</height>
     </rect>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>90</y>
      <width>241</width>
      <height>21</height>
     </rect>
    </property>
    <property name="text">
     <string>显示收到的信息</string>
    </property>
   </widget>
   <widget class="QPushButton" name="sendbt">
    <property name="geometry">
     <rect>
      <x>410</x>
      <y>80</y>
      <width>171</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>发送信息</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

界面设计-
在这里插入图片描述

【2.2】tcpserver服务器

【2.2.1】main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

【2.2.2】mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTcpServer>
#include <QTcpSocket>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
private slots:
    void newClientLink();
    void recvclientmsg();

    void on_sendbt_clicked();

private:
    Ui::MainWindow *ui;
    QTcpServer *myserver;
    QTcpSocket *sock;
};
#endif // MAINWINDOW_H

【2.2.3】mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QHostAddress>
#include <QDebug>

MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //设置标题
    setWindowTitle("我是服务器");
    //初始化QTcpServer的对象
    myserver=new QTcpServer(this);
    //绑定和监听
    myserver->listen(QHostAddress("192.168.24.2"),10000);
    //关联newConnection信号
    connect(myserver,SIGNAL(newConnection()),this,SLOT(newClientLink()));
}

MainWindow::~MainWindow()
{
    delete ui;
}
//如果有新的客户端连接成功,该槽函数会被自动调用
void MainWindow::newClientLink()
{
    qDebug()<<"有新的客户端连接成功了";
    //产生新的套接字
    sock=myserver->nextPendingConnection();
    //反面教材,直接接收信息
    //QByteArray buf=sock->readAll();  错误错误错误

    //关联readyRead()信号
    connect(sock,SIGNAL(readyRead()),this,SLOT(recvclientmsg()));
}

//专门用来接收某个客户端信息的槽函数
void MainWindow::recvclientmsg()
{
    //接收信息
    QByteArray buf=sock->readAll();
    //在文本编辑框中显示出来
    //ui->textEdit->setText(buf);  setText会自动清空覆盖原来显示的信息
    ui->textEdit->append(buf);   //append会追加信息显示,不会覆盖之前显示的信息
}

//发送信息给客户端
void MainWindow::on_sendbt_clicked()
{
    //获取文本编辑框中输入的内容
    QString str=ui->textEdit_2->toPlainText();
    //发送给客户端
    sock->write(str.toUtf8());
}

【2.2.4】mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QTextEdit" name="textEdit">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>90</y>
      <width>321</width>
      <height>461</height>
     </rect>
    </property>
   </widget>
   <widget class="QLabel" name="label">
    <property name="geometry">
     <rect>
      <x>20</x>
      <y>50</y>
      <width>311</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>显示收到的信息</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit_2">
    <property name="geometry">
     <rect>
      <x>400</x>
      <y>90</y>
      <width>341</width>
      <height>461</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="sendbt">
    <property name="geometry">
     <rect>
      <x>400</x>
      <y>50</y>
      <width>201</width>
      <height>31</height>
     </rect>
    </property>
    <property name="text">
     <string>发送信息</string>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

界面设计-
在这里插入图片描述

【3】http获取天气信息,解析json数据源码

【3.1】main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

【3.2】mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QNetworkAccessManager>
#include <QNetworkReply>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();

private slots:
    void on_pushButton_clicked();
    void recvhttp(QNetworkReply *);

private:
    Ui::MainWindow *ui;
    QNetworkAccessManager manager;
};
#endif // MAINWINDOW_H

【3.3】mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QNetworkRequest>
#include <QUrl>
#include <QPixmap>
#include <QJsonDocument>
#include <QJsonParseError>
#include <QJsonObject>
#include <QJsonArray>
#include <QJsonValue>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
    //关联finished信号
    connect(&manager,SIGNAL(finished(QNetworkReply *)),this,SLOT(recvhttp(QNetworkReply *)));
}

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

//获取天气预报的按钮
void MainWindow::on_pushButton_clicked()
{
    //获取输入框中的网址
    QString str=ui->lineEdit->text();
    QUrl url(str);
    //创建http请求
    QNetworkRequest req(url);

    //发送该请求
    manager.get(req);
}
//接收服务器回复的应答信息
void MainWindow::recvhttp(QNetworkReply *reply)
{
    //读取http应答信息
   QByteArray buf=reply->readAll();
   //由于我现在是从网上获取天气预报信息,buf中的数据就是天气预报数据
  // ui->textEdit->setText(buf);
   //天气预报数据是json格式,我来解析一下
   //把获取的json数据标准化存储
   QJsonParseError myerr;
   QJsonDocument mydoc=QJsonDocument::fromJson(buf,&myerr);

   //剥洋葱
   //获取最外面的对象
   QJsonObject obj=mydoc.object();
   //obj存放的就是"weatherinfo":{"city":"北京","cityid":"101010100","temp1":"18℃","temp2":"31℃","weather":"多云转阴","img1":"n1.gif","img2":"d2.gif","ptime":"18:00"}
    //继续获取键值对中的键和值
   QJsonValue val=obj.value("weatherinfo");
   //val存放的就是{"city":"北京","cityid":"101010100","temp1":"18℃","temp2":"31℃","weather":"多云转阴","img1":"n1.gif","img2":"d2.gif","ptime":"18:00"}
   QJsonObject  obj1=val.toObject();
   //obj1存放的就是"city":"北京","cityid":"101010100","temp1":"18℃","temp2":"31℃","weather":"多云转阴","img1":"n1.gif","img2":"d2.gif","ptime":"18:00"
   QJsonValue val1=obj1.value("city");
   qDebug()<<val1.toString();

   QJsonValue val2=obj1.value("temp1");
   qDebug()<<val2.toString();

   QJsonValue val3=obj1.value("temp2");
   qDebug()<<val3.toString();

}

【3.4】mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLineEdit" name="lineEdit">
    <property name="geometry">
     <rect>
      <x>40</x>
      <y>20</y>
      <width>571</width>
      <height>41</height>
     </rect>
    </property>
    <property name="placeholderText">
     <string>请输入天气预报网址</string>
    </property>
   </widget>
   <widget class="QPushButton" name="pushButton">
    <property name="geometry">
     <rect>
      <x>650</x>
      <y>20</y>
      <width>111</width>
      <height>41</height>
     </rect>
    </property>
    <property name="text">
     <string>获取天气</string>
    </property>
   </widget>
   <widget class="QTextEdit" name="textEdit">
    <property name="geometry">
     <rect>
      <x>40</x>
      <y>90</y>
      <width>721</width>
      <height>471</height>
     </rect>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

界面设计:-
在这里插入图片描述

【4】事件实现软键盘源码

这里有多个界面,是因为需要多个界面之间跳转,玩过手机的都知道,划过来划过去,其实就是创建了Qt设计师界面,相当于一个类,创建方法:-
在这里插入图片描述

【4.1】main.c

#include "loginwin.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    loginwin w;
    w.show();
    return a.exec();
}

【4.2】loginwin.h

#ifndef LOGINWIN_H
#define LOGINWIN_H

#include <QMainWindow>

QT_BEGIN_NAMESPACE
namespace Ui { class loginwin; }
QT_END_NAMESPACE

class loginwin : public QMainWindow
{
    Q_OBJECT

public:
    loginwin(QWidget *parent = nullptr);
    ~loginwin();

private:
    Ui::loginwin *ui;
};
#endif // LOGINWIN_H

【4.3】loginwin.cpp

#include "loginwin.h"
#include "ui_loginwin.h"

loginwin::loginwin(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::loginwin)
{
    ui->setupUi(this);
}

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

【4.4】loginwin.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>loginwin</class>
 <widget class="QMainWindow" name="loginwin">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>loginwin</string>
  </property>
  <widget class="QWidget" name="centralwidget">
   <widget class="QLineEdit" name="lineEdit">
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>100</y>
      <width>441</width>
      <height>61</height>
     </rect>
    </property>
   </widget>
   <widget class="QLineEdit" name="lineEdit_2">
    <property name="geometry">
     <rect>
      <x>160</x>
      <y>220</y>
      <width>441</width>
      <height>61</height>
     </rect>
    </property>
   </widget>
   <widget class="QPushButton" name="loginbt">
    <property name="geometry">
     <rect>
      <x>150</x>
      <y>310</y>
      <width>161</width>
      <height>51</height>
     </rect>
    </property>
    <property name="text">
     <string>登录</string>
    </property>
   </widget>
   <widget class="QPushButton" name="regbt">
    <property name="geometry">
     <rect>
      <x>510</x>
      <y>320</y>
      <width>151</width>
      <height>61</height>
     </rect>
    </property>
    <property name="text">
     <string>注册</string>
    </property>
   </widget>
   <widget class="mysolfkey" name="widget" native="true">
    <property name="geometry">
     <rect>
      <x>50</x>
      <y>390</y>
      <width>691</width>
      <height>161</height>
     </rect>
    </property>
   </widget>
  </widget>
  <widget class="QMenuBar" name="menubar">
   <property name="geometry">
    <rect>
     <x>0</x>
     <y>0</y>
     <width>800</width>
     <height>22</height>
    </rect>
   </property>
  </widget>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <customwidgets>
  <customwidget>
   <class>mysolfkey</class>
   <extends>QWidget</extends>
   <header location="global">mysolfkey.h</header>
   <container>1</container>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

设计界面-
在这里插入图片描述

【4.5】mybutton.h

#ifndef MYBUTTON_H
#define MYBUTTON_H

#include <QPushButton>

class mybutton : public QPushButton
{
    Q_OBJECT
public:
    explicit mybutton(QWidget *parent = nullptr);
private slots:
    void fun();
signals:

};

#endif // MYBUTTON_H

【4.6】mybutton.cpp

#include "mybutton.h"
#include <QDebug>
#include <QKeyEvent>
#include <QCoreApplication>
#include <QApplication>
mybutton::mybutton(QWidget *parent) : QPushButton(parent)
{
    //关联clicked信号和自定义的槽函数
    connect(this,SIGNAL(clicked()),this,SLOT(fun()));
}

void mybutton::fun()
{
    //qDebug()<<"你点击软键盘上任何按钮,我都会被调用";
    //获取信号的发送者
    QObject *obj=sender();
    mybutton *bt=qobject_cast<mybutton *>(obj);
    //获取按钮的字面信息
    QString str=bt->text();  // 'a'-32
    int key=str.toInt()-32;
    //定义一个按键事件
    QKeyEvent *keyevent=new QKeyEvent(QEvent::KeyPress,key,Qt::NoModifier,str);
    //把这个按键事件发送出去
    return QCoreApplication::postEvent(QApplication::focusWidget(),keyevent);
}

【4.7】mysolfkey.h

#ifndef MYSOLFKEY_H
#define MYSOLFKEY_H

#include <QWidget>

namespace Ui {
class mysolfkey;
}

class mysolfkey : public QWidget
{
    Q_OBJECT

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

private:
    Ui::mysolfkey *ui;
};

#endif // MYSOLFKEY_H

【4.8】mysolfkey.cpp

#include "mysolfkey.h"
#include "ui_mysolfkey.h"

mysolfkey::mysolfkey(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::mysolfkey)
{
    ui->setupUi(this);
}

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

【4.9】mysolfkey.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>mysolfkey</class>
 <widget class="QWidget" name="mysolfkey">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>228</width>
    <height>158</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>Form</string>
  </property>
  <layout class="QGridLayout" name="gridLayout">
   <item row="0" column="0">
    <layout class="QVBoxLayout" name="verticalLayout">
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout">
       <item>
        <widget class="mybutton" name="pushButton">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>q</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_2">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>w</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_4">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>e</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_3">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>r</string>
         </property>
        </widget>
       </item>
      </layout>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_2">
       <item>
        <widget class="mybutton" name="pushButton_7">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>a</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_6">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>s</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_5">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>d</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_8">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>f</string>
         </property>
        </widget>
       </item>
      </layout>
     </item>
     <item>
      <layout class="QHBoxLayout" name="horizontalLayout_3">
       <item>
        <widget class="mybutton" name="pushButton_14">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>z</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_10">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>x</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_16">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>c</string>
         </property>
        </widget>
       </item>
       <item>
        <widget class="mybutton" name="pushButton_15">
         <property name="minimumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="maximumSize">
          <size>
           <width>40</width>
           <height>40</height>
          </size>
         </property>
         <property name="font">
          <font>
           <family>楷体</family>
           <pointsize>14</pointsize>
          </font>
         </property>
         <property name="focusPolicy">
          <enum>Qt::NoFocus</enum>
         </property>
         <property name="text">
          <string>v</string>
         </property>
        </widget>
       </item>
      </layout>
     </item>
    </layout>
   </item>
  </layout>
 </widget>
 <customwidgets>
  <customwidget>
   <class>mybutton</class>
   <extends>QPushButton</extends>
   <header location="global">mybutton.h</header>
  </customwidget>
 </customwidgets>
 <resources/>
 <connections/>
</ui>

界面设计-
在这里插入图片描述

【5】事件流程重写了事件处理函数

【5.1】main.cpp

#include "mainwindow.h"

#include <QApplication>

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);
    MainWindow w;
    w.show();
    return a.exec();
}

【5.2】mainwindow.cpp

#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
MainWindow::MainWindow(QWidget *parent)
    : QMainWindow(parent)
    , ui(new Ui::MainWindow)
{
    ui->setupUi(this);
}

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

void MainWindow::mouseDoubleClickEvent(QMouseEvent *event)
{
    //打印你双击的坐标位置
    qDebug()<<"你双击的是: "<<event->x()<<"   "<<event->y();
    //判断你用的是哪个键
    if(event->button()==Qt::LeftButton)  //鼠标左键
        qDebug()<<"左键双击";
    else if(event->button()==Qt::RightButton)  //鼠标右键
        qDebug()<<"右键双击";
    else
        qDebug()<<"中间键双击";
}

void MainWindow::keyPressEvent(QKeyEvent *event)
{
    qDebug()<<"你按下去的是  "<<event->text();
}

【5.3】mainwindow.h

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QMouseEvent>
#include <QKeyEvent>
QT_BEGIN_NAMESPACE
namespace Ui { class MainWindow; }
QT_END_NAMESPACE

class MainWindow : public QMainWindow
{
    Q_OBJECT

public:
    MainWindow(QWidget *parent = nullptr);
    ~MainWindow();
    //重写父类的鼠标双击事件的处理函数
    void mouseDoubleClickEvent(QMouseEvent *event);
    //重写父类的按键事件处理函数
    void keyPressEvent(QKeyEvent *event);

private:
    Ui::MainWindow *ui;
};
#endif // MAINWINDOW_H

【5.4】mainwindow.ui

<?xml version="1.0" encoding="UTF-8"?>
<ui version="4.0">
 <class>MainWindow</class>
 <widget class="QMainWindow" name="MainWindow">
  <property name="geometry">
   <rect>
    <x>0</x>
    <y>0</y>
    <width>800</width>
    <height>600</height>
   </rect>
  </property>
  <property name="windowTitle">
   <string>MainWindow</string>
  </property>
  <widget class="QWidget" name="centralwidget"/>
  <widget class="QMenuBar" name="menubar"/>
  <widget class="QStatusBar" name="statusbar"/>
 </widget>
 <resources/>
 <connections/>
</ui>

界面设计-
在这里插入图片描述

【6】所有源码分享

在这里插入图片描述-
在这里插入图片描述

第八章 往期内容回顾

第一期 QT上位机安装与新建项目教程

第二期 QT平台使用规则和代码逻辑学习

第三期 QT中信号与槽和字符串QString的使用

第四期 QT组件布局管理器和多界面传参跳转

第五期 QT消息盒子-对话框-定时器-日期和时间

第六期 mplayer视频播放器+列表框+交叉编译QT程序+QT控制硬件+多进程

第七期 QT网络编程TCP/IP/UDP+Http和JSON解析+qt事件软键盘

跳转到 Cubox 查看

posted @ 2023-04-21 16:58  cps666  阅读(257)  评论(0编辑  收藏  举报