工具介紹:
這是一個功能完整的網絡測速工具,可以測試網絡的下載速度、上傳速度和延遲。
功能特點:
1. 速度測試
? ?- 下載速度測試
? ?- 上傳速度測試
? ?- Ping延遲測試
? ?- 自動選擇最佳服務器
2. 實時顯示
? ?- 進度條顯示測試進度
? ?- 實時顯示測試狀態
? ?- 清晰的數據展示
3. 歷史記錄
? ?- 保存測試歷史
? ?- 顯示最近6次測試結果
? ?- 支持導出歷史記錄
使用要求:
- Python 3.6+
- 需要安裝的庫:
? python -m pip install speedtest-cli
使用方法:
1. 安裝依賴:
? ?- 首先安裝必要的庫
? ?- 確保網絡連接正常
2. 開始測速:
? ?- 點擊"開始測速"按鈕
? ?- 等待測試完成(約1-2分鐘)
? ?- 查看測試結果
3. 歷史記錄:
? ?- 自動保存每次測試結果
? ?- 查看最近的測試歷史
? ?- 可導出完整歷史記錄
完整代碼:
import tkinter as tk
from tkinter import ttk, messagebox
try:import speedtest
except ImportError:messagebox.showerror("錯誤", "請先安裝 speedtest-cli:\npip install speedtest-cli")raise
import threading
import time
from datetime import datetime
import json
import os
from pathlib import Pathclass NetworkSpeedTest:def __init__(self):self.window = tk.Tk()self.window.title("網絡測速工具")self.window.geometry("600x500")# 創建主框架self.main_frame = ttk.Frame(self.window, padding="10")self.main_frame.grid(row=0, column=0, sticky=(tk.W, tk.E, tk.N, tk.S))# 測速結果顯示self.setup_display()# 控制按鈕self.setup_controls()# 歷史記錄self.setup_history()# 初始化speedtestself.st = Noneself.testing = Falseself.history_file = Path.home() / '.speedtest_history.json'self.load_history()def setup_display(self):# 當前速度顯示display_frame = ttk.LabelFrame(self.main_frame, text="測速結果", padding="10")display_frame.grid(row=0, column=0, sticky=(tk.W, tk.E), pady=10)# 下載速度ttk.Label(display_frame, text="下載速度:").grid(row=0, column=0, pady=5)self.download_speed = ttk.Label(display_frame, text="-- Mbps")self.download_speed.grid(row=0, column=1, padx=20)# 上傳速度ttk.Label(display_frame, text="上傳速度:").grid(row=1, column=0, pady=5)self.upload_speed = ttk.Label(display_frame, text="-- Mbps")self.upload_speed.grid(row=1, column=1, padx=20)# Ping值ttk.Label(display_frame, text="Ping延遲:").grid(row=2, column=0, pady=5)self.ping = ttk.Label(display_frame, text="-- ms")self.ping.grid(row=2, column=1, padx=20)# 服務器信息ttk.Label(display_frame, text="測速服務器:").grid(row=3, column=0, pady=5)self.server_info = ttk.Label(display_frame, text="--")self.server_info.grid(row=3, column=1, padx=20)# 進度條self.progress = ttk.Progressbar(display_frame, length=300, mode='determinate')self.progress.grid(row=4, column=0, columnspan=2, pady=10)# 狀態標簽self.status = ttk.Label(display_frame, text="就緒")self.status.grid(row=5, column=0, columnspan=2)def setup_controls(self):control_frame = ttk.Frame(self.main_frame)control_frame.grid(row=1, column=0, pady=10)self.start_button = ttk.Button(control_frame, text="開始測速", command=self.start_test)self.start_button.grid(row=0, column=0, padx=5)ttk.Button(control_frame, text="導出歷史", command=self.export_history).grid(row=0, column=1, padx=5)def setup_history(self):history_frame = ttk.LabelFrame(self.main_frame, text="歷史記錄", padding="10")history_frame.grid(row=2, column=0, sticky=(tk.W, tk.E), pady=10)# 創建表格columns = ('time', 'download', 'upload', 'ping')self.history_tree = ttk.Treeview(history_frame, columns=columns, height=6)self.history_tree.heading('time', text='時間')self.history_tree.heading('download', text='下載(Mbps)')self.history_tree.heading('upload', text='上傳(Mbps)')self.history_tree.heading('ping', text='Ping(ms)')self.history_tree.column('#0', width=0, stretch=tk.NO)self.history_tree.column('time', width=150)self.history_tree.column('download', width=100)self.history_tree.column('upload', width=100)self.history_tree.column('ping', width=100)self.history_tree.grid(row=0, column=0)def load_history(self):if self.history_file.exists():try:with open(self.history_file, 'r') as f:self.history = json.load(f)self.update_history_display()except:self.history = []else:self.history = []def save_history(self):with open(self.history_file, 'w') as f:json.dump(self.history, f)def update_history_display(self):for item in self.history_tree.get_children():self.history_tree.delete(item)for record in self.history[-6:]: # 只顯示最近6條記錄self.history_tree.insert('', 0, values=(record['time'],f"{record['download']:.1f}",f"{record['upload']:.1f}",f"{record['ping']:.0f}"))def start_test(self):if self.testing:returnself.testing = Trueself.start_button['state'] = 'disabled'self.progress['value'] = 0self.status['text'] = "正在初始化..."# 在新線程中運行測速threading.Thread(target=self.run_speedtest, daemon=True).start()def run_speedtest(self):try:# 初始化self.status['text'] = "正在連接到測速服務器..."self.st = speedtest.Speedtest()self.progress['value'] = 20# 選擇服務器self.status['text'] = "正在選擇最佳服務器..."server = self.st.get_best_server()self.server_info['text'] = f"{server['sponsor']} ({server['name']})"self.progress['value'] = 40# 測試下載速度self.status['text'] = "正在測試下載速度..."download_speed = self.st.download() / 1_000_000 # 轉換為Mbpsself.download_speed['text'] = f"{download_speed:.1f} Mbps"self.progress['value'] = 60# 測試上傳速度self.status['text'] = "正在測試上傳速度..."upload_speed = self.st.upload() / 1_000_000 # 轉換為Mbpsself.upload_speed['text'] = f"{upload_speed:.1f} Mbps"self.progress['value'] = 80# 獲取ping值ping_time = server['latency']self.ping['text'] = f"{ping_time:.0f} ms"self.progress['value'] = 100# 保存結果self.history.append({'time': datetime.now().strftime("%Y-%m-%d %H:%M:%S"),'download': download_speed,'upload': upload_speed,'ping': ping_time})self.save_history()self.update_history_display()self.status['text'] = "測速完成"except Exception as e:messagebox.showerror("錯誤", f"測速過程中出錯:{str(e)}")self.status['text'] = "測速失敗"finally:self.testing = Falseself.start_button['state'] = 'normal'def export_history(self):if not self.history:messagebox.showinfo("提示", "沒有歷史記錄可供導出")returnfile_path = tk.filedialog.asksaveasfilename(defaultextension=".csv",filetypes=[("CSV files", "*.csv")],initialfile="speedtest_history.csv")if file_path:try:with open(file_path, 'w', encoding='utf-8') as f:f.write("時間,下載速度(Mbps),上傳速度(Mbps),Ping延遲(ms)\n")for record in self.history:f.write(f"{record['time']},{record['download']:.1f},"f"{record['upload']:.1f},{record['ping']:.0f}\n")messagebox.showinfo("成功", "歷史記錄已導出")except Exception as e:messagebox.showerror("錯誤", f"導出過程中出錯:{str(e)}")def run(self):self.window.mainloop()if __name__ == "__main__":app = NetworkSpeedTest()app.run()