From e05a7c02dfa2971dd87b87b0c14a843f53371b03 Mon Sep 17 00:00:00 2001 From: qsc20001102 Date: Fri, 31 Oct 2025 14:51:19 +0800 Subject: [PATCH] 11 --- app.log | 236 ++++++++++++++ core/Function/__init__.py | 0 .../__pycache__/__init__.cpython-313.pyc | Bin 0 -> 143 bytes .../__pycache__/ping_fun.cpython-313.pyc | Bin 0 -> 5468 bytes core/Function/ping_fun.py | 81 +++++ core/__init__.py | 0 core/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 134 bytes core/__pycache__/csv_manager.cpython-313.pyc | Bin 0 -> 6552 bytes .../__pycache__/logger_config.cpython-313.pyc | Bin 0 -> 1614 bytes .../template_manager.cpython-313.pyc | Bin 0 -> 3566 bytes core/logger_config.py | 26 ++ core/ui/__init__.py | 0 core/ui/__pycache__/__init__.cpython-313.pyc | Bin 0 -> 137 bytes core/ui/__pycache__/basic_ui.cpython-313.pyc | Bin 0 -> 4026 bytes core/ui/__pycache__/tab_ping.cpython-313.pyc | Bin 0 -> 7047 bytes core/ui/__pycache__/ui_main.cpython-313.pyc | Bin 0 -> 1576 bytes core/ui/basic_ui.py | 112 +++++++ core/ui/tab_ping.py | 88 ++++++ core/ui/ui_main copy.py | 297 ++++++++++++++++++ core/ui/ui_main.py | 25 ++ main.py | 21 ++ 21 files changed, 886 insertions(+) create mode 100644 app.log create mode 100644 core/Function/__init__.py create mode 100644 core/Function/__pycache__/__init__.cpython-313.pyc create mode 100644 core/Function/__pycache__/ping_fun.cpython-313.pyc create mode 100644 core/Function/ping_fun.py create mode 100644 core/__init__.py create mode 100644 core/__pycache__/__init__.cpython-313.pyc create mode 100644 core/__pycache__/csv_manager.cpython-313.pyc create mode 100644 core/__pycache__/logger_config.cpython-313.pyc create mode 100644 core/__pycache__/template_manager.cpython-313.pyc create mode 100644 core/logger_config.py create mode 100644 core/ui/__init__.py create mode 100644 core/ui/__pycache__/__init__.cpython-313.pyc create mode 100644 core/ui/__pycache__/basic_ui.cpython-313.pyc create mode 100644 core/ui/__pycache__/tab_ping.cpython-313.pyc create mode 100644 core/ui/__pycache__/ui_main.cpython-313.pyc create mode 100644 core/ui/basic_ui.py create mode 100644 core/ui/tab_ping.py create mode 100644 core/ui/ui_main copy.py create mode 100644 core/ui/ui_main.py create mode 100644 main.py diff --git a/app.log b/app.log new file mode 100644 index 0000000..f28a2b5 --- /dev/null +++ b/app.log @@ -0,0 +1,236 @@ +2025-10-31 08:51:31,451 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 08:51:46,310 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 08:51:46,357 [INFO] 工具运行根目录E:\Git\Network-tools +2025-10-31 09:45:17,149 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 09:45:46,158 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:15:27,393 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:21:24,945 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:21:59,053 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:22:13,870 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:24:12,023 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:25:04,686 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:28:24,939 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:33:28,135 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:41:15,491 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:42:22,366 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 10:51:32,190 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:20:58,065 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:23:34,531 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:26:32,610 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:29:44,348 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:30:13,851 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:31:57,746 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:32:48,306 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:33:04,570 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:33:11,784 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:42:59,572 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:43:31,773 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 11:43:38,061 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:44:18,005 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:44:19,638 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:44:21,100 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:44:32,317 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:44:33,305 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:44:34,377 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:44:47,235 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:44:55,638 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:45:00,578 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:45:47,104 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:45:50,838 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:45:54,654 [INFO] 开始Ping 127.0.0.1 +2025-10-31 11:46:17,406 [INFO] 开始Ping 192.168.151.240 +2025-10-31 11:46:29,080 [INFO] 开始Ping 192.168.151.240 +2025-10-31 11:48:03,804 [INFO] 开始Ping +2025-10-31 11:48:10,070 [INFO] 开始Ping 192.168 +2025-10-31 11:49:00,068 [INFO] 开始Ping 192.168 +2025-10-31 11:49:21,876 [INFO] 开始Ping 192.168 +2025-10-31 11:49:21,966 [INFO] 开始Ping 192.168 +2025-10-31 11:49:25,174 [INFO] 开始Ping 192.167 +2025-10-31 11:49:28,098 [INFO] 开始Ping 192.166 +2025-10-31 11:50:25,990 [INFO] 开始Ping www.feixiangdayezhu.top +2025-10-31 11:50:32,143 [INFO] 开始Ping www.feixiangdayezhu.top +2025-10-31 11:58:31,183 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 12:02:24,907 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 12:02:26,560 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:38:40,411 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 12:38:42,464 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:39:19,146 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 12:39:20,324 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:40:37,507 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 12:40:39,056 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:40:42,804 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:40:49,762 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:53:01,888 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 12:53:03,302 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:53:32,510 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:57:43,441 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 12:57:45,013 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:57:46,557 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:59:28,214 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 12:59:29,475 [INFO] 开始Ping 127.0.0.1 +2025-10-31 12:59:31,041 [INFO] 停止Ping 127.0.0.1 +2025-10-31 12:59:49,953 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:00:18,478 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:00:21,031 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:00:22,589 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:00:27,537 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:00:30,079 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:02:14,767 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:02:16,311 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:02:19,167 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:02:20,081 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:02:20,981 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:03:35,574 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:03:44,390 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:03:52,524 [INFO] 开始Ping 127.0.0.2 +2025-10-31 13:03:58,455 [INFO] 开始Ping 127.0123 +2025-10-31 13:04:01,094 [INFO] 停止Ping 127.0123 +2025-10-31 13:04:17,880 [INFO] 开始Ping 192.168.10.123 +2025-10-31 13:04:19,506 [INFO] 停止Ping 192.168.10.123 +2025-10-31 13:04:26,290 [INFO] 开始Ping 192.168.10.123 +2025-10-31 13:11:03,719 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:11:05,943 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:11:09,009 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:10,539 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:12,750 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:14,039 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:15,209 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:15,921 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:16,153 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:16,341 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:16,543 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:16,770 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:16,993 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:17,218 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:17,422 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:17,624 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:20,217 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:21,560 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:22,519 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:11:23,417 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:16:21,209 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:16:23,970 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:16:27,643 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:19:27,120 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:19:28,182 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:19:29,802 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:20:02,260 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:20:04,024 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:20:05,720 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:20:54,925 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:21:01,586 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:21:03,566 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:21:32,594 [INFO] 开始Ping 192.168.151.240 +2025-10-31 13:21:40,480 [INFO] 停止Ping 192.168.151.240 +2025-10-31 13:21:51,388 [INFO] 开始Ping 192.168.151.240 +2025-10-31 13:21:58,524 [INFO] 停止Ping 192.168.151.240 +2025-10-31 13:34:30,231 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:34:31,640 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:34:34,482 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:35:35,838 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:35:42,707 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:35:44,622 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:38:03,930 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:38:05,174 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:38:07,227 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:38:39,157 [INFO] 开始Ping www.feixiandayezhu.top +2025-10-31 13:38:47,995 [INFO] 停止Ping www.feixiangdayezhu.top +2025-10-31 13:38:48,791 [INFO] 开始Ping www.feixiangdayezhu.top +2025-10-31 13:38:55,178 [INFO] 停止Ping www.feixiangdayezhu.top +2025-10-31 13:38:59,249 [INFO] 开始Ping www.feixiangdayehu.top +2025-10-31 13:39:02,209 [INFO] 停止Ping www.feixiangdayehu.top +2025-10-31 13:39:12,579 [INFO] 开始Ping www.feixiangdayehu.top +2025-10-31 13:39:15,119 [INFO] 停止Ping www.feixiangdayehu.top +2025-10-31 13:39:16,470 [INFO] 开始Ping www.feixiangdayehu.top +2025-10-31 13:39:22,025 [INFO] 停止Ping www.feixiangdayehu.top +2025-10-31 13:42:42,620 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:42:49,590 [INFO] 开始Ping ww。 +2025-10-31 13:43:11,556 [INFO] 开始Ping www.feixiangdayez.top +2025-10-31 13:43:13,506 [INFO] 开始Ping www.feixiangdayez.top +2025-10-31 13:43:15,612 [INFO] 开始Ping www.feixiangdayez.top +2025-10-31 13:43:17,524 [INFO] 停止Ping www.feixiangdayez.top +2025-10-31 13:43:20,080 [INFO] 开始Ping www.feixiangdayez.top +2025-10-31 13:43:21,955 [INFO] 开始Ping www.feixiangdayez.top +2025-10-31 13:43:22,532 [INFO] 开始Ping www.feixiangdayez.top +2025-10-31 13:43:23,536 [INFO] 开始Ping www.feixiangdayez.top +2025-10-31 13:43:26,414 [INFO] 停止Ping www.feixiangdayez.top +2025-10-31 13:44:45,461 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:44:51,580 [INFO] 开始Ping www. +2025-10-31 13:44:57,974 [INFO] 停止Ping www. +2025-10-31 13:44:59,340 [INFO] 开始Ping www. +2025-10-31 13:45:02,060 [INFO] 停止Ping www. +2025-10-31 13:45:03,994 [INFO] 开始Ping www. +2025-10-31 13:45:20,496 [INFO] 开始Ping www.feixiangdayezhu.tt +2025-10-31 13:45:23,284 [INFO] 停止Ping www.feixiangdayezhu.tt +2025-10-31 13:45:37,072 [INFO] 开始Ping www.feixiangdayezhu.top +2025-10-31 13:45:45,236 [INFO] 停止Ping www.feixiangdayezhu.top +2025-10-31 13:45:49,576 [INFO] 开始Ping www.feixiangdahu.top +2025-10-31 13:45:54,494 [INFO] 开始Ping www.feixiangdahu.top +2025-10-31 13:45:56,046 [INFO] 停止Ping www.feixiangdahu.top +2025-10-31 13:45:57,814 [INFO] 开始Ping www.feixiangdahu.top +2025-10-31 13:45:58,768 [INFO] 开始Ping www.feixiangdahu.top +2025-10-31 13:45:59,682 [INFO] 开始Ping www.feixiangdahu.top +2025-10-31 13:46:02,830 [INFO] 开始Ping www.feixianahu.top +2025-10-31 13:46:05,672 [INFO] 开始Ping www.feixianahu.to +2025-10-31 13:47:24,682 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:47:31,549 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:48:04,212 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:48:05,352 [INFO] 开始Ping 127.0.0.1 +2025-10-31 13:48:08,786 [INFO] 停止Ping 127.0.0.1 +2025-10-31 13:48:20,984 [INFO] 开始Ping www.feixiangdayezhu.top +2025-10-31 13:48:29,274 [INFO] 停止Ping www.feixiangdayezhu.top +2025-10-31 13:48:51,354 [INFO] 开始Ping 43.251.226.76 +2025-10-31 13:48:58,048 [INFO] 停止Ping 43.251.226.76 +2025-10-31 13:50:49,309 [INFO] 开始Ping 43.251.226.76 +2025-10-31 13:50:55,823 [INFO] 停止Ping 43.251.226.76 +2025-10-31 13:50:58,687 [INFO] 开始Ping 43.251.226.76 +2025-10-31 13:51:00,637 [INFO] 停止Ping 43.251.226.76 +2025-10-31 13:56:40,523 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:57:00,314 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 13:57:55,928 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:03:57,501 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:04:05,097 [INFO] 开始Ping 127.0.0.1 +2025-10-31 14:04:07,571 [INFO] 停止Ping 127.0.0.1 +2025-10-31 14:04:12,615 [INFO] 开始Ping 12 +2025-10-31 14:04:16,417 [INFO] 停止Ping 12 +2025-10-31 14:05:44,244 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:23:49,003 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:23:59,290 [INFO] 开始Ping 127.0.0.1 +2025-10-31 14:24:02,784 [INFO] 停止Ping 127.0.0.1 +2025-10-31 14:25:09,176 [INFO] 开始由127.0.0.1 Ping 127.0.0.2 +2025-10-31 14:25:15,976 [INFO] 停止由127.0.0.1 Ping 127.0.0.2 +2025-10-31 14:25:27,004 [INFO] 开始由127.0.0.1 Ping www.feixiangdayezhu.top +2025-10-31 14:25:39,846 [INFO] 停止由127.0.0.1 Ping www.feixiangdayezhu.top +2025-10-31 14:25:46,114 [INFO] 开始由127.0.0.1 Ping www.feixiangdayezhu.top +2025-10-31 14:25:46,924 [INFO] 停止由127.0.0.1 Ping www.feixiangdayezhu.top +2025-10-31 14:26:12,106 [INFO] 开始由127.0.0.1 Ping www.feixiangdayezhu.top +2025-10-31 14:26:14,670 [INFO] 停止由127.0.0.1 Ping www.feixiangdayezhu.top +2025-10-31 14:27:11,144 [INFO] 开始由172.24.202.115 Ping www.feixiangdayezhu.top +2025-10-31 14:27:16,196 [INFO] 停止由172.24.202.115 Ping www.feixiangdayezhu.top +2025-10-31 14:27:43,272 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:27:44,512 [INFO] 开始Ping +2025-10-31 14:27:46,552 [INFO] 开始由 Ping +2025-10-31 14:28:16,262 [INFO] 停止由 Ping +2025-10-31 14:28:16,772 [INFO] 停止Ping +2025-10-31 14:28:20,146 [INFO] 开始Ping +2025-10-31 14:28:23,143 [INFO] 停止Ping +2025-10-31 14:29:42,750 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:29:54,403 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:29:55,904 [INFO] 开始Ping +2025-10-31 14:29:58,850 [INFO] 开始由 Ping +2025-10-31 14:30:02,014 [INFO] 停止Ping +2025-10-31 14:30:02,726 [INFO] 停止由 Ping +2025-10-31 14:30:35,157 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:30:37,931 [INFO] 开始Ping +2025-10-31 14:30:44,723 [INFO] 停止Ping +2025-10-31 14:33:21,501 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:33:22,599 [INFO] 开始Ping +2025-10-31 14:33:27,367 [INFO] 停止Ping +2025-10-31 14:33:28,283 [INFO] 开始由 Ping +2025-10-31 14:33:32,113 [INFO] 停止由 Ping +2025-10-31 14:33:36,679 [INFO] 开始Ping +2025-10-31 14:33:38,493 [INFO] 停止Ping +2025-10-31 14:33:39,221 [INFO] 开始由 Ping +2025-10-31 14:33:40,697 [INFO] 停止由 Ping +2025-10-31 14:49:43,147 [INFO] 日志系统初始化完成,日志文件路径:E:\Git\Network-tools\app.log +2025-10-31 14:49:48,110 [INFO] 停止Ping diff --git a/core/Function/__init__.py b/core/Function/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/Function/__pycache__/__init__.cpython-313.pyc b/core/Function/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..76ae9aabf771d0262a3ccb25e2b7631bdcbe8d58 GIT binary patch literal 143 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 literal 0 HcmV?d00001 diff --git a/core/__pycache__/csv_manager.cpython-313.pyc b/core/__pycache__/csv_manager.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..70d1f74a2c74d4cce8bd44087926c9540c062cb0 GIT binary patch literal 6552 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 literal 0 HcmV?d00001 diff --git a/core/__pycache__/logger_config.cpython-313.pyc b/core/__pycache__/logger_config.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..6276e03ae6d512fbe32e4c435f6091369a1ab0c5 GIT binary patch literal 1614 zcmbVM&2Jk;6rZ)%*-gB$Y4`|&N^wlmdXW;i1X>!nAc7H5sIrQL4g$rOiN`$9cLg=;_o3imcZjgv#1t-Fv*aXkZ&TX9p)Cpek^ zi(MOw?O(Q!Hp*#sP!Dn}Q-tycMVuNmx8fRNF_c(6M(O|n5xyY;p2Nd5JpiU%6uymuj~bt)Ggu zl~rr~%W6Jnt=y`8zHa?|?ZIZjy0~er|7dOItl}q?yH~3DPp!g5(iTU?9Mne;+pR1T zApuR*G!b#*^O(2{O!%~F&JbZbiF7puNe7&Tv5cusX^;r&6t=y*iW2A6K%I3>o`2(& z$v2bck^Lcrr1VK2IcCE;^-R7^V5qWAr*35}&0k z2P%TEfUkycz#XCQp3qnJA1h|_+2TTeVFjg%4*`wA!3Nsd7N8AL2P3`tNgh3C!^ilza3DL<1O?~NK2UWo zB0Bb?;1vW-e#wbEI2Biu{|HC~!33wc75;Q{99v=w1%Wfs3ogZT+8t=F+tm_G)gVyX zCLT?3DEf(`q9ac^)+SgAV{?Ly* zv6`UDoF`+(2TsWx5uqM4rjvR?b`y^sPN8a`lxh-jM%AY^h;W8YRlWX|_3QQ8_Zzj1 zRqOH>*4K+xVaZxAR4-qppl^7qOP4AeKit1_+xq3>2b-VuV_CAXhS>Wd_C$n#-$?32 zU;w2>iI-wB8GGHvDdFE58+nI#N0J&0H%gOE#Y9j|IVzvj;|6J`U>>y*PQ+-GjTeo| zE+RVkCL&EAjng!k0VEJWepXt-(9EQxtTaTZmzo$9@GNCHQ1(B&IG+nU*uRj!a3g#( zS@OS_3s-pW4&S}acb9!n7PY+ghyPSXdVELf*_L{4ir>9_PdZa(dhfQ>Tauo8=y7*- z>8y~kJHEqPCD@h9wWMfRX>+CyVW?04GO z8EX)+zn2}<7(pCP8PgdJzJ`L-!G4BtKD0-W7m<}P zEl`*dXv_*s8N!^vg0u)6NULB0X%np29qD<^-1=+c#^v?f_Y!}2KwZw0y9R8%?x|O8Pz<+x`h!ONcZbW}g#1YhqBB@QF5b{v%AJUrbyibwD zKp1P;YSKP2;8T4bT4NO{62vx8RmikFuhl-&;5{8yz3r0P8^v9?o?a_($atDD*eR!FA%$&r6jM7P^Tob)G4k&69yO&peAzC;fB!ObbF;hzHwbx(1|C3nC8_BXn)NbvH5i zHm~|ZqCYAJ!y$hC-CK$KBdarStY80KIw6Vv(T#~I&9O5yb_6EaX_}gE5?tP!`s$Ob ziMxN^xcpJ#%2cBN-Ne0*zxw35$Dz?tMPqw>>IIFx7!Aw1+iMo-m9U~JnyuT{B>^Lf zW{E^Yz^-QP^!eBsq zFNx}<9!b&oOhhtA5cg2t2hoRCOWk9|?-Y-fzf(RQnCzbDp7t)3HudMMxbg;j2YLrz z8+h%SyyU8#bJeama|TNj2Ib|?x$D2y z$8RFa-b{V7r8kspuyD5M6xV!^{cOJlf}%Y-n}nqjYKvj@AbH*4`W7FDg-)H^K}iS4yk|L~?YJ zI+LC2uX2aUc#jbh>rAFsXDgiIE0e8()n z9ZXIUip=as=S+X^ghWMP1oi|&BbiO}ZZifMT10}UnrRZ`4J235i@=dz>W+taWJaNm zJ>rL8>11{@0#SGmE^1H}dJ35y4(Ac1c~psb__fzHGLQTcmz%He#9*d46CVSFs!Ei*9ech5~ zCpD4ah!2n+N>YfY5++krW|KusEVYVE7I$^?psd^k0R$HA8$CUIdbDl0ZM<-@VxnT& zIn%XJc(&iZNn7kSD|tmj;qij0-ub*^Ge21Qo@esKKfXBi@(11_b}_daf=>SNRlu@! zpfz4rH+^FI$#}`hMdyzJ$yGJys*2mH9%aL@FY=Ck`!5U1E!{>m%qZe}&*p_%d~#QeRG zhw3bHH04-l9ad7$b2Ph{S$Ac#gZa$CK^+svYKL3`@?LV1koP)7u{#=w!Fh_BQxsp0 z`69_4mna4yp->}XS(2mBZ572p)Gvydz=$CpAY4O49SE&R6cyE{hW(;XRdM)yOqCQ- z{19QnlAcjuLcA`B6-ot&*U{HB&DpjrG{xN1X_D0!@gQyqdj zq%)A;ki5nY7jK)M>tGbydP!#n5*&m>+2Po$s d_S_|V*}T2%+VKT@O`qivdw{CmLLl^+{tK`6LmB`8 literal 0 HcmV?d00001 diff --git a/core/logger_config.py b/core/logger_config.py new file mode 100644 index 0000000..5282afa --- /dev/null +++ b/core/logger_config.py @@ -0,0 +1,26 @@ +import logging +import os +import sys + +def get_base_dir(): + """获取程序真实所在目录,兼容开发与打包""" + if getattr(sys, 'frozen', False): # 打包后的 exe + return os.path.dirname(sys.executable) + else: # 普通 Python 运行 + return os.path.dirname(os.path.abspath(sys.argv[0])) + +def setup_logger(): + base_dir = get_base_dir() + log_file = os.path.join(base_dir, 'app.log') # 直接放在 main 同级目录 + + logging.basicConfig( + level=logging.INFO, + format='%(asctime)s [%(levelname)s] %(message)s', + handlers=[ + logging.FileHandler(log_file, encoding='utf-8'), + logging.StreamHandler() + ] + ) + + logging.info("日志系统初始化完成,日志文件路径:%s", log_file) + return logging.getLogger(__name__) diff --git a/core/ui/__init__.py b/core/ui/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/ui/__pycache__/__init__.cpython-313.pyc b/core/ui/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..1d52f903ed7067aa41c7b8e4e89a0003dc7caafc GIT binary patch literal 137 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 T=UDQhbY2>N=str_wDbQ0aqy0{ literal 0 HcmV?d00001 diff --git a/core/ui/__pycache__/ui_main.cpython-313.pyc b/core/ui/__pycache__/ui_main.cpython-313.pyc new file mode 100644 index 0000000000000000000000000000000000000000..ed6c54269a5f9c037e42dd9c0f5f365b3bd92ec0 GIT binary patch literal 1576 zcmZ`(&2Jk;6o32S^{%tA15HHirpd|;Y8TYhO|jIXhy&s)35|*uL!}yx*3QJNy!M*e zu}E|32_>RZxkO44QgSR35+^SF6*Y-)Gzf8MLF5(@dS_s8{B}=9 zM^nJpXH%*dC;(4|60gJnoNREg4GuWcG7yPNc^Q^uA}=XKSyG8=37fK_|j$ zF?WWA9oV@!|eEMSlIP-$UpJkl6`*MtjvNSQoF)9wgIrv~2pu=lyUwrYC zO0UE|LwRT3(M6uOEPxTPpboaNvN5`X>6Za%STqRykR@*v3hTu};k_e46Q))J`nfGL z4X?M|)+$pu>->&rq+r%xKYji8kK3GQD#h#6HknF-fU*SjsE?Um$3YWQa*r7Vhu(%; z^)V4VVERfxIaz}S8=-C$)q)l!fzQ;oTWb(8Q6A8(hAiPx+zgrGuCCfDQ$y^p5z#89 zw%jJ>?*YH0a^2#KU3&M;%KILz4C=WO)l;bj1Xns9|Dh%)^IZEL(-HDo9z}>{`uv`Y z4@P*b@CUx#hr{v72gadpJ~XzBhncO+PUb+rJkWc3uB+#EZXW2bij(wK`kT%UKG0{M zouA%a_;%s3x_|!4rh1@Ha&u3g?CO&}{X$p2u=mm9Po4<$#<2#Y+3zmx&Gz#1-TeH1 z?)tGJPoy^02gb1ux#`{PqwMa?qnTf`uWc=EzH?}f^~|ZRIn^_*u4(O^dtzGqX5k+N za<8B8e8E#~0W{=!=f)4=fpk);tnY-)rGkfDo~` zGn+stq%QSp$fcBc)eglWLf-?)i}*8Q6ZDNXL55Ha?JIaLrxVxucZAtavm|YJEs6<~ zX(O6F5%VJAy=G%#Hgg?st}4D)sN)gw`VEf-HQJnIeMThthpx^wX4EnLkYh~9MR8vf z2ChU2T^7+#lVtirzwEb2fg1#)!|QxIRwPOK4aWa~t6jMIC(Qm1vri#?XpHrY+%HCM X=f=J=0: + var.set(listbox[inivar]) + + return { + "frame": frame, + "label": label, + "combobox": combobox, + "var": var + } + + def add_button( + self, parent, button_text, + row, col=0, command="", + label_width=8, entry_width=20, colspan=1, sticky='w' + ): + """ + 添加一个按钮,并返回 (StringVar, Frame) 以便后续控制。 + - parent: 父容器 + - button_text: 按钮文本 + - row, col: 放置在父容器的 grid 行列 + - command: 调用的函数 + - entry_width: 输入框宽度 + - colspan: 该组控件在父容器上跨越的列数 + - sticky: 对齐方式(默认左对齐) + """ + group_frame = ttk.Frame(parent) + group_frame.grid(row=row, column=col, columnspan=colspan, sticky=sticky, padx=5, pady=3) + + btn = ttk.Button(group_frame, text=button_text, command=command) + btn.grid(row=0, column=0, sticky='w') + return { + "frame": group_frame, + "btn": btn, + } + \ No newline at end of file diff --git a/core/ui/tab_ping.py b/core/ui/tab_ping.py new file mode 100644 index 0000000..9355c8f --- /dev/null +++ b/core/ui/tab_ping.py @@ -0,0 +1,88 @@ +import tkinter as tk +from tkinter import ttk, filedialog, messagebox, scrolledtext + +from core.ui.basic_ui import BasicUI +from core.Function.ping_fun import PingFun + +import logging +logger = logging.getLogger(__name__) + +class PingTab(ttk.Frame, BasicUI): + def __init__(self, parent): + super().__init__(parent) + self.ping_ui() + self.ping_fun = PingFun(self.result_box) + + def ping_ui(self): + """ping界面布局""" + self.create_allIP_section() + self.create_assignIP_section() + self.create_outputping_section() +# --------------------------------------UI界面布局函数-------------------------------------- + def create_allIP_section(self): + # 区域标签 + frame = ttk.LabelFrame(self, text="PING 目标IP") + frame.pack(side='top', fill='x', padx=10, pady=5) + + self.entry_allIP = self.add_input(frame, "目标IP", row=0, col=0) + self.allIP_startPing = self.add_button(frame, "开始ping", row=0, col=1, command=self.btn_allIP_startPing) + self.allIP_stopPing = self.add_button(frame, "停止ping", row=0, col=2, command=self.btn_allIP_stopPing) + + def create_assignIP_section(self): + # 区域标签 + frame = ttk.LabelFrame(self, text="指定IP PING 目标IP") + frame.pack(side='top', fill='x', padx=10, pady=5) + + self.entry_assignIP_A = self.add_input(frame, "本地IP", row=0, col=0) + self.entry_assignIP_B = self.add_input(frame, "目标IP", row=0, col=1) + self.assignIP_startPing = self.add_button(frame, "开始ping", row=0, col=2, command=self.btn_assignIP_startPing) + self.assignIP_stopPing = self.add_button(frame, "停止ping", row=0, col=3, command=self.btn_assignIP_stopPing) + + def create_outputping_section(self): + # 区域标签 + frame = ttk.LabelFrame(self, text="PING 结果输出") + frame.pack(side='top', fill='x', padx=10, pady=5) + + self.result_box = scrolledtext.ScrolledText(frame, width=100, height=20) + self.result_box.pack(pady=10) +# --------------------------------------按钮回调函数-------------------------------------- + def btn_allIP_startPing(self): + if not self.entry_allIP['var'].get(): + messagebox.showwarning("输入错误", "请输入IP或域名!") + return + logger.info(f"开始Ping {self.entry_allIP['var'].get()}") + self.ping_fun.strat_ping(self.entry_allIP['var'].get(), callback=self.allIP_ping_callback) + self.allIP_startPing['btn'].config(state='disabled') + + def btn_allIP_stopPing(self): + logger.info(f"停止Ping {self.entry_allIP['var'].get()}") + self.ping_fun.stop_ping() + self.allIP_startPing['btn'].config(state='normal') + + def allIP_ping_callback(self): + self.allIP_startPing['btn'].config(state='normal') + + def btn_assignIP_startPing(self): + if not self.entry_assignIP_B['var'].get(): + messagebox.showwarning("输入错误", "请输入IP或域名!") + return + logger.info(f"开始由{self.entry_assignIP_A['var'].get()} Ping {self.entry_assignIP_B['var'].get()}") + self.ping_fun.strat_ping(self.entry_assignIP_B['var'].get(),local_ip=self.entry_assignIP_A['var'].get(), + callback=self.assignIP_ping_callback) + self.assignIP_startPing['btn'].config(state='disabled') + + def btn_assignIP_stopPing(self): + logger.info(f"停止由{self.entry_assignIP_A['var'].get()} Ping {self.entry_assignIP_B['var'].get()}") + self.ping_fun.stop_ping() + self.assignIP_startPing['btn'].config(state='normal') + + def assignIP_ping_callback(self): + self.assignIP_startPing['btn'].config(state='normal') + + + + + + + + \ No newline at end of file diff --git a/core/ui/ui_main copy.py b/core/ui/ui_main copy.py new file mode 100644 index 0000000..b6a5087 --- /dev/null +++ b/core/ui/ui_main copy.py @@ -0,0 +1,297 @@ +import tkinter as tk +from tkinter import ttk, filedialog, messagebox +import os + +import logging +from core.template_manager import TemplateManager +from core.csv_manager import CSVManager + + +logger = logging.getLogger(__name__) + +class MainUI: + def __init__(self, root, base_dir): + self.root = root + self.root.title("KingSCADA 点表生成工具") # 窗口标题 + self.root.geometry("1000x400") # 窗口大小 + root.resizable(False, False) # 禁止水平和垂直调整大小 + + self.base_dir = base_dir + self.template_manager = TemplateManager(base_dir) + self.csv_manager = CSVManager(base_dir) + # 初始化导入数据模板数据 + self.template_data = [] + self.csv_data = [] + + self.build_ui() + logging.info(f"工具运行根目录{base_dir}") + + def build_ui(self): + # 第一行容器:模板区 + CSV区 + top_row = ttk.Frame(self.root) + top_row.pack(side='top', fill='x', padx=5, pady=5) + + self.create_template_section(parent=top_row) + self.create_csv_section(parent=top_row) + + # 第二行:参数区 + self.create_input_section() + + # 第三行:生成区 + self.create_generate_section() + + # ---------------- 模板区 ---------------- + def create_template_section(self, parent): + frame = ttk.LabelFrame(parent, text="配置文件选择", padding=5) + frame.pack(side='left', padx=5, pady=5, anchor='nw') + + self.device_cb = self._add_combobox(frame, "设备类型:", row=0, col=0, listbox=self.template_manager.get_device_types(), inivar=-1) + # 选择完成事件 + self.device_cb["combobox"].bind('<>', self.on_device_selected) + + self.template_cb = self._add_combobox(frame, "模板文件:", row=0, col=1, listbox=[], inivar=-1) + #选择完成事件 + self.template_cb['combobox'].bind('<>', self.on_template_selected) + # 模板显示表格 + self.template_table = ttk.Treeview(frame, columns=("name","desc","type","access","address"), show="headings", height=5) + col_defs = { + "name": ("名称", 100), + "desc": ("描述", 130), + "type": ("类型", 100), + "access": ("读写", 80), + "address": ("地址", 78), + } + for col, (text, width) in col_defs.items(): + self.template_table.heading(col, text=text) + self.template_table.column(col, width=width, anchor="center") + self.template_table.grid(row=1, column=0, columnspan=4, sticky='nsew', pady=(9,5)) + + def on_device_selected(self, event=None): + """设备类型选择完成事件""" + # 获取目录下的所有模板文件 + device = self.device_cb['var'].get() + self.template_cb['combobox']['values'] = self.template_manager.get_templates_by_device(device) + #更新参数区的内容 + if device == "SIEMENS" : + for row in self.template_table.get_children(): #清空表格 + self.template_table.delete(row) + self.template_cb['var'].set("") #清空模板选择 + self.deviceseries['combobox']['values'] = self.deviceseries_siemens #更新设备系列选项 + self.channeldriver['combobox']['values'] = self.channeldriver_siemens #更新通道驱动选项 + self.deviceseries['var'].set(self.deviceseries_siemens[0]) #设置默认值 + self.channeldriver['var'].set(self.channeldriver_siemens[0]) #设置默认值 + self.db_num["frame"].grid() #显示DB块号输入框 + if device == "AB" : + for row in self.template_table.get_children(): + self.template_table.delete(row) + self.template_cb['var'].set("") + self.deviceseries['combobox']['values'] = self.deviceseries_ab + self.channeldriver['combobox']['values'] = self.channeldriver_ab + self.deviceseries['var'].set(self.deviceseries_ab[0]) + self.channeldriver['var'].set(self.channeldriver_ab[0]) + self.db_num["frame"].grid_remove() #隐藏DB块号输入框 + + + def on_template_selected(self, event=None): + """模板文件选择完成事件""" + device = self.device_cb['var'].get() + template = self.template_cb['var'].get() + self.template_data = self.template_manager.load_template(device, template) + self.refresh_template_table() + + def refresh_template_table(self): + """刷新模板显示表格""" + for row in self.template_table.get_children(): + self.template_table.delete(row) + try: + for item in self.template_data: + self.template_table.insert('', 'end', values=(item['name'], item['desc'], item['type'], item['access'], item['address'])) + except Exception as e: + for row in self.template_table.get_children(): + self.template_table.delete(row) + logger.error(f"加载模板异常{e}") + messagebox.showwarning("加载出错", f"加载模板异常{e}", icon="error") + + # ---------------- CSV区 ---------------- + def create_csv_section(self, parent): + frame = ttk.LabelFrame(parent, text="CSV 数据导入", padding=5) + frame.pack(side='left', padx=5, pady=5, anchor='nw') + + btn = ttk.Button(frame, text="选择CSV文件", command=self.load_csv_file) + btn.grid(row=0, column=0, sticky='w') + + self.csv_table = ttk.Treeview(frame, columns=("code","desc","offset"), show="headings", height=5) + col_defs = { + "code": ("设备代号", 150), + "desc": ("设备名称", 180), + "offset": ("拼接地址", 120), + } + for col, (text, width) in col_defs.items(): + self.csv_table.heading(col, text=text) + self.csv_table.column(col, width=width, anchor="center") + self.csv_table.grid(row=1, column=0, columnspan=4, sticky='nsew', pady=5) + + def load_csv_file(self): + filepath = filedialog.askopenfilename(filetypes=[("CSV Files", "*.csv")]) + if not filepath: + return + self.csv_data = self.csv_manager.load_csv(filepath) + self.refresh_csv_table() + + def refresh_csv_table(self): + """刷新CSV显示表格""" + for row in self.csv_table.get_children(): + self.csv_table.delete(row) + try: + for row in self.csv_data: + self.csv_table.insert('', 'end', values=(row['设备代号'], row['设备描述'], row['拼接地址'])) + except Exception as e: + for row in self.csv_table.get_children(): + self.csv_table.delete(row) + logger.error(f"导入数据异常{e}") + messagebox.showwarning("导入出错", f"导入数据异常{e}\n检查第一行列名是否正确", icon="error") + + # ---------------- 参数区 ---------------- + def create_input_section(self): + frame = ttk.LabelFrame(self.root, text="参数输入", padding=10) + frame.pack(side='top', fill='x', padx=10, pady=5) + + self.start_id = self._add_input(frame, "起始ID", row=0, col=0, inivar=1001) + self.dev_name = self._add_input(frame, "设备名称", row=0, col=1, inivar="PLC1") + self.group_name = self._add_input(frame, "分组路径", row=0, col=2, inivar="TEST.一期") + self.group_name_en = self._add_combobox(frame, "设备分组", row=0, col=3, listbox=["禁用", "启用"]) + + self.link = self._add_combobox(frame, "采集链路", row=1, col=0, listbox=["以太网", "COM"]) + #选择完成事件 + self.link["combobox"].bind('<>', self.on_link_selected) + self.link_com = self._add_input(frame, "串口号", row=1, col=1, inivar="11") + self.link_ip = self._add_input(frame, "IP地址", row=1, col=1, inivar="192.168.10.11") + + self.deviceseries_siemens = ["S7-1500", "S7-1200", "S7-300"] + self.channeldriver_siemens = ["S71500Tcp", "S71200Tcp", "S7300Tcp"] + self.deviceseries_ab = ["AB-ControlLogixTCP"] + self.channeldriver_ab = ["ControlLogix"] + self.deviceseries = self._add_combobox(frame, "设备系列", row=2, col=0, listbox=self.deviceseries_siemens) + self.channeldriver = self._add_combobox(frame, "通道驱动", row=2, col=1, listbox=self.channeldriver_siemens) + self.db_num = self._add_input(frame, "DB块号", row=2, col=2, inivar="3") + + def on_link_selected(self, event=None): + """链路选择完成事件""" + link_var = self.link["var"].get() + if link_var == "以太网" : + self.link_com["frame"].grid_remove() + self.link_ip["frame"].grid() + if link_var == "COM" : + self.link_ip["frame"].grid_remove() + self.link_com["frame"].grid() + + def _add_input( + self, parent, label_text, + row, col=0, inivar="", + label_width=8, entry_width=20, colspan=1, sticky='w' + ): + """ + 添加一个带文本标签和输入框的组合控件,并返回 (StringVar, Frame) 以便后续控制。 + - parent: 父容器 + - label: 标签文字 + - row, col: 放置在父容器的 grid 行列 + - inivar: 初始值 + - entry_width: 输入框宽度 + - colspan: 该组控件在父容器上跨越的列数 + - sticky: 对齐方式(默认左对齐) + """ + group_frame = ttk.Frame(parent) + group_frame.grid(row=row, column=col, columnspan=colspan, sticky=sticky, padx=5, pady=3) + + # 标签 + label = ttk.Label(group_frame, text=label_text + ":", width=label_width, anchor='w').grid(row=0, column=0, sticky='w', padx=(0, 5)) + + # 输入框 + var = tk.StringVar(value=inivar) + entry = ttk.Entry(group_frame, textvariable=var, width=entry_width) + entry.grid(row=0, column=1, sticky='w') + + return { + "frame": group_frame, + "label": label, + "entry": entry, + "var": var + } + + def _add_combobox( + self, parent, label_text, row, col=0, + listbox=[], inivar=0, width=17, colspan=1, + sticky='w', label_width=8, state="readonly" + ): + """ + 创建一组 [标签 + 下拉框] 控件。 + 返回 dict,方便外部单独或统一控制。 + + - values: 下拉选项列表 + - default: 初始值(可选) + - state: "readonly" 表示只能从列表选,"normal" 可手动输入 + """ + frame = ttk.Frame(parent) + frame.grid(row=row, column=col, columnspan=colspan, sticky=sticky, padx=5, pady=3) + + # 标签 + label = ttk.Label( + frame, + text=label_text + ":", + width=label_width, + anchor='w' + ) + label.grid(row=0, column=0, sticky='w', padx=(0, 5)) + + # 变量 + 下拉框 + var = tk.StringVar() + combobox = ttk.Combobox( + frame, + textvariable=var, + values=listbox, + width=width, + state=state + ) + combobox.grid(row=0, column=1, sticky='w') + if inivar>=0: + var.set(listbox[inivar]) + + return { + "frame": frame, + "label": label, + "combobox": combobox, + "var": var + } + + + # ---------------- 生成区 ---------------- + def create_generate_section(self): + frame = ttk.Frame(self.root) + frame.pack(fill='x', padx=10, pady=5) + + btn = ttk.Button(frame, text="生成点表文件", command=self.generate_csv) + btn.pack(anchor='center') + + def generate_csv(self): + if not self.template_data or not self.csv_data: + messagebox.showwarning("警告", "请先加载模板和CSV数据!") + return + + inputs = { + "start_id": self.start_id["var"].get(), #起始ID + "ip": self.link_ip["var"].get(), + "device_name": self.dev_name["var"].get(), #设备名称 + "group_name": self.group_name["var"].get(), #分组路径 + "link":self.link["var"].get(), #链路选择 + "link_ip":self.link_ip["var"].get(), #IP地址 + "link_com":self.link_com["var"].get(), #串口号 + "deviceseries": self.deviceseries["var"].get(), #设备系类 + "channeldriver": self.channeldriver["var"].get(), #通道驱动 + "db_num": self.db_num["var"].get(), #DB块号 + "device": self.device_cb["var"].get(), #设备类型 + "group_name_en": self.group_name_en["var"].get() #设备分组是否启用 + } + + output_path = self.csv_manager.generate_output(self.template_data, inputs) + messagebox.showwarning("生成成功", output_path, icon="info") + \ No newline at end of file diff --git a/core/ui/ui_main.py b/core/ui/ui_main.py new file mode 100644 index 0000000..b57f31d --- /dev/null +++ b/core/ui/ui_main.py @@ -0,0 +1,25 @@ +import tkinter as tk +from tkinter import ttk, filedialog, messagebox + +from core.ui.basic_ui import BasicUI +from core.ui.tab_ping import PingTab + +import logging +logger = logging.getLogger(__name__) + +class MainUI(BasicUI): + def __init__(self, root): + self.root = root + self.root.title("Network tools") # 窗口标题 + self.root.geometry("800x500") # 窗口大小 + root.resizable(False, False) # 禁止水平和垂直调整大小 + # 创建 Notebook 作为多标签页容器 + self.tab_control = ttk.Notebook(root) + self.tab_control.pack(expand=1, fill="both") + # 实例化各个功能页 + self.tabs = { + "Ping测试": PingTab(self.tab_control), + } + # 添加到 Notebook + for name, tab in self.tabs.items(): + self.tab_control.add(tab, text=name) \ No newline at end of file diff --git a/main.py b/main.py new file mode 100644 index 0000000..780b197 --- /dev/null +++ b/main.py @@ -0,0 +1,21 @@ +import sys +import os +import tkinter as tk + +from core.logger_config import setup_logger +from core.ui.ui_main import MainUI + +if __name__ == "__main__": + # 进行日志配置 + setup_logger() + # 判断是否是打包后的环境 + if getattr(sys, 'frozen', False): + # 打包后的路径(exe所在的目录) + base_dir = os.path.dirname(sys.executable) + else: + # 普通Python运行时 + base_dir = os.path.dirname(os.path.abspath(__file__)) + # 启动主界面 + root = tk.Tk() + app = MainUI(root) + root.mainloop()