QTcpServer类 --》表示tcp服务器
QTcpSocket类 --》表示tcp套接字
添加新的库
绝大部分类都是在 core gui widgets这三个库里面(QT工程默认也是添加这三个库)
有些类属于其它的内库,需要主动在pro文件中添加新的内库
QT += core gui network //添加了network这个新的库
第一步:创建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();
第一步:创建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();
(1)获取连接成功的客户端/服务器的ip和端口号
QHostAddress QAbstractSocket::peerAddress() const
返回值:连接成功的客户端/服务器的ip地址
QString QHostAddress::toString() const //把返回值QHostAddress对象转换成我们熟悉的字符串格式ip地址
quint16 QAbstractSocket::peerPort() const
返回值:连接成功的客户端/服务器的端口号
4.判断客户端/服务器是否断开连接
[signal] void QAbstractSocket::disconnected()
//断开连接会自动触发该信号,程序员在槽函数中写代码判断
QUdpSocket
发送端
QUdpSocket::QUdpSocket(QObject *parent = nullptr)
bool QAbstractSocket::bind(const QHostAddress &address, quint16 port = 0)
参数: address --》你要绑定的ip地址
QHostAddress(const QString &address) //address是你的ip地址
port --》你要绑定的端口号
发送: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()信号
程序员关联该信号,在槽函数中去接收信息即可
学习前端的同学需要重点掌握的一种应用层的通信协议
http协议的底层就是tcp
比如:张同学通过360浏览器登录QQ的官方网站
360浏览器:tcp客户端
QQ的官网服务器: tcp服务器
你在浏览器中输入:www.qq.com(域名或者URL地址) --》会被浏览器解析成QQ服务器的ip地址和端口号
QNetworkRequest --》表示http请求
QNetworkAccessManager --》管理http请求(发送http请求)
QNetworkReply --》表示http的应答
QNetworkRequest(const QUrl &url)
参数:url --》你要访问的网址
QUrl(const QString &url) //url就是网址www.csdn.net
QNetworkReply *QNetworkAccessManager::get(const QNetworkRequest &request)
参数:request --》你要发送的http请求
关键点:我如何得知服务器真的回复了应答信息 给我????
方法:如果服务器应答成功QNetworkAccessManager对象会自动触发
[signal] void QNetworkAccessManager::finished(QNetworkReply *reply)信号
程序员主动关联该信号,在槽函数里面读取应答信息即可
QNetworkReply类中: QByteArray QIODevice::readAll() 读取应答信息
例子一:http请求下载网络上的图片
bool QPixmap::loadFromData(const QByteArray &data)
参数:data --》从网上下载的图片原始数据
注意:图片的网址需要把https中的s去掉
https 有加密
http 没有加密
例子二:http请求获取网络上的天气预报
http://www.weather.com.cn/data/cityinfo/101010100.html
json数据:一种人为制定的数据格式,在计算机前端开发中经常使用这种格式的数据,保存信息很方便
json数据只能由数组,对象,键值对三种构成
对象:用{}来表示,可以嵌套其他两种数据 { {},{}} {键值对} {[数组]} {{},[]}
数组:用[]来表示,数组里面只能存放相同类型的数据 [1,2,3] [{},{},{}] [键值对,键值对,键值对]
键值对:用键:值表示, 键只能是字符串,值可以是任意合法类型
星期一:1
星期二:2
张三:123456
李四:789456
json数据在解析之前,程序员必须要提前知道json数据的构成,否则无法解析
QT提供了如下几个类帮助大家解析json数据:
QJsonDocument --》把json数据标准化存储
QJsonObject --》对象
QJsonArray --》数组
QJsonValue --》值
QJsonParseError --》保存出错信息
第一步:把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程序所做的一切行为动作–>都称之为事件
比如:用户用鼠标把窗口拉大,拉小 --》窗口大小改变事件
用户用鼠标拖动窗口 --》移动事件
用户按了键盘 --》按键事件
用户鼠标点击窗口 --》鼠标事件
用户关闭窗口 --》关闭事件
QEvent: 所有事件类的父类
详情见截图
事件类型 枚举值 事件处理函数
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) //移动窗口对应的处理函数
当我用鼠标拖动窗口的时候,窗口背景色的颜色会随机变换
QT中产生随机数
int qrand() --》类似rand()
void qsrand(uint seed) --》类似srand()
第一步: 【设计好软键盘的ui(模板选择QWidget,原因是软键盘等会要嵌套到主窗口中)】
在ui把按钮的focusPolicy属性设置成Nofocus
第二步:在主窗口中拖一个QWidget容器过来,然后右键点击QWidget,选择提升为你刚才创建的那个软键盘类型
第三步:写代码实现软键盘可以正常使用
思路一:传统思路,利用信号与槽实现软键盘的功能 (把所有的信号关联槽函数,一个个去判断)
思路二:使用按键事件来实现软键盘的功能
在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()
返回值:鼠标停留的组件地址
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
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
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
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
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());
}
把这段代码赋值进你创建的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>
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
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
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
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);
}
<?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>
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
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
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
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);
}
<?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>
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
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
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
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());
}
<?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>
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
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
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
#include
#include
#include
#include
#include
#include
#include
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();
}
<?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>
这里有多个界面,是因为需要多个界面之间跳转,玩过手机的都知道,划过来划过去,其实就是创建了Qt设计师界面,相当于一个类,创建方法:
#include "loginwin.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
loginwin w;
w.show();
return a.exec();
}
#ifndef LOGINWIN_H
#define LOGINWIN_H
#include
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
#include "loginwin.h"
#include "ui_loginwin.h"
loginwin::loginwin(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::loginwin)
{
ui->setupUi(this);
}
loginwin::~loginwin()
{
delete 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>
#ifndef MYBUTTON_H
#define MYBUTTON_H
#include
class mybutton : public QPushButton
{
Q_OBJECT
public:
explicit mybutton(QWidget *parent = nullptr);
private slots:
void fun();
signals:
};
#endif // MYBUTTON_H
#include "mybutton.h"
#include
#include
#include
#include
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);
}
#ifndef MYSOLFKEY_H
#define MYSOLFKEY_H
#include
namespace Ui {
class mysolfkey;
}
class mysolfkey : public QWidget
{
Q_OBJECT
public:
explicit mysolfkey(QWidget *parent = nullptr);
~mysolfkey();
private:
Ui::mysolfkey *ui;
};
#endif // MYSOLFKEY_H
#include "mysolfkey.h"
#include "ui_mysolfkey.h"
mysolfkey::mysolfkey(QWidget *parent) :
QWidget(parent),
ui(new Ui::mysolfkey)
{
ui->setupUi(this);
}
mysolfkey::~mysolfkey()
{
delete 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>
#include "mainwindow.h"
#include
int main(int argc, char *argv[])
{
QApplication a(argc, argv);
MainWindow w;
w.show();
return a.exec();
}
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include
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();
}
#ifndef MAINWINDOW_H
#define MAINWINDOW_H
#include
#include
#include
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
<?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>
第一期 QT上位机安装与新建项目教程
第二期 QT平台使用规则和代码逻辑学习
第三期 QT中信号与槽和字符串QString的使用
第四期 QT组件布局管理器和多界面传参跳转
第五期 QT消息盒子-对话框-定时器-日期和时间
第六期 mplayer视频播放器+列表框+交叉编译QT程序+QT控制硬件+多进程
第七期 QT网络编程TCP/IP/UDP+Http和JSON解析+qt事件软键盘