Files
EZProxy/child/ui/traffic_widget.py
2025-11-10 17:29:11 +08:00

163 lines
5.6 KiB
Python

from PyQt5.QtWidgets import (
QWidget, QVBoxLayout, QHBoxLayout, QLabel,
QProgressBar, QGroupBox
)
from PyQt5.QtCore import Qt, QTimer
from PyQt5.QtCharts import (
QChart, QChartView, QLineSeries,
QValueAxis, QBarSet, QBarSeries, QBarCategoryAxis
)
from PyQt5.QtGui import QPainter, QColor, QPen
class TrafficWidget(QWidget):
def __init__(self, parent=None):
super().__init__(parent)
self.init_ui()
self.init_chart()
self.reset_stats()
# 定时器用于模拟数据
self.timer = QTimer()
self.timer.timeout.connect(self.update_fake_data)
self.timer.start(1000)
def init_ui(self):
"""初始化UI"""
layout = QVBoxLayout()
# 速度显示
speed_layout = QHBoxLayout()
self.download_label = QLabel("下载: 0.00 KB/s")
self.upload_label = QLabel("上传: 0.00 KB/s")
self.total_label = QLabel("总计: 0.00 MB")
speed_layout.addWidget(self.download_label)
speed_layout.addWidget(self.upload_label)
speed_layout.addWidget(self.total_label)
speed_layout.addStretch()
layout.addLayout(speed_layout)
# 进度条
self.progress = QProgressBar()
self.progress.setRange(0, 100)
layout.addWidget(self.progress)
# 图表
self.chart_view = QChartView()
self.chart_view.setRenderHint(QPainter.Antialiasing)
layout.addWidget(self.chart_view)
self.setLayout(layout)
def init_chart(self):
"""初始化图表"""
self.chart = QChart()
self.chart.setTitle("实时流量统计")
self.chart.legend().setVisible(True)
# 创建系列
self.download_series = QLineSeries()
self.download_series.setName("下载")
self.download_series.setColor(QColor(52, 152, 219))
self.upload_series = QLineSeries()
self.upload_series.setName("上传")
self.upload_series.setColor(QColor(46, 204, 113))
self.chart.addSeries(self.download_series)
self.chart.addSeries(self.upload_series)
# 创建坐标轴
self.axis_x = QValueAxis()
self.axis_x.setTitleText("时间 (秒)")
self.axis_x.setRange(0, 60)
self.axis_x.setTickCount(7)
self.axis_y = QValueAxis()
self.axis_y.setTitleText("流量 (KB)")
self.axis_y.setRange(0, 100)
self.chart.addAxis(self.axis_x, Qt.AlignBottom)
self.chart.addAxis(self.axis_y, Qt.AlignLeft)
self.download_series.attachAxis(self.axis_x)
self.download_series.attachAxis(self.axis_y)
self.upload_series.attachAxis(self.axis_x)
self.upload_series.attachAxis(self.axis_y)
self.chart_view.setChart(self.chart)
def reset_stats(self):
"""重置统计数据"""
self.download_speed = 0.0
self.upload_speed = 0.0
self.total_download = 0.0
self.total_upload = 0.0
self.time_points = []
self.download_points = []
self.upload_points = []
def update_stats(self, stats):
"""更新统计数据"""
self.download_speed = stats.get('download_speed', 0.0)
self.upload_speed = stats.get('upload_speed', 0.0)
self.total_download = stats.get('total_download', 0.0)
self.total_upload = stats.get('total_upload', 0.0)
# 更新显示
self.download_label.setText(f"下载: {self.download_speed:.2f} KB/s")
self.upload_label.setText(f"上传: {self.upload_speed:.2f} KB/s")
self.total_label.setText(f"总计: {(self.total_download + self.total_upload) / 1024:.2f} MB")
# 更新进度条
total_speed = self.download_speed + self.upload_speed
progress = min(100, int(total_speed / 1024)) # 假设1MB/s为满
self.progress.setValue(progress)
self.progress.setFormat(f"总流量: {total_speed:.1f} KB/s")
# 更新图表
self.add_data_point()
def add_data_point(self):
"""添加数据点到图表"""
current_time = len(self.time_points)
# 保留最近60秒的数据
if len(self.time_points) >= 60:
self.time_points.pop(0)
self.download_points.pop(0)
self.upload_points.pop(0)
self.time_points.append(current_time)
self.download_points.append(self.download_speed)
self.upload_points.append(self.upload_speed)
# 更新系列数据
self.download_series.clear()
self.upload_series.clear()
for i, (t, d, u) in enumerate(zip(self.time_points, self.download_points, self.upload_points)):
self.download_series.append(i, d)
self.upload_series.append(i, u)
# 调整Y轴范围
max_value = max(max(self.download_points), max(self.upload_points), 100) * 1.1
self.axis_y.setRange(0, max_value)
def update_fake_data(self):
"""模拟数据更新(实际应用中应替换为真实数据)"""
import random
fake_download = random.uniform(10, 500)
fake_upload = random.uniform(5, 100)
fake_total_download = self.total_download + fake_download
fake_total_upload = self.total_upload + fake_upload
stats = {
'download_speed': fake_download,
'upload_speed': fake_upload,
'total_download': fake_total_download,
'total_upload': fake_total_upload
}
self.update_stats(stats)