从C到C++:Qt网络编程入门小结 基于 RFID 仓库管理系统的 Client 类实现
·
一、class:struct 的升级版
cpp
// C 的 struct:只能装变量
struct Client {
int fd;
};
// C++ 的 class:变量+函数可以装一起
class Client : public QObject {
int fd;
void sendCommand(const QString &cmd); // 函数可以放里面
};
二、:: 作用域解析 —— "属于哪个类"
| 写法 | 含义 |
|---|---|
Client::Client() |
Client类的构造函数(类的构造函数 必须 与类同名) |
Client::onConnected() |
Client类的onConnected函数 |
QTcpSocket::connected |
QTcpSocket类的connected信号(系统函数) |
QTcpSocket::readyRead |
QTcpSocket类的readyRead信号 |
规则: 左边::右边 = "左边类里的右边函数"
三、构造函数初始化
cpp
Client::Client(QObject *parent) // 参数名可以随便起
: QObject(parent) // 初始化列表:先初始化父类
{
// 构造函数体:真正的初始化操作
m_socket = new QTcpSocket(this);
m_serverPort = 0;
}
四、信号与槽 —— Qt 的"回调"
声明(头文件)
cpp
signals:
void connected(); // 信号:只有声明
void tagReceived(QString, QString);
private slots:
void onConnected(); // 槽:普通函数,能被信号触发
void onReadyRead();
连接(构造函数里)
connect(m_socket, &QTcpSocket::connected,
this, &Client::onConnected);
// ↑ ↑ ↑
// 谁发信号 发什么信号 哪个槽函数处理
&类名::函数名 = 取成员函数地址,告诉 connect 连的是哪个函数。
发射(触发时)
cpp
emit tagReceived(epc, tid);
// 所有 connect 了这个信号的槽都会被自动调用
五、QTcpSocket —— TCP 通信
四个自带信号
| 信号 | 触发时机 |
|---|---|
connected() |
TCP 三次握手成功 |
disconnected() |
TCP 断开 |
readyRead() |
收到数据(最重要的) |
errorOccurred() |
连接失败/超时 |
异步连接
cpp
m_socket->connectToHost(QHostAddress("192.168.0.165"), 8888);
// 立即返回,不阻塞
// 连上了 → connected() 信号
// 连不上 → errorOccurred() 信号
六、用 cJSON(不是 Qt 的 JSON)
为什么要转来转去?
QString ← Qt界面统一用这个
↓ .toUtf8().constData()
const char* ← cJSON只认C字符串
↓ cJSON_AddStringToObject
cJSON对象 ← 内存中的JSON结构
↓ cJSON_PrintUnformatted
char* ← C字符串
↓ QByteArray(data)
QByteArray ← Qt字节数组
↓ .append('\n')
← 加\n做消息分隔
↓ m_socket->write()
TCP发出去 ← 网络传输
| Qt 类 | 存什么 | 用在哪儿 |
|---|---|---|
QString |
文本(Unicode) | 界面显示 |
QByteArray |
原始字节 | 网络传输、文件读写 |
QTcpSocket |
TCP连接 | 收发数据 |
七、写好的 Client 类接口
cpp
class Client : public QObject {
public:
explicit Client(QObject *parent = nullptr);
~Client();
void connectToServer(const QString &ip, quint16 port);
void disconnectFromServer();
void sendCommand(const QString &cmd);
bool isConnected() const;
signals:
void connected();
void disconnected();
void connectionError(const QString &errorMsg);
void tagReceived(const QString &epc, const QString &tid);
void scanDone(int count);
private slots:
void onConnected();
void onDisconnected();
void onReadyRead();
void onError(QAbstractSocket::SocketError error);
private:
void parseBuffer();
QTcpSocket *m_socket;
QByteArray m_recvBuffer;
QString m_serverIp;
quint16 m_serverPort;
};
| 概念 | 说明 |
|---|---|
explicit |
防呆锁,禁止隐式转换 |
QObject *parent = nullptr |
默认参数,不传时自动为nullptr |
: QObject(parent) |
初始化列表,在{}之前调用父类构造 |
new QTcpSocket(this) |
创建对象 + 指定父对象(Qt自动管理内存) |
m_ 前缀 |
成员变量命名习惯(member) |
更多推荐

所有评论(0)