目录
[1 创建项目](#1 创建项目)
[2 创建界面](#2 创建界面)
[3 实现功能](#3 实现功能)
效果

步骤
1 创建项目
创建项目,这里使用Qt Widgets Application模板,项目名称这里设置为"TCPClient"

使用qmake构建工具

这里类名命名为"Widget_TCP"

这里构建套件使用MinGW

2 创建界面
创建UI界面如下图所示

使用到的qss代码:
javascript
/* ========== QWidget ========== */
QWidget {
font-family: "Microsoft YaHei", "PingFang SC", sans-serif;
font-size: 13px;
color: #2c3e50;
}
/* ========== QLabel ========== */
QLabel {
color: #34495e;
font-weight: 500;
font-size: 13px;
padding: 2px 0px;
}
QLabel#titleLabel {
font-size: 18px;
font-weight: 700;
color: #2c3e50;
padding: 8px 0px 12px 0px;
letter-spacing: 1px;
}
/* ========== QLineEdit ========== */
QLineEdit {
background-color: #f0f2f5;
border: 1.5px solid #dcdfe6;
border-radius: 8px;
padding: 8px 12px;
min-height: 20px;
color: #2c3e50;
selection-background-color: #4a90d9;
transition: border-color 0.2s;
}
QLineEdit:hover {
border-color: #a0c4f0;
background-color: #f8faff;
}
QLineEdit:focus {
border-color: #4a90d9;
background-color: #ffffff;
box-shadow: 0 0 0 3px rgba(74, 144, 217, 0.15);
}
QLineEdit:disabled {
background-color: #e9ecef;
color: #6c7a89;
border-color: #d5dbe3;
}
/* ========== QPushButton ========== */
QPushButton {
border: none;
border-radius: 8px;
padding: 9px 28px;
font-weight: 600;
font-size: 13px;
min-width: 80px;
min-height: 30px;
transition: all 0.2s;
}
/* "取消"按钮 */
QPushButton#cancelButton {
background-color: #eef1f5;
color: #4a5a6e;
}
QPushButton#cancelButton:hover {
background-color: #e2e6ed;
color: #2c3e50;
}
QPushButton#cancelButton:pressed {
background-color: #d0d6df;
}
/* "连接"按钮 */
QPushButton#connectButton {
background-color: #4a90d9;
color: #ffffff;
}
QPushButton#connectButton:hover {
background-color: #5b9ee6;
box-shadow: 0 4px 12px rgba(74, 144, 217, 0.35);
}
QPushButton#connectButton:pressed {
background-color: #3a7bc7;
box-shadow: 0 2px 6px rgba(74, 144, 217, 0.25);
}
QPushButton#connectButton:disabled {
background-color: #b0c4de;
color: #e8edf5;
}
/* ========== QTextEdit ========== */
QTextEdit {
background-color: #fafbfc;
border: 1.5px solid #e4e7ed;
border-radius: 8px;
padding: 10px;
color: #2c3e50;
font-size: 13px;
line-height: 1.6;
selection-background-color: #4a90d9;
}
QTextEdit:focus {
border-color: #4a90d9;
background-color: #ffffff;
}
/* 滚动条美化 */
QTextEdit QScrollBar:vertical {
background: #f0f2f5;
width: 10px;
border-radius: 5px;
}
QTextEdit QScrollBar::handle:vertical {
background: #c0c8d6;
border-radius: 5px;
min-height: 30px;
}
QTextEdit QScrollBar::handle:vertical:hover {
background: #a0aab8;
}
QTextEdit QScrollBar::add-line:vertical,
QTextEdit QScrollBar::sub-line:vertical {
height: 0px;
}
添加3个按钮的槽函数

3 实现功能
在项目文件(.pro)中添加网络模块"network"

添加如下代码:
cpp
#ifndef WIDGET_TCP_H
#define WIDGET_TCP_H
#include <QWidget>
#include <QTcpSocket>
#include <QHostAddress>
#include <QMessageBox>
#include <QDateTime>
QT_BEGIN_NAMESPACE
namespace Ui {
class Widget_TCP;
}
QT_END_NAMESPACE
class Widget_TCP : public QWidget
{
Q_OBJECT
public:
explicit Widget_TCP(QWidget *parent = nullptr);
~Widget_TCP() override;
private slots:
//按钮槽函数
void on_pushButton_cancel_clicked();
void on_pushButton_connect_clicked();
void on_pushButton_send_clicked();
// TCP Socket 槽函数
void onConnected();
void onDisconnected();
void onErrorOccurred(QAbstractSocket::SocketError error);
void onReadyRead();
private:
Ui::Widget_TCP *ui;
QTcpSocket *socket;
// 辅助函数
void updateUIStatus(bool connected);
void appendMessage(const QString &message);
bool isConnected() const;
};
#endif // WIDGET_TCP_H
cpp
#include "widget_tcp.h"
#include "ui_widget_tcp.h"
Widget_TCP::Widget_TCP(QWidget *parent)
: QWidget(parent)
, ui(new Ui::Widget_TCP)
{
ui->setupUi(this);
setWindowTitle("TCP客户端"); // 设置窗口标题
ui->pushButton_send->setEnabled(false); // 默认禁用发送按钮
socket = new QTcpSocket; //创建socket对象
// 连接信号槽
connect(socket, &QTcpSocket::connected, this, &Widget_TCP::onConnected);
connect(socket, &QTcpSocket::disconnected, this, &Widget_TCP::onDisconnected);
connect(socket, &QTcpSocket::errorOccurred, this, &Widget_TCP::onErrorOccurred);
connect(socket, &QTcpSocket::readyRead, this, &Widget_TCP::onReadyRead);
}
Widget_TCP::~Widget_TCP()
{
delete ui;
}
// ========== 按钮槽函数 ==========
void Widget_TCP::on_pushButton_cancel_clicked()
{
if (isConnected()) {
socket->disconnectFromHost();
appendMessage("用户主动断开连接");
} else if (socket->state() == QAbstractSocket::ConnectingState) {
socket->abort();
appendMessage("已取消连接");
updateUIStatus(false);
} else {
// 清空消息区域
ui->textEdit_message->clear();
appendMessage("已清空消息记录");
}
}
void Widget_TCP::on_pushButton_connect_clicked()
{
//获取ip地址和端口号
QString IP = ui->lineEdit_address->text();
QString port = ui->lineEdit_port->text();
//连接服务器
socket->connectToHost(QHostAddress(IP), port.toShort());
}
void Widget_TCP::on_pushButton_send_clicked()
{
if (!isConnected()) {
QMessageBox::warning(this, "未连接", "请先连接到服务器!");
return;
}
QString message = ui->lineEdit_sendMessage->text().trimmed();
if (message.isEmpty()) {
QMessageBox::information(this, "提示", "请输入要发送的消息!");
ui->lineEdit_sendMessage->setFocus();
return;
}
// 发送消息
QByteArray data = message.toUtf8();
qint64 bytesWritten = socket->write(data);
if (bytesWritten == -1) {
appendMessage("❌ 发送失败: " + socket->errorString());
} else {
// 显示发送的消息(自己发的显示在右侧,用不同颜色)
appendMessage("我: " + message);
ui->lineEdit_sendMessage->clear();
ui->lineEdit_sendMessage->setFocus();
}
}
// ========== TCP Socket 槽函数 ==========
void Widget_TCP::onConnected()
{
appendMessage("✅ 连接成功!");
updateUIStatus(true);
ui->lineEdit_sendMessage->setFocus();
ui->pushButton_send->setEnabled(true);
}
void Widget_TCP::onDisconnected()
{
appendMessage("⚠️ 连接已断开");
updateUIStatus(false);
}
void Widget_TCP::onErrorOccurred(QAbstractSocket::SocketError error)
{
QString errorMsg;
switch (error) {
case QAbstractSocket::ConnectionRefusedError:
errorMsg = "连接被拒绝,请检查服务器是否启动";
break;
case QAbstractSocket::RemoteHostClosedError:
errorMsg = "远程主机已关闭连接";
break;
case QAbstractSocket::HostNotFoundError:
errorMsg = "主机地址未找到,请检查IP地址";
break;
case QAbstractSocket::SocketTimeoutError:
errorMsg = "连接超时,请检查网络或服务器状态";
break;
default:
errorMsg = QString("连接错误: %1").arg(socket->errorString());
break;
}
appendMessage("❌ " + errorMsg);
QMessageBox::critical(this, "连接错误", errorMsg);
updateUIStatus(false);
}
void Widget_TCP::onReadyRead()
{
// 读取服务器发送的数据
QByteArray data = socket->readAll();
QString message = QString::fromUtf8(data);
// 显示接收到的消息(服务器发的显示在左侧,用蓝色)
appendMessage("服务器: " + message);
}
// ========== 辅助函数 ==========
void Widget_TCP::updateUIStatus(bool connected)
{
if (connected) {
ui->textEdit_message->append("连接成功");
} else {
ui->textEdit_message->append("连接失败");
}
}
void Widget_TCP::appendMessage(const QString &message)
{
// 获取当前时间
QString timeStr = QDateTime::currentDateTime().toString("hh:mm:ss");
// 追加到文本编辑框
ui->textEdit_message->append(QString("%1:%2").arg(timeStr).arg(message) );
// 自动滚动到底部
QTextCursor cursor = ui->textEdit_message->textCursor();
cursor.movePosition(QTextCursor::End);
ui->textEdit_message->setTextCursor(cursor);
}
bool Widget_TCP::isConnected() const
{
return socket->state() == QAbstractSocket::ConnectedState;
}