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 0000000..76ae9aa Binary files /dev/null and b/core/Function/__pycache__/__init__.cpython-313.pyc differ diff --git a/core/Function/__pycache__/ping_fun.cpython-313.pyc b/core/Function/__pycache__/ping_fun.cpython-313.pyc new file mode 100644 index 0000000..cd4a021 Binary files /dev/null and b/core/Function/__pycache__/ping_fun.cpython-313.pyc differ diff --git a/core/Function/ping_fun.py b/core/Function/ping_fun.py new file mode 100644 index 0000000..0d2c20a --- /dev/null +++ b/core/Function/ping_fun.py @@ -0,0 +1,81 @@ +import tkinter as tk +from tkinter import scrolledtext, messagebox +import subprocess +import platform +import threading +import re + +class PingFun: + def __init__(self, result_box: scrolledtext.ScrolledText): + self.result_box = result_box + + # Ping 状态和统计 + self.process = None # 子进程对象 + self.stop_flag = False # 停止标志 + self.sent = 0 # 发送的包数 + self.received = 0 # 接收的包数 + self.rtts = [] # 存储延迟值 + + def strat_ping(self, host, local_ip=None, callback=None): + """开始 ping""" + self.callback = callback + + # 清空显示框和统计数据 + self.result_box.delete('1.0', tk.END) + self.sent = 0 + self.received = 0 + self.rtts.clear() + self.stop_flag = False + + command = ['ping', host, '-t'] + if local_ip: + command += ['-S', local_ip] + + threading.Thread(target=self.ping, args=(command,), daemon=True).start() + + def stop_ping(self): + """手动停止 ping""" + if self.process: + self.process.terminate() # 立即终止子进程 + self.result_box.insert(tk.END, "\nPing 已手动停止。\n") + self.result_box.see(tk.END) + self.process = None + self.show_statistics() + + def ping(self, command): + """执行 ping 命令并处理输出""" + rtt_pattern = re.compile(r'时间[=<](\d+)ms', re.IGNORECASE) + try: + self.process = subprocess.Popen(command, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, universal_newlines=True) + for line in iter(self.process.stdout.readline, ''): + if self.stop_flag: + break + if line: + self.result_box.insert(tk.END, line) + self.result_box.see(tk.END) + self.sent += 1 + # 解析延迟 + match = rtt_pattern.search(line) + if match: + self.received += 1 + self.rtts.append(float(match.group(1))) + except Exception as e: + self.result_box.insert(tk.END, f"Ping 失败: {e}\n") + finally: + # 清理进程对象 + self.process = None + if self.callback: + self.callback() + + def show_statistics(self): + """显示统计信息""" + if self.sent == 0: + return + loss = (self.sent - self.received) / self.sent * 100 + stats = f"\n==== Ping 统计 ====\n" \ + f"发送: {self.sent},接收: {self.received},丢包率: {loss:.2f}%\n" + if self.rtts: + stats += f"最小延迟: {min(self.rtts)} ms,最大延迟: {max(self.rtts)} ms,平均延迟: {sum(self.rtts)/len(self.rtts):.2f} ms\n" + self.result_box.insert(tk.END, stats) + self.result_box.see(tk.END) + diff --git a/core/__init__.py b/core/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/core/__pycache__/__init__.cpython-313.pyc b/core/__pycache__/__init__.cpython-313.pyc new file mode 100644 index 0000000..45aff71 Binary files /dev/null and b/core/__pycache__/__init__.cpython-313.pyc differ diff --git a/core/__pycache__/csv_manager.cpython-313.pyc b/core/__pycache__/csv_manager.cpython-313.pyc new file mode 100644 index 0000000..70d1f74 Binary files /dev/null and b/core/__pycache__/csv_manager.cpython-313.pyc differ diff --git a/core/__pycache__/logger_config.cpython-313.pyc b/core/__pycache__/logger_config.cpython-313.pyc new file mode 100644 index 0000000..6276e03 Binary files /dev/null and b/core/__pycache__/logger_config.cpython-313.pyc differ diff --git a/core/__pycache__/template_manager.cpython-313.pyc b/core/__pycache__/template_manager.cpython-313.pyc new file mode 100644 index 0000000..51a91c1 Binary files /dev/null and b/core/__pycache__/template_manager.cpython-313.pyc differ 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 0000000..1d52f90 Binary files /dev/null and b/core/ui/__pycache__/__init__.cpython-313.pyc differ diff --git a/core/ui/__pycache__/basic_ui.cpython-313.pyc b/core/ui/__pycache__/basic_ui.cpython-313.pyc new file mode 100644 index 0000000..c579c2b Binary files /dev/null and b/core/ui/__pycache__/basic_ui.cpython-313.pyc differ diff --git a/core/ui/__pycache__/tab_ping.cpython-313.pyc b/core/ui/__pycache__/tab_ping.cpython-313.pyc new file mode 100644 index 0000000..92527ef Binary files /dev/null and b/core/ui/__pycache__/tab_ping.cpython-313.pyc differ 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 0000000..ed6c542 Binary files /dev/null and b/core/ui/__pycache__/ui_main.cpython-313.pyc differ diff --git a/core/ui/basic_ui.py b/core/ui/basic_ui.py new file mode 100644 index 0000000..20b8c89 --- /dev/null +++ b/core/ui/basic_ui.py @@ -0,0 +1,112 @@ +import os +import tkinter as tk +from tkinter import ttk, filedialog, messagebox + +import logging +logger = logging.getLogger(__name__) + +class BasicUI: + + 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 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()