add tcp client

This commit is contained in:
zhangsheng 2025-03-13 15:12:03 +08:00
parent 5b93c1e055
commit 50c55283a0
4 changed files with 605 additions and 0 deletions

104
MyTcpClient.cpp Normal file
View File

@ -0,0 +1,104 @@
#include "MyTcpClient.h"
#include <QDebug>
#include "data_config.h"
MyTcpClient::MyTcpClient(QObject *parent) : QObject(parent), shouldReconnect(true) {
socket = new QTcpSocket(this);
connect(socket, &QTcpSocket::connected, this, &MyTcpClient::onConnected);
connect(socket, &QTcpSocket::readyRead, this, &MyTcpClient::onReadyRead);
connect(socket, &QTcpSocket::disconnected, this, &MyTcpClient::onDisconnected);
//connect(socket, &QTcpSocket::errorOccurred, this, &MyTcpClient::onErrorOccurred);
// 连接失败后,定时尝试重连
connect(&reconnectTimer, &QTimer::timeout, this, &MyTcpClient::onReconnect);
reconnectTimer.setInterval(5000); // 5秒重连一次
// 发送心跳包
//connect(&heartbeatTimer, &QTimer::timeout, this, &MyTcpClient::sendHeartbeat);
//heartbeatTimer.setInterval(10000); // 10秒发送一次心跳
}
MyTcpClient::~MyTcpClient() {
shouldReconnect = false;
if (socket) {
socket->disconnectFromHost();
socket->deleteLater();
}
}
void MyTcpClient::connectToServer(const QString &host, quint16 port) {
serverHost = host;
serverPort = port;
if (socket->state() == QAbstractSocket::ConnectedState) {
qDebug() << "Already connected!";
return;
}
qDebug() << "Connecting to" << host << ":" << port;
socket->connectToHost(host, port);
if (!socket->waitForConnected()) {
qDebug() << "Connection failed!";
return;
}
}
int MyTcpClient::sendData(char*data,qint64 len) {
qint64 bytesWritten = socket->write(data, len);
socket->waitForBytesWritten();
return bytesWritten;
}
void MyTcpClient::waitForRead() {
socket->waitForReadyRead();
}
void MyTcpClient::disconnectFromServer() {
shouldReconnect = false; // 停止自动重连
reconnectTimer.stop();
heartbeatTimer.stop();
socket->disconnectFromHost();
}
void MyTcpClient::onConnected() {
qDebug() << "Connected to server!";
emit connected();
reconnectTimer.stop(); // 连接成功,停止自动重连
heartbeatTimer.start(); // 开始发送心跳包
}
void MyTcpClient::onReadyRead() {
QByteArray data = socket->readAll();
emit dataReceived(data);
}
void MyTcpClient::onDisconnected() {
qDebug() << "Disconnected from server!";
emit disconnected();
if (shouldReconnect) {
qDebug() << "Attempting to reconnect in 5 seconds...";
reconnectTimer.start(); // 触发自动重连
heartbeatTimer.stop(); // 断开后停止心跳
}
}
void MyTcpClient::onErrorOccurred(QAbstractSocket::SocketError socketError) {
Q_UNUSED(socketError)
qDebug() << "Socket error:" << socket->errorString();
emit errorOccurred(socket->errorString());
}
void MyTcpClient::onReconnect() {
if (socket->state() == QAbstractSocket::UnconnectedState) {
qDebug() << "Reconnecting to" << serverHost << ":" << serverPort;
socket->connectToHost(serverHost, serverPort);
}
}
void MyTcpClient::sendHeartbeat() {
if (socket->state() == QAbstractSocket::ConnectedState) {
QByteArray heartbeat = "HEARTBEAT"; // 这里可以换成协议规定的心跳包
socket->write(heartbeat);
qDebug() << "Sent heartbeat to server.";
}
}

43
MyTcpClient.h Normal file
View File

@ -0,0 +1,43 @@
#ifndef MYTCPCLIENT_H
#define MYTCPCLIENT_H
#include <QTcpSocket>
#include <QTimer>
#include <QObject>
class MyTcpClient : public QObject {
Q_OBJECT
public:
explicit MyTcpClient(QObject *parent = nullptr);
~MyTcpClient();
void connectToServer(const QString &host, quint16 port);
int sendData(char* data,qint64 len);
void waitForRead();
void disconnectFromServer();
signals:
void connected();
void disconnected();
void dataReceived(const QByteArray &data);
void errorOccurred(const QString &errorMsg);
private slots:
void onConnected();
void onReadyRead();
void onDisconnected();
void onErrorOccurred(QAbstractSocket::SocketError socketError);
void onReconnect();
void sendHeartbeat();
private:
QTcpSocket *socket;
QTimer reconnectTimer; // 自动重连定时器
QTimer heartbeatTimer; // 心跳包定时器
QString serverHost;
quint16 serverPort;
bool shouldReconnect; // 标记是否需要重连
};
#endif // MYTCPCLIENT_H

5
qss.qrc Normal file
View File

@ -0,0 +1,5 @@
<RCC>
<qresource prefix="/">
<file>qss/soft.css</file>
</qresource>
</RCC>

453
qss/soft.css Normal file
View File

@ -0,0 +1,453 @@
QWidget[flag="title"]{
/*border-image:url(:/image/title.png)*/
background-color:#f2f4f7;background-image:url(:/image/title.png);background-position:left;background-repeat:no-repeat;
}
QWidget[flag="body"]{
border-style:none;
border-radius:0px;
padding:5px;
color:#f2f4f7;
background:#f2f4f7;
}
QLabel{
background-color: transparent; /* 按钮背景颜色 */
border-radius:0px;
color:#484848;
background:none;
border-style:none;
}
QPushButton {
background-color: #f2f4f7; /* 按钮背景颜色 */
color: black; /* 文字颜色 */
border: 1px solid #2980b9; /* 边框颜色 */
border-radius: 6px; /* 圆角 */
padding: 5px 10px; /* 内边距 */
font: 12px "黑体"; /* 字体 */
}
QPushButton:hover {
background-color: #1f5188; /* 悬停时背景颜色 */
border-color: #1f6690; /* 悬停时边框颜色 */
color: white; /* 悬停时文字颜色 */
}
QPushButton:pressed {
background-color: #1f6690; /* 按下时背景颜色 */
border-color: #0f3d5a; /* 按下时边框颜色 */
color: white; /* 悬停时文字颜色 */
}
QComboBox {
background-color: white; /* 背景颜色 */
color: #484848; /* 文字颜色 */
border: 1px solid #2980b9; /* 边框颜色 */
border-radius: 6px; /* 圆角 */
padding: 5px 10px; /* 内边距 */
font: 12px "黑体"; /* 字体 */
min-width: 100px; /* 最小宽度 */
}
/* 下拉箭头 */
/*QComboBox::down-arrow {
width: 14px;
height: 14px;
}*/
/* 鼠标悬停 */
QComboBox:hover {
background-color: #2980b9;
color: white; /* 文字颜色 */
}
/* 按下时 */
QComboBox:pressed {
background-color: #1f6690;
}
/* 禁用状态 */
QComboBox:disabled {
background-color: #7f8c8d;
color: #bdc3c7;
border-color: #95a5a6;
}
/* 下拉列表整体 */
QComboBox QAbstractItemView {
background-color: white; /* 背景颜色 */
border: 0px solid #34495e;
color: #1f1010;
selection-background-color: #1f5188; /* 选中项背景颜色 */
selection-color: white; /* 选中项文字颜色 */
}
/* 下拉列表项 */
QComboBox QAbstractItemView::item {
padding: 5px;
color: #484848;
height: 15px; /* 设置每一项的高度 */
}
QComboBox QAbstractItemView::item:hover{
background-color:#409CE1;
color:#1b1e23;
}
QComboBox QAbstractItemView::item:selected{
background-color:#409CE1;
color:#ffffff;
}
QMenuBar{
background-color: white; /* 设置MenuBar的背景颜色 */
color: #1f1010; /* 设置MenuBar的字体颜色 */
}
QStatusBar{
background-color: white; /* 设置StatusBar的背景颜色 */
color: #1f1010; /* 设置StatusBar的字体颜色 */
}
QMenuBar::item {
/* 这里可以设置每个菜单项的样式 */
spacing: 3px; /* 设置菜单项之间的间距 */
padding: 1px 10px; /* 设置菜单项的填充 */
background-color: white; /* 设置菜单项的背景颜色 */
color: #1f1010; /* 设置菜单项的字体颜色 */
}
QMenuBar::item:selected {
/* 设置选中菜单项的样式 */
background-color: #1f5188; /* 选中时背景颜色 */
color: white; /* 选中时字体颜色 */
}
QMenu {
background-color: white; /* 背景颜色 */
border: 0px solid #666;
color: #1f1010; /* 字体颜色 */
}
QMenu::item {
padding: 6px 20px;
background-color: white;
}
QMenu::item:selected { /* 悬停 */
background-color: #1f5188;
color: white;
}
QMenu::separator {
height: 1px;
background: white;
margin: 5px;
}
QGroupBox {
border: 1px solid #2980b9; /* 边框颜色 */
border-radius: 6px; /* 圆角 */
margin-top: 10px; /* 标题上方的间距 */
font: 12px "黑体"; /* 设置字体 */
color: white; /* 标题颜色 */
background-color: #f2f4f7; /* 背景颜色 */
}
/* 标题文本的背景 */
QGroupBox::title {
subcontrol-origin: margin;
subcontrol-position: top left; /* 让标题靠左 */
padding: 2px 10px; /* 调整标题的内边距 */
background-color: #2980b9; /* 标题背景颜色 */
color: white; /* 标题文字颜色 */
border-radius: 1px;
}
/* 整个选项卡区域的背景 */
QTabWidget::pane {
border: 1px solid #2980b9; /* 边框颜色 */
border-radius: 6px; /* 圆角 */
background-color: #f2f4f7; /* 背景颜色 */
}
/* 选项卡(未选中状态) */
QTabBar::tab {
background: #f2f4f7; /* 选项卡背景 */
color: #484848; /* 文字颜色 */
border: 1px solid #2980b9; /* 选项卡边框 */
border-radius: 4px; /* 选项卡圆角 */
padding: 5px 15px; /* 内边距 */
margin: 2px; /* 选项卡之间的间距 */
}
/* 选中的选项卡 */
QTabBar::tab:selected {
background: #2980b9;
color: white;
font-weight: bold;
}
/* 悬停时的选项卡 */
QTabBar::tab:hover {
background: #2980b9;
color: white;
}
/* 选项卡栏的位置(靠左) */
QTabWidget::tab-bar {
alignment: left;
}
QDoubleSpinBox {
border: 1px solid #2980b9; /* 边框颜色 */
border-radius: 6px; /* 圆角 */
background-color: white; /* 背景颜色 */
color: #484848; /* 文字颜色 */
padding: 2px 8px; /* 内边距 */
font: 12px "Arial";
}
/* 失去焦点时的样式 */
QDoubleSpinBox:!focus {
border: 1px solid #1f6690;
}
/* 鼠标悬停时 */
QDoubleSpinBox:hover {
border: 1px solid #1abc9c;
}
/* 增加/减少按钮 */
QDoubleSpinBox::up-button, QDoubleSpinBox::down-button {
width: 16px;
border: none;
background-color: #3498db; /* 按钮背景色 */
color: white;
border-radius: 4px;
}
/* 鼠标悬停时按钮变色 */
QDoubleSpinBox::up-button:hover, QDoubleSpinBox::down-button:hover {
background-color: #1f6690;
}
/* 按钮按下时 */
QDoubleSpinBox::up-button:pressed, QDoubleSpinBox::down-button:pressed {
background-color: #145a7a;
}
/* 上增按钮 */
QDoubleSpinBox::up-arrow {
image: url(:/icons/up_arrow.png); /* 自定义上箭头图片 */
width: 10px;
height: 10px;
}
/* 下减按钮 */
QDoubleSpinBox::down-arrow {
image: url(:/icons/down_arrow.png); /* 自定义下箭头图片 */
width: 10px;
height: 10px;
}
/* 禁用状态 */
QDoubleSpinBox:disabled {
background-color: #cac4c3;
color: black;
border: 1px solid #95a5a6;
}
/* QCheckBox 默认样式 */
QCheckBox {
spacing: 5px; /* 复选框与文本的间距 */
color: #484848; /* 文本颜色 */
font-size: 14px;
}
/* 鼠标悬停 */
QCheckBox:hover {
color: #1abc9c;
}
/* 复选框(未选中状态) */
QCheckBox::indicator {
width: 16px;
height: 16px;
border-radius: 4px;
background-color: #f2f4f7;
border: 1px solid #2980b9;
}
/* 复选框(选中状态) */
QCheckBox::indicator:checked {
background-color: #2980b9;
border: 1px solid #1abc9c;
image: url(:/icons/checked.png); /* 自定义选中图标 */
}
/* 复选框(未选中但鼠标悬停) */
QCheckBox::indicator:hover {
background-color: #1f6690;
}
/* 复选框(禁用状态) */
QCheckBox:disabled {
color: #7f8c8d;
}
QCheckBox::indicator:disabled {
background-color: #7f8c8d;
border: 2px solid #95a5a6;
}
QLineEdit {
border: 1px solid #2980b9; /* 边框颜色 */
border-radius: 6px; /* 圆角 */
background-color: white; /* 背景色 */
color: #484848; /* 文字颜色 */
font-size: 14px;
padding: 4px 10px; /* 内边距 */
}
/* 当 QLineEdit 处于焦点状态(被选中) */
QLineEdit:focus {
border: 1px solid #1abc9c; /* 选中时的边框颜色 */
background-color: white; /* 选中时的背景色 */
}
/* 禁用状态 */
QLineEdit:disabled {
background-color: white;
color: #484848;
border: 0px solid #95a5a6;
}
/* 只读状态 */
QLineEdit:read-only {
background-color: #cac4c3;
color: #cccccc;
border: 2px solid #555555;
}
/* 提示文本Placeholder颜色 */
QLineEdit::placeholder {
color: #95a5a6;
font-style: italic;
}
/* 清除按钮(如果 `setClearButtonEnabled(true)` 被调用) */
QLineEdit::clear-button {
image: url(:/icons/clear.png);
width: 16px;
height: 16px;
margin-right: 5px;
}
QSpinBox {
border: 1px solid #2980b9; /* 边框颜色 */
border-radius: 6px; /* 圆角 */
background-color: white; /* 背景色 */
color: #484848; /* 文字颜色 */
font-size: 14px;
padding: 2px 8px; /* 内边距 */
}
/* 选中状态 */
QSpinBox:focus {
border: 2px solid #1abc9c; /* 选中时的边框颜色 */
background-color: white; /* 选中时的背景色 */
}
/* 禁用状态 */
QSpinBox:disabled {
background-color: #cac4c3;
color: #484848;
border: 1px solid #95a5a6;
}
/* 只读状态 */
QSpinBox:read-only {
background-color: #3b3b3b;
color: #cccccc;
border: 1px solid #555555;
}
/* 上下调节按钮 */
QSpinBox::up-button, QSpinBox::down-button {
width: 16px;
background-color: #2980b9; /* 按钮背景 */
border: none;
border-radius: 3px;
}
/* 上调节按钮 */
QSpinBox::up-button {
subcontrol-origin: border;
subcontrol-position: top right; /* 右上角 */
image: url(:/icons/up_arrow.png); /* 上箭头图标 */
margin: 2px;
}
/* 下调节按钮 */
QSpinBox::down-button {
subcontrol-origin: border;
subcontrol-position: bottom right; /* 右下角 */
image: url(:/icons/down_arrow.png); /* 下箭头图标 */
margin: 2px;
}
/* 按钮鼠标悬停 */
QSpinBox::up-button:hover, QSpinBox::down-button:hover {
background-color: #1abc9c;
}
/* 按钮禁用状态 */
QSpinBox::up-button:disabled, QSpinBox::down-button:disabled {
background-color: #7f8c8d;
image: none;
}
/* 箭头禁用状态 */
QSpinBox::up-arrow:disabled, QSpinBox::down-arrow:disabled {
image: none;
}
QRadioButton {
color: #484848; /* 文字颜色 */
font-size: 14px;
spacing: 8px; /* 文字与圆圈的间距 */
}
/* 未选中时的圆圈 */
QRadioButton::indicator {
width: 16px;
height: 16px;
border-radius: 8px; /* 让它变成圆形 */
border: 1px solid #2980b9; /* 圆圈边框 */
background-color: transparent;
}
/* 选中状态 */
QRadioButton::indicator:checked {
background-color: #2980b9; /* 选中时的内部颜色 */
border: 1px solid #1abc9c; /* 选中时的边框颜色 */
}
/* 禁用状态 */
QRadioButton:disabled {
color: #7f8c8d;
}
QRadioButton::indicator:disabled {
border: 1px solid #7f8c8d;
background-color: #95a5a6;
}
QTableView QLineEdit,QTableView QComboBox,QTableView QSpinBox,QTableView QDoubleSpinBox,QTableView QDateEdit,QTableView QTimeEdit,QTableView QDateTimeEdit{
border:2px groove gray;
color: #484848; /* 文字颜色 */
/*border-radius:10px;
border-radius: 15px;*/
}
QTableView QLineEdit:focus,QTableView QComboBox:focus,QTableView QSpinBox:focus,QTableView QDoubleSpinBox:focus,QTableView QDateEdit:focus,QTableView QTimeEdit:focus,QTableView QDateTimeEdit:focus{
border-width:0px;
border-radius:0px;
}
QLineEdit,QTextEdit,QPlainTextEdit,QSpinBox,QDoubleSpinBox,QComboBox,QDateEdit,QTimeEdit,QDateTimeEdit{
color:#1b1e23;
background:#ffffff;
}
QPalette{background:#f2f4f7;}*{outline:0px;color:#f2f4f7;}
QGraphicsView{
border:1px solid #f2f4f7;
qproperty-backgroundBrush:#f2f4f7;
}