Files
CalibratorLauncher/widgets/networktestwidget.cpp
2026-01-02 19:20:35 +09:00

471 lines
14 KiB
C++

#include "networktestwidget.h"
#include "overlaydialogswidget.h"
#include <QScrollArea>
#include <QDateTime>
#include <QDebug>
// 样式常量定义
const QString NetworkTestWidget::BUTTON_STYLE = R"(
QPushButton {
background-color: #f5f5f5;
color: #333333;
border: 1px solid #ddd;
border-radius: 6px;
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
min-height: 36px;
}
QPushButton:hover {
background-color: #e8e8e8;
border-color: #ccc;
}
QPushButton:pressed {
background-color: #d0d0d0;
}
QPushButton:disabled {
background-color: #f0f0f0;
color: #999;
}
)";
const QString NetworkTestWidget::PRIMARY_BUTTON_STYLE = R"(
QPushButton {
background-color: #2196F3;
color: white;
border: none;
border-radius: 6px;
padding: 8px 16px;
font-size: 14px;
font-weight: 500;
min-height: 36px;
}
QPushButton:hover {
background-color: #1976D2;
}
QPushButton:pressed {
background-color: #1565C0;
}
QPushButton:disabled {
background-color: #90CAF9;
}
)";
const QString NetworkTestWidget::INPUT_STYLE = R"(
QLineEdit {
background-color: white;
border: 1px solid #ddd;
border-radius: 6px;
padding: 8px 12px;
font-size: 14px;
min-height: 36px;
}
QLineEdit:focus {
border-color: #2196F3;
}
)";
const QString NetworkTestWidget::GROUP_STYLE = R"(
QGroupBox {
background-color: white;
border: 1px solid #e0e0e0;
border-radius: 8px;
margin-top: 16px;
padding-top: 16px;
font-size: 14px;
font-weight: 600;
}
QGroupBox::title {
subcontrol-origin: margin;
left: 16px;
padding: 0 8px;
color: #333;
}
)";
NetworkTestWidget::NetworkTestWidget(QWidget *parent)
: QWidget(parent), m_testStep(0)
{
setupUI();
m_testTimer = new QTimer(this);
connect(m_testTimer, &QTimer::timeout, this, [this]()
{
m_testStep++;
m_progressBar->setValue(m_testStep * 10);
if (m_testStep >= 10) {
m_testTimer->stop();
m_progressBar->setValue(100);
} });
}
void NetworkTestWidget::setupUI()
{
QVBoxLayout *mainLayout = new QVBoxLayout(this);
mainLayout->setContentsMargins(0, 0, 0, 0);
mainLayout->setSpacing(0);
// 标题栏
mainLayout->addWidget(createTitleBar());
// 内容区域
QScrollArea *scrollArea = new QScrollArea;
scrollArea->setWidgetResizable(true);
scrollArea->setFrameShape(QFrame::NoFrame);
scrollArea->setStyleSheet("QScrollArea { background-color: #f5f5f5; }");
QWidget *contentWidget = new QWidget;
contentWidget->setStyleSheet("background-color: #f5f5f5;");
QVBoxLayout *contentLayout = new QVBoxLayout(contentWidget);
contentLayout->setContentsMargins(20, 20, 20, 20);
contentLayout->setSpacing(16);
contentLayout->addWidget(createTestPanel());
contentLayout->addWidget(createResultPanel(), 1);
scrollArea->setWidget(contentWidget);
mainLayout->addWidget(scrollArea, 1);
}
QWidget *NetworkTestWidget::createTitleBar()
{
QWidget *titleBar = new QWidget;
titleBar->setFixedHeight(60);
titleBar->setStyleSheet("background: qlineargradient(x1:0, y1:0, x2:1, y2:0, stop:0 #1976D2, stop:1 #1565C0);");
QHBoxLayout *layout = new QHBoxLayout(titleBar);
layout->setContentsMargins(16, 0, 16, 0);
// 返回按钮
m_backBtn = new QPushButton("← 返回");
m_backBtn->setCursor(Qt::PointingHandCursor);
m_backBtn->setStyleSheet(R"(
QPushButton {
background: rgba(255,255,255,0.2);
color: white;
border: none;
border-radius: 6px;
padding: 8px 16px;
font-size: 14px;
}
QPushButton:hover {
background: rgba(255,255,255,0.3);
}
)");
connect(m_backBtn, &QPushButton::clicked, this, &NetworkTestWidget::backRequested);
layout->addWidget(m_backBtn);
// 标题(居中)
m_titleLabel = new QLabel("网络测试");
m_titleLabel->setStyleSheet("color: white; font-size: 18px; font-weight: bold;");
m_titleLabel->setAlignment(Qt::AlignCenter);
layout->addWidget(m_titleLabel, 1);
// 右侧占位,保持标题居中
QWidget *spacer = new QWidget;
spacer->setFixedWidth(m_backBtn->sizeHint().width());
layout->addWidget(spacer);
return titleBar;
}
QWidget *NetworkTestWidget::createTestPanel()
{
QGroupBox *group = new QGroupBox("测试设置");
group->setStyleSheet(GROUP_STYLE);
QVBoxLayout *layout = new QVBoxLayout(group);
layout->setContentsMargins(16, 24, 16, 16);
layout->setSpacing(16);
// Ping测试
QHBoxLayout *pingLayout = new QHBoxLayout;
QLabel *pingLabel = new QLabel("Ping主机:");
pingLabel->setFixedWidth(80);
pingLabel->setStyleSheet("font-size: 14px; color: #333;");
pingLayout->addWidget(pingLabel);
m_hostEdit = new QLineEdit;
m_hostEdit->setStyleSheet(INPUT_STYLE);
m_hostEdit->setText("www.baidu.com");
m_hostEdit->setPlaceholderText("输入主机名或IP地址");
pingLayout->addWidget(m_hostEdit, 1);
m_pingBtn = new QPushButton("Ping测试");
m_pingBtn->setStyleSheet(PRIMARY_BUTTON_STYLE);
m_pingBtn->setFixedWidth(100);
m_pingBtn->setCursor(Qt::PointingHandCursor);
connect(m_pingBtn, &QPushButton::clicked, this, &NetworkTestWidget::onPingTest);
pingLayout->addWidget(m_pingBtn);
layout->addLayout(pingLayout);
// 服务器连接测试
QHBoxLayout *serverLayout = new QHBoxLayout;
QLabel *serverLabel = new QLabel("服务器:");
serverLabel->setFixedWidth(80);
serverLabel->setStyleSheet("font-size: 14px; color: #333;");
serverLayout->addWidget(serverLabel);
m_serverEdit = new QLineEdit;
m_serverEdit->setStyleSheet(INPUT_STYLE);
m_serverEdit->setText("192.168.1.100");
m_serverEdit->setPlaceholderText("服务器地址");
serverLayout->addWidget(m_serverEdit, 1);
QLabel *portLabel = new QLabel("端口:");
portLabel->setStyleSheet("font-size: 14px; color: #333;");
serverLayout->addWidget(portLabel);
m_portEdit = new QLineEdit;
m_portEdit->setStyleSheet(INPUT_STYLE);
m_portEdit->setFixedWidth(80);
m_portEdit->setText("8080");
serverLayout->addWidget(m_portEdit);
m_serverTestBtn = new QPushButton("连接测试");
m_serverTestBtn->setStyleSheet(PRIMARY_BUTTON_STYLE);
m_serverTestBtn->setFixedWidth(100);
m_serverTestBtn->setCursor(Qt::PointingHandCursor);
connect(m_serverTestBtn, &QPushButton::clicked, this, &NetworkTestWidget::onServerTest);
serverLayout->addWidget(m_serverTestBtn);
layout->addLayout(serverLayout);
// 其他测试按钮
QHBoxLayout *otherLayout = new QHBoxLayout;
m_dnsTestBtn = new QPushButton("DNS解析测试");
m_dnsTestBtn->setStyleSheet(BUTTON_STYLE);
m_dnsTestBtn->setCursor(Qt::PointingHandCursor);
connect(m_dnsTestBtn, &QPushButton::clicked, this, &NetworkTestWidget::onDnsTest);
otherLayout->addWidget(m_dnsTestBtn);
m_speedTestBtn = new QPushButton("网速测试");
m_speedTestBtn->setStyleSheet(BUTTON_STYLE);
m_speedTestBtn->setCursor(Qt::PointingHandCursor);
connect(m_speedTestBtn, &QPushButton::clicked, this, &NetworkTestWidget::onSpeedTest);
otherLayout->addWidget(m_speedTestBtn);
otherLayout->addStretch();
layout->addLayout(otherLayout);
return group;
}
QWidget *NetworkTestWidget::createResultPanel()
{
QGroupBox *group = new QGroupBox("测试结果");
group->setStyleSheet(GROUP_STYLE);
QVBoxLayout *layout = new QVBoxLayout(group);
layout->setContentsMargins(16, 24, 16, 16);
layout->setSpacing(12);
// 进度条
m_progressBar = new QProgressBar;
m_progressBar->setFixedHeight(6);
m_progressBar->setRange(0, 100);
m_progressBar->setValue(0);
m_progressBar->setTextVisible(false);
m_progressBar->setStyleSheet(R"(
QProgressBar {
background-color: #e0e0e0;
border-radius: 3px;
}
QProgressBar::chunk {
background-color: #4CAF50;
border-radius: 3px;
}
)");
layout->addWidget(m_progressBar);
// 日志显示
m_logEdit = new QTextEdit;
m_logEdit->setReadOnly(true);
m_logEdit->setStyleSheet(R"(
QTextEdit {
background-color: #1e1e1e;
color: #d4d4d4;
border: 1px solid #ddd;
border-radius: 6px;
padding: 12px;
font-family: 'Courier New', monospace;
font-size: 13px;
}
)");
m_logEdit->setMinimumHeight(300);
layout->addWidget(m_logEdit, 1);
// 清除按钮
QHBoxLayout *buttonLayout = new QHBoxLayout;
buttonLayout->addStretch();
m_clearBtn = new QPushButton("清除日志");
m_clearBtn->setStyleSheet(BUTTON_STYLE);
m_clearBtn->setFixedWidth(100);
m_clearBtn->setCursor(Qt::PointingHandCursor);
connect(m_clearBtn, &QPushButton::clicked, this, &NetworkTestWidget::onClearLog);
buttonLayout->addWidget(m_clearBtn);
layout->addLayout(buttonLayout);
// 添加初始日志
appendLog("网络测试工具已就绪", "#4CAF50");
appendLog("请选择测试项目开始测试...", "#888");
return group;
}
void NetworkTestWidget::appendLog(const QString &message, const QString &color)
{
QString timestamp = QDateTime::currentDateTime().toString("hh:mm:ss");
QString html = QString("<span style='color: #888;'>[%1]</span> <span style='color: %2;'>%3</span><br>")
.arg(timestamp, color, message);
m_logEdit->insertHtml(html);
m_logEdit->moveCursor(QTextCursor::End);
}
void NetworkTestWidget::onPingTest()
{
QString host = m_hostEdit->text().trimmed();
if (host.isEmpty())
{
OverlayDialog::warning(window(), "提示", "请输入要Ping的主机名或IP地址");
return;
}
m_pingBtn->setEnabled(false);
m_progressBar->setValue(0);
m_testStep = 0;
appendLog(QString("开始Ping测试: %1").arg(host), "#2196F3");
m_testTimer->start(200);
// 模拟Ping测试
QTimer::singleShot(2000, this, [this, host]()
{
m_testTimer->stop();
m_progressBar->setValue(100);
m_pingBtn->setEnabled(true);
// 模拟结果
appendLog(QString("正在解析主机 %1...").arg(host), "#888");
appendLog(QString("目标IP: 110.242.68.66"), "#888");
appendLog("", "#888");
appendLog("来自 110.242.68.66 的回复: 字节=64 时间=15ms TTL=52", "#4CAF50");
appendLog("来自 110.242.68.66 的回复: 字节=64 时间=14ms TTL=52", "#4CAF50");
appendLog("来自 110.242.68.66 的回复: 字节=64 时间=16ms TTL=52", "#4CAF50");
appendLog("来自 110.242.68.66 的回复: 字节=64 时间=15ms TTL=52", "#4CAF50");
appendLog("", "#888");
appendLog("Ping统计: 已发送=4, 已接收=4, 丢失=0 (0% 丢失)", "#4CAF50");
appendLog("往返时间: 最短=14ms, 最长=16ms, 平均=15ms", "#888");
appendLog("", "#888");
appendLog("✓ Ping测试完成", "#4CAF50"); });
}
void NetworkTestWidget::onSpeedTest()
{
m_speedTestBtn->setEnabled(false);
m_progressBar->setValue(0);
m_testStep = 0;
appendLog("开始网速测试...", "#2196F3");
m_testTimer->start(300);
QTimer::singleShot(3000, this, [this]()
{
m_testTimer->stop();
m_progressBar->setValue(100);
m_speedTestBtn->setEnabled(true);
appendLog("正在测试下载速度...", "#888");
appendLog("下载速度: 45.6 Mbps", "#4CAF50");
appendLog("正在测试上传速度...", "#888");
appendLog("上传速度: 12.3 Mbps", "#4CAF50");
appendLog("网络延迟: 18ms", "#888");
appendLog("抖动: 2ms", "#888");
appendLog("", "#888");
appendLog("✓ 网速测试完成", "#4CAF50"); });
}
void NetworkTestWidget::onDnsTest()
{
m_dnsTestBtn->setEnabled(false);
m_progressBar->setValue(0);
m_testStep = 0;
appendLog("开始DNS解析测试...", "#2196F3");
m_testTimer->start(150);
QTimer::singleShot(1500, this, [this]()
{
m_testTimer->stop();
m_progressBar->setValue(100);
m_dnsTestBtn->setEnabled(true);
appendLog("DNS服务器: 114.114.114.114", "#888");
appendLog("", "#888");
appendLog("www.baidu.com -> 110.242.68.66 (8ms)", "#4CAF50");
appendLog("www.google.com -> 142.250.80.46 (25ms)", "#4CAF50");
appendLog("www.github.com -> 20.205.243.166 (45ms)", "#4CAF50");
appendLog("", "#888");
appendLog("✓ DNS解析测试完成", "#4CAF50"); });
}
void NetworkTestWidget::onServerTest()
{
QString server = m_serverEdit->text().trimmed();
QString port = m_portEdit->text().trimmed();
if (server.isEmpty())
{
OverlayDialog::warning(window(), "提示", "请输入服务器地址");
return;
}
m_serverTestBtn->setEnabled(false);
m_progressBar->setValue(0);
m_testStep = 0;
appendLog(QString("开始连接测试: %1:%2").arg(server, port), "#2196F3");
m_testTimer->start(200);
QTimer::singleShot(2000, this, [this, server, port]()
{
m_testTimer->stop();
m_progressBar->setValue(100);
m_serverTestBtn->setEnabled(true);
// 随机模拟成功或超时
bool success = (QDateTime::currentMSecsSinceEpoch() % 3) != 0;
if (success) {
appendLog(QString("正在连接 %1:%2...").arg(server, port), "#888");
appendLog("TCP握手成功", "#4CAF50");
appendLog("连接延迟: 25ms", "#888");
appendLog("服务器响应: HTTP 200 OK", "#4CAF50");
appendLog("", "#888");
appendLog("✓ 服务器连接测试成功", "#4CAF50");
} else {
appendLog(QString("正在连接 %1:%2...").arg(server, port), "#888");
appendLog("连接超时 (5000ms)", "#f44336");
appendLog("", "#888");
appendLog("✗ 服务器连接测试失败", "#f44336");
appendLog("请检查服务器地址和端口是否正确", "#ff9800");
} });
}
void NetworkTestWidget::onClearLog()
{
m_logEdit->clear();
m_progressBar->setValue(0);
appendLog("日志已清除", "#888");
}