├── requirements.txt ├── logo.ico ├── __pycache__ ├── func.cpython-310.pyc └── tools_dict.cpython-310.pyc ├── startGui.bat ├── startGui.vbs ├── 使用说明.txt ├── 工具推荐归类参考.txt ├── config ├── startCommand.ini └── config.ini ├── tools_dict.py ├── README.MD └── gui.py /requirements.txt: -------------------------------------------------------------------------------- 1 | ttkbootstrap==1.7.4 2 | -------------------------------------------------------------------------------- /logo.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyB-or/FreeGui/HEAD/logo.ico -------------------------------------------------------------------------------- /__pycache__/func.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyB-or/FreeGui/HEAD/__pycache__/func.cpython-310.pyc -------------------------------------------------------------------------------- /__pycache__/tools_dict.cpython-310.pyc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/tyB-or/FreeGui/HEAD/__pycache__/tools_dict.cpython-310.pyc -------------------------------------------------------------------------------- /startGui.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | if "%1"=="h" goto begin 3 | start mshta vbscript:createobject("wscript.shell").run("""%~nx0"" h",0)(window.close)&&exit 4 | :begin 5 | 6 | python gui.py -------------------------------------------------------------------------------- /startGui.vbs: -------------------------------------------------------------------------------- 1 | set ws=WScript.CreateObject("WScript.Shell") 2 | currentpath = createobject("Scripting.FileSystemObject").GetFolder(".").Path 3 | GUI_Tools = currentpath & "\startGui.bat" 4 | ws.Run GUI_Tools,0 -------------------------------------------------------------------------------- /使用说明.txt: -------------------------------------------------------------------------------- 1 | 工具按钮:鼠标左键查看,右键运行,左键双击打开目录,等同右边笔记上面的按钮。 2 | 3 | 配置文件控制大小,布局,颜色等样式 4 | 5 | 启动命令配置文件配置一键启动的命令,没有就默认进入对应的cmd界面 6 | 7 | 工具框架中上面的是菜单切换 8 | 9 | ============================== 10 | 不想python gui.py运行可以写bat隐藏cmd运行,或者写vbs脚本运行 11 | 12 | 或者找工具把bat转成exe,再复制到桌面。(推荐,工具可百度) 13 | 14 | (python打包有点问题,可以自行研究) 15 | 16 | python3.7有问题,请使用高版本(我的环境是py3.10) 17 | 18 | -------------------------------------------------------------------------------- /工具推荐归类参考.txt: -------------------------------------------------------------------------------- 1 | All-Defense-Tool:【]2.4k stars】 2 | 3 | 本项目集成了全网优秀的开源攻防武器项目,包含信息收集工具(自动化利用工具、资产发现工具、目录扫描工具、子域名收集工具、指纹识别工具、端口扫描工具、各种插件....etc...),漏洞利用工具(各大CMS利用工具、中间件利用工具等项目........),内网渗透工具(隧道代理、密码提取.....)、应急响应工具、甲方运维工具、等其他安全攻防资料整理,供攻防双方使用。 4 | 5 | 本项目集成了全网优秀的攻防武器工具项目,包含自动化利用,子域名、目录扫描、端口扫描等信息收集工具,各大中间件、cms漏洞利用工具,爆破工具、内网横向及免杀、社工钓鱼以及应急响应等资料。 6 | 7 | https://github.com/guchangan1/All-Defense-Tool 8 | 9 | 10 | ==================================== 11 | [~]#棱角 » 工具中心--- 工具也很多,也有很多好的开源项目 12 | 13 | https://forum.ywhack.com/center.php -------------------------------------------------------------------------------- /config/startCommand.ini: -------------------------------------------------------------------------------- 1 | #添加参考: 2 | #[webfinder-3.2] 这个是工具的目录 3 | #command = java -jar webfinder-3.2.jar 这个是在工具当前目录下的启动工具的命令,不需要加引号。 4 | #type = powershell 【可选】 5 | # 6 | # 7 | #常见问题: 8 | #1.工具的名称填写不规范,会默认进入工具的cmd界面 9 | #2.双击启动没有反应,启动命令填写错误,可以用python gui.py,在控制台查看报错信息 10 | # 11 | #启动命令:start xx.exe java -jar xx.jar 12 | 13 | 14 | # =========================英文路径工具========================= 15 | [0-GUI_Tools] 16 | command = start start.vbs 17 | 18 | [bp_22.9] 19 | command = start cn_start-burp.bat 20 | 21 | #可web 22 | [msf_pro_4.21] 23 | command = start console.bat 24 | 25 | [cs4.5] 26 | command = start cobaltstrike.exe 27 | # =========================信息收集========================= 28 | [小米范] 29 | command = java -jar webfinder-3.2.jar 30 | 31 | [fofaViewer] 32 | command = java -jar fofaViewer.jar 33 | 34 | # =========================扫描评估========================= 35 | [2-goby-redteam--有问题] 36 | command = start ./goby/Goby.exe 37 | -------------------------------------------------------------------------------- /tools_dict.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/python3 2 | # coding=utf-8 3 | 4 | import os 5 | import configparser 6 | import json 7 | 8 | styleIniPath = os.path.dirname(os.path.abspath(__file__)) 9 | styleIniPath = f"{styleIniPath}\config\config.ini" 10 | 11 | conf_style = configparser.ConfigParser() 12 | conf_style.read(filenames=styleIniPath, encoding="utf-8") 13 | 14 | funlist = conf_style.get("tool", "funList") 15 | funlist = json.loads(funlist) 16 | 17 | 18 | def tools_root_path(): 19 | rootPath = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) 20 | return rootPath 21 | 22 | 23 | def toolsDir(type_mark=funlist[0][1]): 24 | tools_dict = {} 25 | tool_type_root_dir = tools_root_path() 26 | tool_type_dir = sorted([ 27 | i for i in os.listdir(tool_type_root_dir) 28 | if (os.path.isdir(f"{tool_type_root_dir}\{i}") 29 | and i.count(type_mark) == 1) 30 | ]) 31 | 32 | for toolType in tool_type_dir: 33 | tools = sorted([ 34 | i for i in os.listdir(f'{tool_type_root_dir}\{toolType}') 35 | if os.path.isdir(f'{tool_type_root_dir}\{toolType}\{i}') 36 | ]) 37 | tools_dict[toolType] = tools 38 | return tools_dict 39 | 40 | 41 | if __name__ == '__main__': 42 | print(toolsDir()) 43 | -------------------------------------------------------------------------------- /config/config.ini: -------------------------------------------------------------------------------- 1 | # 20230111 2 | #bytyb-or 3 | #python3.10#3.7有问题,建议使用3.10版本 4 | #样式参考:https://ttkbootstrap.readthedocs.io/en/latest/zh/ 5 | 6 | #""" 7 | #修改外观,样式 8 | #配置文件分为app(全局)app-左(工具)app-右(笔记)3大区域 9 | #""" 10 | 11 | #===================================工具相关参数===================================== 12 | 13 | [app] 14 | title=渗透测试工具箱 15 | #工具的标题 16 | theme=darkly 17 | #工具主题样式,参考:litera,darkly,lumen,sandstone,yeti,united,morph,journal,superhero,solar,simplex,cerculean 18 | 19 | size_w=2550 20 | #工具大小--宽 21 | size_h=1550 22 | #工具大小--高 23 | 24 | average = 5 25 | #工具等分为多少份 26 | tool_aver = 3 27 | #工具框架占比3份,说明,工具框架的宽度占比总宽的3/5 28 | note_aver = 2 29 | #工具框架占比3份,占比总宽的2/5 30 | 31 | 32 | txt_mark=00.txt 33 | #笔记标识,每个工具的txt备忘。不建议修改。00可以保证排序比较前。 34 | 35 | #============================tool框架相关参数-左边==================================== 36 | 37 | [tool] 38 | title=工具导航-ToolsGui 39 | #工具框架的标题 40 | theme=primary 41 | #Labelframe控件bootstyle,影响边框颜色参考:default,primary,success,info,warning,danger 42 | scrolled=round 43 | #滚动条样式:圆【加-round】和方形,方形参考:default,primary,secondary,success,info,warning,danger,light,dark,圆角举例:danger-round,默认圆角就是round 44 | 45 | toolColumn=6 46 | #多少列,工具框架中多少列,可修改 47 | columnWidth=20 48 | #列宽--自己设置,分辨率会影响,所以需要自己调试 49 | 50 | #注意:这里的后面的标识也是目录识别的特征,可以自己设置,根据不同的标识区分不同类别,实现功能菜单的切换 51 | #同步toolColumn参数,如果设置7列,列表中必须7个元素,如果分类不多,就用["预留X","自己设定标志识别符"]占位。 52 | funList=[["测试工具","--"],["学习笔记","~~"],["测试专项","__"],["预留1","自己设定标志识别符"],["预留2","自己设定标志识别符"],["预留3","自己设定标志识别符"]] 53 | 54 | 55 | funBtnBootstyle=success 56 | #工具框架中的菜单切换按钮的样式,Bootstyle:default,primary,secondary,success,info,warning,danger,light,dark 57 | funBtnBootstyle_click=warning 58 | 59 | typeBtnBootstyle=info 60 | #工具类别按钮的样式,Bootstyle:Bootstyle:default,primary,secondary,success,info,warning,danger,light,dark 61 | toolBtnBootstyle=info-link 62 | #工具按钮的样式,Bootstyle:success-linkdanger-link(参考上面的加-link) 63 | 64 | 65 | #==================================note框架相关参数-右边=============================== 66 | 67 | [note] 68 | title=Note 69 | #笔记框架的标题 70 | theme=PRIMARY 71 | ##笔记框架样式,Labelframe控件bootstyle,影响边框颜色参考:default,primary,success,info,warning,danger 72 | theme_up = default 73 | #笔记框架功能框架样式,Labelframe控件bootstyle,影响边框颜色参考:default,primary,success,info,warning,danger 74 | 75 | funBtnBootstyle=warning 76 | #笔记框架中上面的按钮的样式,Bootstyle:Bootstyle:default,primary,secondary,success,info,warning,danger,light,dark 77 | 78 | startComBtnBootstyle_open=info 79 | #启动命令修改按钮样式的单独设置,参考Bootstyle 80 | startComBtnBootstyle_save=danger 81 | #启动命令按钮样式的单独设置,参考Bootstyle 82 | 83 | styleBtnBootstyle_open=info 84 | #样式修改按钮样式的单独设置,参考Bootstyle 85 | styleBtnBootstyle_save=danger 86 | #样式保存按钮样式的单独设置,参考Bootstyle 87 | 88 | txt_title=--Content-- 89 | #txt笔记的文本提示信息,LabelFrame,后续会随点击的工具不同,变成对应的路径信息 90 | 91 | noteFrameDownStyle=success 92 | #笔记框架文本框架样式,Style 笔记框架中分上下,上-功能,下-txt笔记, 93 | scrolledTextBootstyle=success-round 94 | #txt笔记的滚动条样式,#滚动条样式:圆【加-round】和方形,方形参考:Bootstyle:default,primary,secondary,success,info,warning,danger,light,dark,圆角举例:danger-round,默认圆角就是round 95 | -------------------------------------------------------------------------------- /README.MD: -------------------------------------------------------------------------------- 1 | # 工具介绍 2 | 3 | freeGui:基于ttkbootstrap开发的一款用来管理自己的渗透测试工具的一个小工具,并提供一些实用小功能,例如打开目录,运行工具,工具备忘命令。 4 | 5 | # 开发目的 6 | 7 | 总结:工具整理+效率提升 8 | 9 | 1.工具太多,杂乱,用这个可以帮忙分类工具 10 | 11 | 2.一些不常用的工具需要使用时可能需要重新查资料,这个可以记录一些备忘(txt笔记)方便快速查询 12 | 13 | 3.有的工具使用需要修改配置文件,使用这个可以一键直达工具目录 14 | 15 | 4.工具快捷启动,添加启动命令以后可以直接启动工具 16 | 17 | 5.自由删减工具,用过一些集成工具,虽然开箱即用,但是自由度不高。这个可以帮助自己构建属于自己的工具箱。 18 | 19 | 6.工具外观自由,工具内部提供高度自由化的配置,可以在工具内部按照自己的喜好修改样式。 20 | 21 | # 工具使用: 22 | 23 | 注意:请使用python3.10及以上版本,低版本可能会出现异常。 24 | 25 | ## 1.安装模块: 26 | 27 | ``` 28 | pip install -r requirements.txt 29 | ``` 30 | 31 | ## 2.启动方式: 32 | 33 | ``` 34 | 1.控制台模式:(查看调试信息) 35 | python gui.py 36 | 37 | 2.bat启动 38 | startGui.bat (已经设置隐藏启动) 39 | 40 | 3.exe文件: 41 | --(这里可以使用python打包成exe,但是我没有弄,你自己可以本地尝试下) 42 | 使用其他工具把bat转成exe(推荐) 43 | Quick Batch File Compiler【可以设置图标】 44 | ``` 45 | 46 | ## 3.功能介绍: 47 | 48 | a.工具按钮:鼠标左键单击查看,右键单击运行,左键双击打开对应的目录,等同右边笔记上面的按钮。 49 | 50 | b.配置文件可以控制软件大小,布局,按钮颜色等样式。请自行研究(样式修改按钮) 51 | 52 | c.命令配置文件配置一键启动命令,没有就默认进入对应的cmd界面 53 | 54 | d.工具框架中上面的是菜单切换,点击可以切换。 55 | 56 | e.自由添加工具分类和工具:类别目录添加时需要带标识:--,类别目录下可自由添加工具,目录名字不宜太长。(请阅读配置文件修改) 57 | 58 | (工具汇总:链接:https://pan.baidu.com/s/19qQHDk49NTUKfq3jXAnB2A?pwd=wby8 提取码:wby8 ) 59 | 工具展示图: 60 | ![image](https://user-images.githubusercontent.com/38561404/212345858-ca79d9d3-6581-4979-83a9-9af9dc3ba219.png) 61 | 目录结构图: 62 | 请仔细阅读配置文件,在设置类别目录时请带标识。 63 | ![image](https://user-images.githubusercontent.com/38561404/212346586-bdad75e9-9626-464c-9376-a343a2f02e05.png) 64 | 65 | 66 | # 配置文件说明: 67 | 68 | 样式配置文件:app样式,工具框样式,笔记框样式 69 | 70 | \config\\config.ini 71 | 72 | ``` 73 | #20230111 74 | #bytyb-or 75 | #python3.10#3.7有问题,建议使用3.10版本 76 | #样式参考:https://ttkbootstrap.readthedocs.io/en/latest/zh/ 77 | 78 | #""" 79 | #修改外观,样式 80 | #配置文件分为app(全局)app-左(工具)app-右(笔记)3大区域 81 | #""" 82 | 83 | #===================================工具相关参数===================================== 84 | 85 | [app] 86 | title=渗透测试工具箱 87 | #工具的标题 88 | theme=darkly 89 | #工具主题样式,参考:litera,darkly,lumen,sandstone,yeti,united,morph,journal,superhero,solar,simplex,cerculean 90 | 91 | size_w=2550 92 | #工具大小--宽 93 | size_h=1550 94 | #工具大小--高 95 | 96 | average = 5 97 | #工具等分为多少份 98 | tool_aver = 3 99 | #工具框架占比3份,说明,工具框架的宽度占比总宽的3/5 100 | note_aver = 2 101 | #工具框架占比3份,占比总宽的2/5 102 | 103 | 104 | txt_mark=00.txt 105 | #笔记标识,每个工具的txt备忘。不建议修改。00可以保证排序比较前。 106 | 107 | #============================tool框架相关参数-左边==================================== 108 | 109 | [tool] 110 | title=工具导航-ToolsGui 111 | #工具框架的标题 112 | theme=primary 113 | #Labelframe控件bootstyle,影响边框颜色参考:default,primary,success,info,warning,danger 114 | scrolled=round 115 | #滚动条样式:圆【加-round】和方形,方形参考:default,primary,secondary,success,info,warning,danger,light,dark,圆角举例:danger-round,默认圆角就是round 116 | 117 | toolColumn=6 118 | #多少列,工具框架中多少列,可修改 119 | columnWidth=20 120 | #列宽--自己设置,分辨率会影响,所以需要自己调试 121 | 122 | #注意:这里的后面的标识也是目录识别的特征,可以自己设置,根据不同的标识区分不同类别,实现功能菜单的切换 123 | #同步toolColumn参数,如果设置7列,列表中必须7个元素,如果分类不多,就用["预留X","自己设定标志识别符"]占位。 124 | funList=[["测试工具","--"],["红蓝对抗","~~"],["学习笔记","__"],["预留1","自己设定标志识别符"],["预留2","自己设定标志识别符"],["预留3","自己设定标志识别符"]] 125 | 126 | funBtnBootstyle=success 127 | #工具框架中的菜单切换按钮的样式,Bootstyle:default,primary,secondary,success,info,warning,danger,light,dark 128 | typeBtnBootstyle=info 129 | #工具类别按钮的样式,Bootstyle:Bootstyle:default,primary,secondary,success,info,warning,danger,light,dark 130 | toolBtnBootstyle=info-link 131 | #工具按钮的样式,Bootstyle:success-linkdanger-link(参考上面的加-link) 132 | 133 | 134 | #==================================note框架相关参数-右边=============================== 135 | 136 | [note] 137 | title=Note 138 | #笔记框架的标题 139 | theme=PRIMARY 140 | #笔记框架样式,Labelframe控件bootstyle,影响边框颜色参考:default,primary,success,info,warning,danger 141 | theme_up = default 142 | #笔记框架功能框架样式,Labelframe控件bootstyle,影响边框颜色参考:default,primary,success,info,warning,danger 143 | 144 | funBtnBootstyle=warning 145 | #笔记框架中上面的按钮的样式,Bootstyle:Bootstyle:default,primary,secondary,success,info,warning,danger,light,dark 146 | 147 | startComBtnBootstyle_open=info 148 | #启动命令修改按钮样式的单独设置,参考Bootstyle 149 | startComBtnBootstyle_save=danger 150 | #启动命令按钮样式的单独设置,参考Bootstyle 151 | 152 | styleBtnBootstyle_open=info 153 | #样式修改按钮样式的单独设置,参考Bootstyle 154 | styleBtnBootstyle_save=danger 155 | #样式保存按钮样式的单独设置,参考Bootstyle 156 | 157 | txt_title=--Content-- 158 | #txt笔记的文本提示信息,LabelFrame,后续会随点击的工具不同,变成对应的路径信息 159 | 160 | noteFrameDownStyle=success 161 | #笔记框架文本框架样式,Style 笔记框架中分上下,上-功能,下-txt笔记, 162 | scrolledTextBootstyle=success-round 163 | #txt笔记的滚动条样式,#滚动条样式:圆【加-round】和方形,方形参考:Bootstyle:default,primary,secondary,success,info,warning,danger,light,dark,圆角举例:danger-round,默认圆角就是round 164 | 165 | 166 | ``` 167 | 168 | 启动命令配置文件: 169 | 170 | \config\\startCommand.ini 171 | 172 | ``` 173 | #添加参考: 174 | #[webfinder-3.2] 这个是工具的目录 175 | #command = java -jar webfinder-3.2.jar 这个是在工具当前目录下的启动工具的命令,不需要加引号。 176 | #type = powershell 【可选】,若添加此参数,会调用powershell 177 | # 178 | #常见问题: 179 | #1.工具的名称填写不规范,会默认进入工具的cmd界面 180 | #2.双击启动没有反应,启动命令填写错误,可以用python gui.py,在控制台查看报错信息 181 | # 182 | #启动命令参考:start xx.exe java -jar xx.jar 183 | 184 | 185 | # =========================英文路径工具========================= 186 | [0-GUI_Tools] 187 | command = start start.vbs 188 | ``` 189 | 190 | 191 | 192 | # 免责声明 193 | 194 | ``` 195 | 本工具仅面向合法授权的企业安全建设行为,在使用本工具进行检测时,您应确保该行为符合当地的法律法规,并且已经取得了足够的授权。 196 | 197 | 如您在使用本工具的过程中存在任何非法行为,您需自行承担相应后果,我们将不承担任何法律及连带责任。 198 | 199 | 在使用本工具前,请您务必审慎阅读、充分理解各条款内容,限制、免责条款或者其他涉及您重大权益的条款可能会以加粗、加下划线等形式提示您重点注意。 除非您已充分阅读、完全理解并接受本协议所有条款,否则,请您不要使用本工具。 200 | 201 | 您的使用行为或者您以其他任何明示或者默示方式表示接受本协议的,即视为您已阅读并同意本协议的约束。 202 | ``` 203 | 204 | -------------------------------------------------------------------------------- /gui.py: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | import ttkbootstrap as ttk 5 | from ttkbootstrap.constants import * 6 | from ttkbootstrap.scrolled import ScrolledText, ScrolledFrame 7 | from ttkbootstrap.dialogs.dialogs import Messagebox 8 | import subprocess 9 | import configparser 10 | import json 11 | 12 | import os 13 | import datetime 14 | 15 | import tools_dict 16 | 17 | 18 | class APP(ttk.Frame): 19 | 20 | def __init__(self, master=None): 21 | super().__init__(master) 22 | self.master = master 23 | self.pack() 24 | 25 | self.rootPath = tools_dict.tools_root_path() 26 | print(f"调试信息: 1.工具的类别目录是:\n{self.rootPath}\n") 27 | self.toolsDic = tools_dict.toolsDir() 28 | 29 | self.config_ini_path1 = os.path.dirname(os.path.abspath(__file__)) 30 | self.config_ini_path = f"{self.config_ini_path1}\config\config.ini" 31 | print(f"调试信息: 2.config.ini文件路径是: \n{self.config_ini_path}\n") 32 | 33 | self.config_style = configparser.ConfigParser() 34 | self.config_style.read(filenames=self.config_ini_path, 35 | encoding="utf-8") 36 | 37 | self.app_size_w = int(self.config_style["app"]["size_w"]) 38 | self.app_size_h = int(self.config_style["app"]["size_h"]) 39 | self.average = int(self.config_style["app"]["average"]) 40 | self.tool_aver = int(self.config_style["app"]["tool_aver"]) 41 | self.note_aver = int(self.config_style["app"]["note_aver"]) 42 | 43 | print( 44 | f"调试信息: 3.工具框架的宽是:\n{int(self.app_size_w/self.average*self.tool_aver)}\n" 45 | ) 46 | print( 47 | f"调试信息: 4.笔记框架的宽是:\n{int(self.app_size_w/self.average*self.note_aver)}\n" 48 | ) 49 | 50 | self.toolFra = ttk.LabelFrame( 51 | self, 52 | text=self.config_style["tool"]["title"], 53 | bootstyle=self.config_style["tool"]["theme"], 54 | width=int(self.app_size_w / self.average * self.tool_aver), 55 | height=self.app_size_h, 56 | labelanchor=NW, 57 | padding=7, 58 | border=10) 59 | self.toolFra.pack(side="left", 60 | fill=BOTH, 61 | ipadx=7, 62 | ipady=10, 63 | padx=10, 64 | pady=20) 65 | self.toolFrame = ScrolledFrame( 66 | self.toolFra, 67 | autohide=True, 68 | width=int(self.app_size_w / self.average * self.tool_aver), 69 | height=self.app_size_h + 500, 70 | bootstyle=self.config_style["tool"]["scrolled"]) 71 | self.toolFrame.pack(fill=BOTH, anchor=NW) 72 | 73 | self.noteFrame = ttk.LabelFrame( 74 | self, 75 | text=self.config_style["note"]["title"], 76 | bootstyle=self.config_style["note"]["theme"], 77 | width=int(self.app_size_w / self.average * self.note_aver), 78 | height=self.app_size_h, 79 | labelanchor=NW, 80 | padding=7, 81 | border=10) 82 | self.noteFrame.pack(side="left", ipadx=7, ipady=10, padx=10, pady=20) 83 | 84 | self.noteFrame_up = ttk.Frame( 85 | self.noteFrame, bootstyle=self.config_style["note"]["theme_up"]) 86 | self.noteFrame_up.pack(side="top", fill="x", ipadx=7, ipady=10) 87 | 88 | self.noteFrameTxtSaveBtn = ttk.Button( 89 | self.noteFrame_up, 90 | text=" 保存笔记 ", 91 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 92 | self.noteFrameTxtSaveBtn.pack(anchor=W, 93 | padx=2, 94 | pady=2, 95 | ipadx=10, 96 | side="left", 97 | ipady=10) 98 | 99 | self.noteFrameStartBtn = ttk.Button( 100 | self.noteFrame_up, 101 | text=" 打开目录 ", 102 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 103 | self.noteFrameStartBtn.pack(anchor=W, 104 | side="left", 105 | padx=2, 106 | pady=2, 107 | ipadx=10, 108 | ipady=10) 109 | 110 | self.noteFrameRefreshBtn = ttk.Button( 111 | self.noteFrame_up, 112 | text=" 刷新GUI ", 113 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 114 | self.noteFrameRefreshBtn.pack(anchor=W, 115 | side="left", 116 | padx=2, 117 | pady=2, 118 | ipadx=10, 119 | ipady=10) 120 | self.noteFrameRefreshBtn["command"] = self.refresh 121 | 122 | self.noteFrameOpenDirBtn = ttk.Button( 123 | self.noteFrame_up, 124 | text=" 启动工具 ", 125 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 126 | self.noteFrameOpenDirBtn.pack(anchor=W, 127 | side="left", 128 | padx=2, 129 | pady=2, 130 | ipadx=10, 131 | ipady=10) 132 | 133 | self.noteFrameCommandBtn = ttk.Button( 134 | self.noteFrame_up, 135 | text=" 编辑启动命令 ", 136 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 137 | self.noteFrameCommandBtn.pack(anchor=W, 138 | side="left", 139 | padx=2, 140 | pady=2, 141 | ipadx=10, 142 | ipady=10) 143 | self.noteFrameCommandBtn[COMMAND] = self.openStartCommandIniFile 144 | 145 | self.noteFrameStyleBtn = ttk.Button( 146 | self.noteFrame_up, 147 | text=" 样式修改 ", 148 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 149 | self.noteFrameStyleBtn.pack(anchor=W, 150 | side="right", 151 | padx=2, 152 | pady=2, 153 | ipadx=10, 154 | ipady=10) 155 | self.noteFrameStyleBtn[COMMAND] = self.openStyleIniFile 156 | 157 | self.noteFrame_down = ttk.LabelFrame( 158 | self.noteFrame, 159 | text=self.config_style["note"]["txt_title"], 160 | style=self.config_style["note"]["noteFrameDownStyle"], 161 | padding=5) 162 | self.noteFrame_down.pack(fill=BOTH, padx=3, pady=3) 163 | 164 | self.txtCount = ScrolledText( 165 | self.noteFrame_down, 166 | width=int(self.app_size_w / self.average * self.note_aver), 167 | height=self.app_size_h, 168 | bootstyle=self.config_style["note"]["scrolledTextBootstyle"], 169 | autohide=True) 170 | self.txtCount.pack(fill=BOTH, side=BOTTOM, anchor=NW) 171 | 172 | self.toolFrameFun() 173 | 174 | def toolFrameFun(self): 175 | print("调试信息: 5.应用总宽-工具宽-笔记宽-工具列宽: \n ", self.app_size_w, 176 | int(self.app_size_w / self.average * self.tool_aver), 177 | int(self.app_size_w / self.average * self.note_aver), 178 | self.config_style["tool"]["columnWidth"]) 179 | print() 180 | print("调试信息: 6.应用总高-工具高-笔记高: \n", self.app_size_h, self.app_size_h, 181 | self.app_size_h) 182 | print() 183 | print(f'调试信息: 7.工具列数:\n{self.config_style["tool"]["toolColumn"]}\n') 184 | print(f'调试信息: 8.工具列宽:\n{self.config_style["tool"]["columnWidth"]}\n') 185 | 186 | toolFunlist = self.config_style.get("tool", "funList") 187 | toolFunlist = json.loads(toolFunlist) 188 | 189 | for i in range(int(self.config_style["tool"]["toolColumn"])): 190 | self.Btnfr1 = ttk.Button( 191 | self.toolFrame, 192 | text=toolFunlist[i][0], 193 | width=self.config_style["tool"]["columnWidth"], 194 | bootstyle=self.config_style["tool"]["funBtnBootstyle"], 195 | command=lambda arg=toolFunlist[i][1]: self.toolFunBtn( 196 | arg)).grid(pady=2, row=0, column=i) 197 | r = 1 198 | 199 | for k in self.toolsDic.keys(): 200 | self.btnToolType = ttk.Button( 201 | self.toolFrame, 202 | text=k, 203 | bootstyle=self.config_style["tool"]["typeBtnBootstyle"], 204 | command=lambda a=k: 205 | [self.openToolTypeNote(a), 206 | self.toolTypeTitle(a)]) 207 | self.btnToolType.grid(row=r, 208 | column=0, 209 | columnspan=int( 210 | self.config_style["tool"]["toolColumn"]), 211 | sticky=W) 212 | 213 | self.btnToolType.bind("", 214 | lambda event, arg0=k: self.openTypeDir(arg0)) 215 | 216 | r += 1 217 | c = 0 218 | 219 | for i in self.toolsDic[k]: 220 | if c == int(self.config_style["tool"]["toolColumn"]): 221 | r += 1 222 | c = 0 223 | self.btnTools = ttk.Button( 224 | self.toolFrame, 225 | bootstyle=self.config_style["tool"]["toolBtnBootstyle"], 226 | text=i, 227 | command=lambda a=k, b=i: 228 | [self.openToolNote(a, b), 229 | self.toolTitle(a, b)]) 230 | 231 | self.btnTools.grid(row=r, column=c, sticky=N + S + W, pady=2) 232 | 233 | self.btnTools.bind( 234 | "", 235 | lambda event, arg1=k, arg2=i: self.openToolDir(arg1, arg2)) 236 | 237 | self.btnTools.bind( 238 | "", 239 | lambda event, arg1=k, arg2=i: self.openToolCmd(arg1, arg2)) 240 | 241 | c += 1 242 | r += 1 243 | 244 | def toolTypeTitle(self, typedir): 245 | 246 | for widget in self.noteFrame_up.winfo_children(): 247 | widget.destroy() 248 | 249 | self.noteFrameTxtSaveBtn = ttk.Button( 250 | self.noteFrame_up, 251 | text=" 保存笔记 ", 252 | bootstyle=self.config_style["note"]["funBtnBootstyle"], 253 | command=lambda a=typedir: self.saveTypeNote(a)) 254 | self.noteFrameTxtSaveBtn.pack(anchor=W, 255 | side="left", 256 | padx=2, 257 | pady=2, 258 | ipadx=10, 259 | ipady=10) 260 | 261 | self.noteFrameStartBtn = ttk.Button( 262 | self.noteFrame_up, 263 | text=" 打开目录 ", 264 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 265 | self.noteFrameStartBtn.pack(anchor=W, 266 | side="left", 267 | padx=2, 268 | pady=2, 269 | ipadx=10, 270 | ipady=10) 271 | self.noteFrameStartBtn[ 272 | COMMAND] = lambda arg0=typedir: self.openTypeDir(arg0) 273 | 274 | self.noteFrameRefreshBtn = ttk.Button( 275 | self.noteFrame_up, 276 | text=" 刷新GUI ", 277 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 278 | self.noteFrameRefreshBtn.pack(anchor=W, 279 | side="left", 280 | padx=2, 281 | pady=2, 282 | ipadx=10, 283 | ipady=10) 284 | self.noteFrameRefreshBtn["command"] = self.refresh 285 | 286 | self.noteFrameOpenDirBtn = ttk.Button( 287 | self.noteFrame_up, 288 | text=" 启动工具 ", 289 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 290 | self.noteFrameOpenDirBtn.pack(anchor=W, 291 | side="left", 292 | padx=2, 293 | pady=2, 294 | ipadx=10, 295 | ipady=10) 296 | 297 | self.noteFrameCommandBtn = ttk.Button( 298 | self.noteFrame_up, 299 | text=" 编辑启动命令 ", 300 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 301 | self.noteFrameCommandBtn.pack(anchor=W, 302 | side="left", 303 | padx=2, 304 | pady=2, 305 | ipadx=10, 306 | ipady=10) 307 | self.noteFrameCommandBtn[COMMAND] = self.openStartCommandIniFile 308 | 309 | self.noteFrameStyleBtn = ttk.Button( 310 | self.noteFrame_up, 311 | text=" 样式修改 ", 312 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 313 | self.noteFrameStyleBtn.pack(anchor=W, 314 | side="right", 315 | padx=2, 316 | pady=2, 317 | ipadx=10, 318 | ipady=10) 319 | self.noteFrameStyleBtn[COMMAND] = self.openStyleIniFile 320 | 321 | def toolTitle(self, typedir, tool): 322 | 323 | for widget in self.noteFrame_up.winfo_children(): 324 | widget.destroy() 325 | 326 | self.noteFrameTxtSaveBtn = ttk.Button( 327 | self.noteFrame_up, 328 | text=" 保存笔记 ", 329 | bootstyle=self.config_style["note"]["funBtnBootstyle"], 330 | command=lambda a=typedir, b=tool: self.saveToolNote(a, b)) 331 | self.noteFrameTxtSaveBtn.pack(anchor=W, 332 | side="left", 333 | padx=2, 334 | pady=2, 335 | ipadx=10, 336 | ipady=10) 337 | 338 | self.noteFrameStartBtn = ttk.Button( 339 | self.noteFrame_up, 340 | text=" 打开目录 ", 341 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 342 | self.noteFrameStartBtn.pack(anchor=W, 343 | side="left", 344 | padx=2, 345 | pady=2, 346 | ipadx=10, 347 | ipady=10) 348 | self.noteFrameStartBtn[ 349 | COMMAND] = lambda arg1=typedir, arg2=tool: self.openToolDir( 350 | arg1, arg2) 351 | 352 | self.noteFrameRefreshBtn = ttk.Button( 353 | self.noteFrame_up, 354 | text=" 刷新GUI ", 355 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 356 | self.noteFrameRefreshBtn.pack(anchor=W, 357 | side="left", 358 | padx=2, 359 | pady=2, 360 | ipadx=10, 361 | ipady=10) 362 | self.noteFrameRefreshBtn["command"] = self.refresh 363 | 364 | self.noteFrameOpenDirBtn = ttk.Button( 365 | self.noteFrame_up, 366 | text=" 启动工具 ", 367 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 368 | self.noteFrameOpenDirBtn.pack(anchor=W, 369 | side="left", 370 | padx=2, 371 | pady=2, 372 | ipadx=10, 373 | ipady=10) 374 | self.noteFrameOpenDirBtn[ 375 | COMMAND] = lambda arg1=typedir, arg2=tool: self.openToolCmd( 376 | arg1, arg2) 377 | 378 | self.noteFrameCommandBtn = ttk.Button( 379 | self.noteFrame_up, 380 | text=" 编辑启动命令 ", 381 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 382 | self.noteFrameCommandBtn.pack(anchor=W, 383 | side="left", 384 | padx=2, 385 | pady=2, 386 | ipadx=10, 387 | ipady=10) 388 | self.noteFrameCommandBtn[COMMAND] = self.openStartCommandIniFile 389 | 390 | self.noteFrameStyleBtn = ttk.Button( 391 | self.noteFrame_up, 392 | text=" 样式修改 ", 393 | bootstyle=self.config_style["note"]["funBtnBootstyle"]) 394 | self.noteFrameStyleBtn.pack(anchor=W, 395 | side="right", 396 | padx=2, 397 | pady=2, 398 | ipadx=10, 399 | ipady=10) 400 | self.noteFrameStyleBtn[COMMAND] = self.openStyleIniFile 401 | 402 | def saveTypeNote(self, typedir): 403 | notePath = f'{self.rootPath}\{typedir}\{self.config_style["app"]["txt_mark"]}' 404 | 405 | content = self.txtCount.get(1.0, END) 406 | with open(notePath, "w", encoding='utf-8') as f: 407 | f.write(content) 408 | 409 | def saveToolNote(self, typedir, tool): 410 | notePath = f'{self.rootPath}\{typedir}\{tool}\{self.config_style["app"]["txt_mark"]}' 411 | 412 | content = self.txtCount.get(1.0, END) 413 | with open(notePath, "w", encoding='utf-8') as f: 414 | f.write(content) 415 | 416 | def openToolNote(self, typedir, tool): 417 | notePath = f'{self.rootPath}\{typedir}\{tool}\{self.config_style["app"]["txt_mark"]}' 418 | 419 | self.noteFrame_down["text"] = f"-- {self.rootPath}\{typedir}\{tool} --" 420 | 421 | if os.path.exists(notePath): 422 | with open(notePath, encoding='utf-8') as f: 423 | self.txtCount.delete('1.0', END) 424 | self.txtCount.insert(END, f.read()) 425 | 426 | else: 427 | Messagebox.ok(message="\n\t你还没有创建笔记,已自动创建初始化信息。\t\n", 428 | title='OpenNote') 429 | infoMsg = f"-----你还没有创建笔记-----{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}-----" 430 | self.txtCount.delete('1.0', END) 431 | self.txtCount.insert(END, infoMsg) 432 | f = open(notePath, "w", encoding='utf-8') 433 | f.writelines(infoMsg) 434 | f.close() 435 | 436 | def openToolTypeNote(self, typedir): 437 | notePath = f'{self.rootPath}\{typedir}\{self.config_style["app"]["txt_mark"]}' 438 | 439 | self.noteFrame_down["text"] = f"-- {self.rootPath}\{typedir} --" 440 | 441 | if os.path.exists(notePath): 442 | with open(notePath, encoding='utf-8') as f: 443 | self.txtCount.delete('1.0', END) 444 | self.txtCount.insert(END, f.read()) 445 | 446 | else: 447 | Messagebox.ok(message="\n\t你还没有创建笔记,已自动创建初始化信息。\t\n", 448 | title='OpenNote') 449 | infoMsg = f"-----你还没有创建笔记-----{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}-----" 450 | self.txtCount.delete('1.0', END) 451 | self.txtCount.insert(END, infoMsg) 452 | f = open(notePath, "w", encoding='utf-8') 453 | f.writelines(infoMsg) 454 | f.close() 455 | 456 | def openTypeDir(self, typedir): 457 | os.startfile(f'{self.rootPath}\{typedir}') 458 | 459 | def openToolDir(self, typedir, tool): 460 | os.startfile(f'{self.rootPath}\{typedir}\{tool}') 461 | 462 | def openToolCmd(self, typedir, tool): 463 | os.chdir(f"{self.rootPath}\{typedir}\{tool}") 464 | 465 | iniPath = os.path.dirname(os.path.abspath(__file__)) 466 | 467 | iniPath = f"{iniPath}\config\startCommand.ini" 468 | conf = configparser.ConfigParser() 469 | conf.read(filenames=iniPath, encoding="utf-8") 470 | 471 | if tool in conf.sections(): 472 | 473 | if "type" in conf.options(tool): 474 | print(conf.get(tool, "type")) 475 | 476 | if "command" in conf.options(tool): 477 | print(conf.get(tool, "command")) 478 | startCommand = conf.get(tool, "command") 479 | subprocess.Popen( 480 | f'start powershell -NoExit "{startCommand}"', 481 | shell=True) 482 | else: 483 | subprocess.Popen(f'start powershell -NoExit ', shell=True) 484 | else: 485 | startCommand = conf.get(tool, "command") 486 | subprocess.Popen(f'{startCommand}', shell=True) 487 | else: 488 | 489 | subprocess.Popen(f'start cmd /k "title {tool}"', shell=True) 490 | os.chdir(self.rootPath) 491 | print(typedir, tool) 492 | 493 | def openStartCommandIniFile(self): 494 | path = os.path.dirname(os.path.abspath(__file__)) 495 | 496 | path = f"{path}\config\startCommand.ini" 497 | print(path) 498 | global afterTxt 499 | afterTxt = self.txtCount.get(1.0, END) 500 | with open(path, encoding='utf-8') as f: 501 | self.txtCount.delete('1.0', END) 502 | self.txtCount.insert(END, f.read()) 503 | print(f.read()) 504 | self.noteFrameCommandBtn.pack_forget() 505 | self.noteFrameTxtSaveBtn['state'] = DISABLED 506 | self.noteFrameStyleBtn['state'] = DISABLED 507 | self.saveBtn = ttk.Button( 508 | self.noteFrame_up, 509 | text="保存启动命令", 510 | bootstyle=self.config_style["note"]["startComBtnBootstyle_save"]) 511 | self.saveBtn.pack(anchor=W, 512 | side="left", 513 | padx=2, 514 | pady=2, 515 | ipadx=10, 516 | ipady=10) 517 | self.saveBtn[COMMAND] = self.saveStartCommandIniFile 518 | 519 | def saveStartCommandIniFile(self): 520 | path = os.path.dirname(os.path.abspath(__file__)) 521 | 522 | path = f"{path}\config\startCommand.ini" 523 | print(path) 524 | command_ini_data = self.txtCount.get(1.0, END) 525 | print(type(command_ini_data)) 526 | self.saveBtn.pack_forget() 527 | self.noteFrameCommandBtn.pack(anchor=W, 528 | side="left", 529 | padx=2, 530 | pady=2, 531 | ipadx=10, 532 | ipady=10) 533 | with open(path, "w", encoding='utf-8') as f: 534 | f.write(command_ini_data) 535 | 536 | self.txtCount.delete('1.0', END) 537 | self.txtCount.insert(END, afterTxt) 538 | self.noteFrameTxtSaveBtn['state'] = NORMAL 539 | self.noteFrameStyleBtn['state'] = NORMAL 540 | 541 | def openStyleIniFile(self): 542 | path = os.path.dirname(os.path.abspath(__file__)) 543 | 544 | path = f"{path}\config\config.ini" 545 | 546 | global afterTxt2 547 | afterTxt2 = self.txtCount.get(1.0, END) 548 | with open(path, encoding='utf-8') as f: 549 | self.txtCount.delete('1.0', END) 550 | self.txtCount.insert(END, f.read()) 551 | 552 | self.noteFrameStyleBtn.pack_forget() 553 | self.noteFrameTxtSaveBtn['state'] = DISABLED 554 | self.noteFrameCommandBtn['state'] = DISABLED 555 | 556 | self.saveBtn = ttk.Button( 557 | self.noteFrame_up, 558 | text="样式保存", 559 | bootstyle=self.config_style["note"]["styleBtnBootstyle_save"]) 560 | self.saveBtn.pack(anchor=W, 561 | side="right", 562 | padx=2, 563 | pady=2, 564 | ipadx=10, 565 | ipady=10) 566 | self.saveBtn[COMMAND] = self.saveStyleIniFile 567 | 568 | def saveStyleIniFile(self): 569 | path = os.path.dirname(os.path.abspath(__file__)) 570 | 571 | path = f"{path}\config\config.ini" 572 | 573 | command_ini_data = self.txtCount.get(1.0, END) 574 | 575 | self.saveBtn.pack_forget() 576 | self.noteFrameStyleBtn.pack(anchor=W, 577 | side="right", 578 | padx=2, 579 | pady=2, 580 | ipadx=10, 581 | ipady=10) 582 | with open(path, "w", encoding='utf-8') as f: 583 | f.write(command_ini_data) 584 | 585 | self.txtCount.delete('1.0', END) 586 | self.txtCount.insert(END, afterTxt2) 587 | self.noteFrameTxtSaveBtn['state'] = NORMAL 588 | self.noteFrameCommandBtn['state'] = NORMAL 589 | 590 | def refresh(self): 591 | self.toolsDic = tools_dict.toolsDir() 592 | 593 | for widget in self.toolFrame.winfo_children(): 594 | widget.destroy() 595 | self.toolFrameFun() 596 | 597 | def toolFunBtn(self, typeMark): 598 | self.toolsDic = tools_dict.toolsDir(typeMark) 599 | 600 | for widget in self.toolFrame.winfo_children(): 601 | widget.destroy() 602 | self.toolFrameFun() 603 | 604 | 605 | styleIniPath = os.path.dirname(os.path.abspath(__file__)) 606 | styleIniPath = f"{styleIniPath}\config\config.ini" 607 | 608 | conf_style = configparser.ConfigParser() 609 | conf_style.read(filenames=styleIniPath, encoding="utf-8") 610 | 611 | root = ttk.Window(title=conf_style["app"]["title"], 612 | themename=str(conf_style["app"]["theme"])) 613 | 614 | screenheight = root.winfo_screenheight() 615 | screenwidth = root.winfo_screenwidth() 616 | print(" 调试信息: 屏幕的-宽-高-是 (in pixels) = \n", (screenwidth, screenheight)) 617 | print() 618 | 619 | 620 | 621 | size_w = conf_style["app"]["size_w"] 622 | size_h = conf_style["app"]["size_h"] 623 | 624 | center_w = int((screenwidth - int(size_w)) / 2) 625 | center_h = int((screenheight - int(size_h)) / 2) 626 | print("调试信息: 工具的位置参数信息:宽-高-左边距-上边距:\n", size_w, size_h, center_w, center_h) 627 | print() 628 | root.geometry(f'{size_w}x{size_h}+{center_w}+{center_h}') 629 | 630 | root.iconbitmap('logo.ico') 631 | app = APP(master=root) 632 | 633 | root.mainloop() 634 | --------------------------------------------------------------------------------