开发平台:Qt 6.2 + Qt Design Studio 3.2.0
编译环境:MinGW 11.2.0 64bit --release
主要内容:Qt Quick Application载入QML,C++与QML交互处理逻辑
实现功能:串口调试,网络调试,数据操作等
源码与安装包免费下载链接在文末!不再赘述请参照源码学习!
部分原理可参考这篇文章学习(欢迎吐槽):
(87条消息) Qt学习记录_阿衰0110的博客-CSDN博客
main.cpp代码片段:
//#include <QGuiApplication>
#include <QApplication>
#include <QQmlApplicationEngine>
#include <QQuickView>
#include <QtQml>
#include <QDebug>
#include "userfunc.h"
int main(int argc, char *argv[])
{
QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
//QGuiApplication app(argc, argv);
QApplication app(argc, argv);
QQmlApplicationEngine engine;
engine.addImportPath("qrc:/AS_TOOL_UI/imports"); // 添加imports文件路径
engine.load(QUrl(QStringLiteral("qrc:/AS_TOOL_UI/content/App.qml"))); // 加载QML
UserFunc myClass(engine.rootObjects()); // 获取QML对象
app.installNativeEventFilter(myClass.mySerialEvent); // 安装window串口拔插事件
engine.rootContext()->setContextProperty("myClass", &myClass); // 将C++类添加进QML使用
engine.rootContext()->setContextProperty("mySerial", myClass.serial_main); // 将C++类添加进QML使用
//myClass.set_QMLObject(engine.rootObjects()); // 获取QML对象
return app.exec();
}
serial.cpp代码片段,实现串口功能
#include "serial.h"
#include <QDebug>
Serial::Serial()
{
// 定义文本编码
tc = QTextCodec::codecForName("UTF-8");
}
QStringList Serial::serialScan(void)
{
QStringList serialPortList;
serialDescription.clear(); // 每次扫描先清除串口描述信息
foreach (const QSerialPortInfo &info, QSerialPortInfo::availablePorts()) {
this->setPort(info);
serialPortList.append(this->portName());
serialDescription.append(info.description());
//qDebug() << this->portName();
//qDebug() << info.description();
}
return serialPortList;
}
bool Serial::serialOpen(QString serialName, int baudRate)
{
this->setPortName(serialName);
if(this->open(QIODeviceBase::ReadWrite)) {
this->setBaudRate(baudRate);
this->setDataBits(QSerialPort::Data8);
this->setParity(QSerialPort::NoParity);
this->setStopBits(QSerialPort::OneStop);
this->setFlowControl(QSerialPort::NoFlowControl);
// 下位机发送数据会响应这个槽函数
connect(this, &QSerialPort::readyRead, this, &Serial::ReadData);
return true;
}
return false;
}
// 读数据
void Serial::ReadData()
{
dataBuf = this->readAll();
this->rxByte += tc->toUnicode(dataBuf).length();
emit this->readSignal(this->rxByte);
}
// 写数据
void Serial::sendData(QByteArray sendData)
{
int byteTemp;
byteTemp = this->write(sendData);
// 发送失败返回-1
if(byteTemp != -1)
{
this->txByte += byteTemp;
emit this->sendSuccess(this->txByte);
}
}
// 关闭串口
void Serial::serialClose()
{
this->clear();
this->close();
}
serial.h代码片段
#ifndef SERIAL_H
#define SERIAL_H
#include <QObject>
#include <QtSerialPort/QSerialPort>
#include <QtSerialPort/QSerialPortInfo>
#include <QStringList>
#include <QString>
#include <QByteArray>
#include <QTextCodec>
class Serial : public QSerialPort
{
Q_OBJECT
public:
explicit Serial();
// 发送字节数
int txByte = 0;
// 接收字节数
int rxByte = 0;
// 数据缓存区
QByteArray dataBuf;
// 串口描述内容
QStringList serialDescription;
// 串口扫描函数
QStringList serialScan(void);
bool serialOpen(QString serialName, int baudRate);
void ReadData();
void sendData(QByteArray sendData);
void serialClose();
private:
QTextCodec *tc;
signals:
void readSignal(int recByte);
void sendSuccess(int sendByte);
public slots:
};
#endif // SERIAL_H
network.cpp代码片段,实现TCP Server,TCP Client,UDP功能
#include "network.h"
#include <QNetworkDatagram>
#include <QDebug>
network::network(QObject *parent)
: QObject{parent}
{
// 定义文本编码
tc = QTextCodec::codecForName("UTF-8");
// 实例化TCP服务端
tcpServer = new QTcpServer();
connect(tcpServer, &QTcpServer::newConnection, this, &network::TCPServer_newConnect);
// 实例化TCP客户端
tcpClient = new QTcpSocket();
connect(tcpClient, &QTcpSocket::connected, this, &network::TCPClient_newConnect);
connect(tcpClient, &QTcpSocket::disconnected, this, &network::TCPClient_disconnect);
connect(tcpClient, &QTcpSocket::readyRead, this, &network::TCPClient_readData);
// 实例化UDP
udpSocket = new QUdpSocket();
connect(udpSocket, &QUdpSocket::readyRead, this, &network::UDP_readData);
}
bool network::TCPServer_open(QString ownIp, unsigned short ownPort)
{
bool result = true;
if(ownIp.length() < 10)
{
// 监听本地ip和port以监测有无接收数据
result = tcpServer->listen(QHostAddress::Any, ownPort);
}
else
{
result = tcpServer->listen(QHostAddress(ownIp), ownPort);
}
return result;
// if(!result)
// {
// qDebug() << "(TCP Server) listen fail";
// return false;
// }
// qDebug() << "(TCP Server) listen success";
// return true;
}
void network::TCPServer_close()
{
tcpServer->close();
}
void network::TCPServer_newConnect()
{
QTcpSocket *newTcpClient = tcpServer->nextPendingConnection(); // 新的客户端发起的连接
//QHostAddress newClientIp = newTcpClient->peerAddress(); // 新的客户端的IP
//quint16 newClientPort = newTcpClient->peerPort(); // 新的客户端的端口
// 是否已存在连接列表中
if(clientList.contains(newTcpClient))
{
//qDebug() << QString("(TCP Server) already exist IP:%1 PORT:%2").arg(newClientIp.toString()).arg(newClientPort);
}
else
{
clientList.append(newTcpClient); // 记录新的客户端
// 连接信号
connect(newTcpClient, &QTcpSocket::disconnected, this, &network::TCPServer_disconnect); // 断开连接的信号与槽
connect(newTcpClient, &QTcpSocket::readyRead, this, &network::TCPServer_readData); // 数据接收的信号与槽 readyRead()是QIODevice下的信号
//qDebug() << QString("(TCP Server) new connect IP:%1 PORT:%2").arg(newClientIp.toString()).arg(newClientPort);
}
}
void network::TCPServer_disconnect()
{
QTcpSocket *newTcpClient = static_cast<QTcpSocket *>(QObject::sender());
clientList.removeOne(newTcpClient); // 移除断开连接的客户端
// 断开信号
disconnect(newTcpClient, &QTcpSocket::disconnected, this, &network::TCPServer_disconnect); // 断开连接的信号与槽
disconnect(newTcpClient, SIGNAL(readyRead()), this, SLOT(TCPServer_readData())); // 数据接收的信号与槽
//qDebug() << "(TCP Server) disconnect";
}
void network::TCPServer_readData()
{
QTcpSocket *newTcpClient = static_cast<QTcpSocket *>(QObject::sender());
this->TCPServer_dataBuf = newTcpClient->readAll();
this->TCPServer_rxByte += tc->toUnicode(this->TCPServer_dataBuf).length();
emit this->tcpServer_readSuccess(this->TCPServer_rxByte);
//qDebug() << "(TCP Server) rec data:" + tc->toUnicode(TCPServer_dataBuf);
}
void network::TCPServer_sendData(QByteArray sendData)
{
int byteTemp = 0;
foreach(QTcpSocket *socket, clientList)
{
byteTemp = socket->write(sendData);
}
// 发送失败返回-1
if(byteTemp != -1)
{
this->TCPServer_txByte += byteTemp;
emit this->tcpServer_sendSuccess(this->TCPServer_txByte);
}
}
bool network::TCPClient_open(QString remoteIp, unsigned short remotePort)
{
QHostAddress serverIp;
// IP错误则返回false
if(!serverIp.setAddress(remoteIp))
{
//qDebug() << "(TCP Client) remoteIp error";
return false;
}
// 防止TCP Client已打开
if(tcpClient->isOpen())
{
tcpClient->close();
}
tcpClient->connectToHost(serverIp, remotePort);
// 是否连接成功
if(!tcpClient->waitForConnected(500))
{
//qDebug() << "(TCP Client) tcp client connect fail";
return false;
}
return true;
}
void network::TCPClient_close()
{
tcpClient->close();
}
void network::TCPClient_newConnect()
{
//qDebug() << "(TCP Client) new connect";
}
void network::TCPClient_disconnect()
{
if(tcpClient->isOpen())
{
tcpClient->close();
}
//qDebug() << "(TCP Client) disconnect";
}
void network::TCPClient_readData()
{
this->TCPClient_dataBuf = tcpClient->readAll();
this->TCPClient_rxByte += tc->toUnicode(this->TCPClient_dataBuf).length();
emit this->tcpClient_readSuccess(this->TCPClient_rxByte);
//qDebug() << "(TCP Client) rec data:" + tc->toUnicode(TCPClient_dataBuf);
}
void network::TCPClient_sendData(QByteArray sendData)
{
int byteTemp = 0;
byteTemp = tcpClient->write(sendData);
// 发送失败返回-1
if(byteTemp != -1)
{
this->TCPClient_txByte += byteTemp;
emit this->tcpClient_sendSuccess(this->TCPClient_txByte);
}
//qDebug() << "(TCP Client) send byte:" << byteTemp;
}
bool network::UDP_open(QString ownIp, unsigned short ownPort, QString remoteIp, unsigned short remotePort)
{
bool result = true;
if(ownIp.length() < 10)
{
// 绑定本地ip和port以监测有无接收数据
result = udpSocket->bind(QHostAddress::Any, ownPort);
}
else
{
result = udpSocket->bind(QHostAddress(ownIp), ownPort);
}
this->UDP_remoteIp = QHostAddress(remoteIp);
this->UDP_remotePort = remotePort;
return result;
// if(!result)
// {
// qDebug() << "UDP open fail";
// return false;
// }
// qDebug() << "UDP open success";
// return true;
}
void network::UDP_close()
{
udpSocket->close();
}
void network::UDP_readData()
{
while(udpSocket->hasPendingDatagrams())
{
QNetworkDatagram datagram = udpSocket->receiveDatagram();
this->UDP_dataBuf = datagram.data();
this->UDP_rxByte += tc->toUnicode(this->UDP_dataBuf).length();
emit this->udp_readSuccess(this->UDP_rxByte);
//qDebug() << datagram.data();
}
}
void network::UDP_sendData(QByteArray sendData)
{
int byteTemp = 0;
byteTemp = udpSocket->writeDatagram(sendData, this->UDP_remoteIp, this->UDP_remotePort);
// 发送失败返回-1
if(byteTemp != -1)
{
this->UDP_txByte += byteTemp;
emit this->udp_sendSuccess(this->UDP_txByte);
}
}
network.h代码片段
#ifndef NETWORK_H
#define NETWORK_H
#include <QObject>
#include <QList>
#include <QByteArray>
#include <QTextCodec>
#include <QHostAddress>
#include <QTcpSocket>
#include <QTcpServer>
#include <QUdpSocket>
class network : public QObject
{
Q_OBJECT
public:
explicit network(QObject *parent = nullptr);
// 数据缓存区
QByteArray TCPServer_dataBuf;
QByteArray TCPClient_dataBuf;
QByteArray UDP_dataBuf;
// 发送/接收字节数
int TCPServer_txByte = 0;
int TCPServer_rxByte = 0;
int TCPClient_txByte = 0;
int TCPClient_rxByte = 0;
int UDP_txByte = 0;
int UDP_rxByte = 0;
bool TCPServer_open(QString ownIp, unsigned short ownPort);
void TCPServer_close();
void TCPServer_sendData(QByteArray sendData);
bool TCPClient_open(QString remoteIp, unsigned short remotePort);
void TCPClient_close();
void TCPClient_sendData(QByteArray sendData);
bool UDP_open(QString ownIp, unsigned short ownPort, QString remoteIp, unsigned short remotePort);
void UDP_close();
void UDP_sendData(QByteArray sendData);
private:
QTextCodec *tc; // 编码
QTcpServer *tcpServer; // tcp服务端
QList<QTcpSocket*> clientList; // 保存连接的客户端
QTcpSocket *tcpClient; // tcp客户端
QUdpSocket *udpSocket; // udp
QHostAddress UDP_remoteIp;
unsigned short UDP_remotePort;
signals:
void tcpServer_readSuccess(int recByte);
void tcpServer_sendSuccess(int sendByte);
void tcpClient_readSuccess(int recByte);
void tcpClient_sendSuccess(int sendByte);
void udp_readSuccess(int recByte);
void udp_sendSuccess(int sendByte);
private slots:
void TCPServer_readData();
void TCPServer_newConnect();
void TCPServer_disconnect();
void TCPClient_readData();
void TCPClient_newConnect();
void TCPClient_disconnect();
void UDP_readData();
};
#endif // NETWORK_H
界面如下:
Qt6.2+QtDS多功能串口助手源码与安装包下载地址:
https://download.csdn.net/download/m0_50669075/85347047
END