gui.py 6.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  1. import tkinter
  2. from newtkinter import askopenfilename
  3. from tkinter.messagebox import showwarning, askokcancel
  4. from tkinter.scrolledtext import ScrolledText
  5. import webbrowser
  6. from system.controller import Systemctl, NamingError, ConflictError
  7. from system import QueueController
  8. queue_controller = QueueController()
  9. SCREEN = tkinter.Tk()
  10. systemctl = Systemctl()
  11. SCREEN.title("插件管理")
  12. SCREEN.resizable(width=False, height=False)
  13. SCREEN.geometry(f"+10+10")
  14. bg_color = "#FFFAFA" # 主颜色
  15. SCREEN["bg"] = bg_color
  16. botton_color = "#FFFAFA" # 按钮颜色
  17. word_color = "#000000" # 文字颜色
  18. FONT = ("黑体", 11) # 设置字体
  19. gui_width = 13 # 标准宽度
  20. gui_height = 2
  21. row = 0
  22. column = 0
  23. def code_window(name):
  24. global bg_color
  25. cli_screen = tkinter.Toplevel(bg=bg_color)
  26. cli_screen.title(f"插件查看器:{name}")
  27. cli_screen.geometry("+10+10") # 设置所在位置
  28. cli_screen.resizable(width=False, height=False)
  29. class ScrolledCli(ScrolledText):
  30. def __init__(self, *args, **kwargs):
  31. super(ScrolledCli, self).__init__(*args, **kwargs)
  32. def insert(self, index, chars, *args):
  33. text.config(state=tkinter.NORMAL)
  34. super(ScrolledCli, self).insert(index, chars, *args)
  35. text.config(state=tkinter.DISABLED)
  36. def clear(self):
  37. text.config(state=tkinter.NORMAL)
  38. self.delete("0.0", tkinter.END)
  39. text.config(state=tkinter.DISABLED)
  40. text = ScrolledCli(cli_screen, font=("黑体", 11), height=30, width=100)
  41. text.grid(column=0, row=0, columnspan=5, sticky=tkinter.E + tkinter.W)
  42. text.config(state=tkinter.DISABLED)
  43. cli_screen.update()
  44. return text, cli_screen
  45. def get_dir():
  46. plugin_dir_box.delete(0, tkinter.END)
  47. plugin_dir_box.insert(0, *systemctl.get_dir())
  48. def get_all_plugin():
  49. plugin_box.delete(0, tkinter.END)
  50. plugin_box.insert(0, *systemctl.get_all_plugin())
  51. def get_plugin():
  52. try:
  53. index = plugin_dir_box.curselection()[0]
  54. except IndexError:
  55. return False
  56. plugin_box.delete(0, tkinter.END)
  57. plugin_box.insert(0, *systemctl.get_plugin(index))
  58. def add_plugin():
  59. index = plugin_dir_box.curselection()[0]
  60. plugin_dir = askopenfilename(title="选择插件文件", filetypes=[("Python", ".py")])
  61. try:
  62. plugin_list = systemctl.add_plugin(index, plugin_dir)
  63. except NamingError:
  64. showwarning("文件错误", "插件命名错误,命名规则:\ntemplate_[类\\方法名].py")
  65. except ConflictError:
  66. if askokcancel("提示", f"已经存在插件,是否需要尝试合并插件?\n[合并失败将产生不可逆的后果]"):
  67. systemctl.merge_plugin(index, plugin_dir)
  68. except BaseException as e:
  69. showwarning("文件错误", f"插件导入遇到了未知错误:\n{e}")
  70. else:
  71. plugin_box.delete(0, tkinter.END)
  72. plugin_box.insert(0, *plugin_list)
  73. def del_plugin():
  74. index = plugin_box.curselection()[0]
  75. try:
  76. plugin_list = systemctl.del_plugin(index)
  77. plugin_box.delete(0, tkinter.END)
  78. plugin_box.insert(0, *plugin_list)
  79. finally:
  80. pass
  81. def show_plugin():
  82. index = plugin_box.curselection()[0]
  83. try:
  84. code, name = systemctl.show_plugin(index)
  85. code_window(name)[0].insert(tkinter.END, code)
  86. finally:
  87. pass
  88. def show_log():
  89. try:
  90. log = systemctl.show_log()
  91. code_window('日志信息')[0].insert(tkinter.END, log)
  92. finally:
  93. pass
  94. def system_main(in_queue, out_queue):
  95. global SCREEN
  96. queue_controller.set_queue(in_queue, out_queue)
  97. queue_controller()
  98. SCREEN.mainloop()
  99. queue_controller.stop_process()
  100. (
  101. tkinter.Label(
  102. SCREEN,
  103. text="【插件管理】",
  104. bg=bg_color,
  105. fg=word_color,
  106. font=FONT,
  107. width=gui_width * 3,
  108. height=gui_height,
  109. ).grid(column=column, row=row, columnspan=3)
  110. )
  111. row += 1
  112. (
  113. tkinter.Button(
  114. SCREEN,
  115. bg=botton_color,
  116. fg=word_color,
  117. command=get_dir,
  118. text="查看插件列表",
  119. font=FONT,
  120. width=gui_width,
  121. height=gui_height,
  122. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  123. )
  124. (
  125. tkinter.Button(
  126. SCREEN,
  127. bg=botton_color,
  128. fg=word_color,
  129. command=get_all_plugin,
  130. text="查看所有插件",
  131. font=FONT,
  132. width=gui_width,
  133. height=gui_height,
  134. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  135. )
  136. (
  137. tkinter.Button(
  138. SCREEN,
  139. bg=botton_color,
  140. fg=word_color,
  141. command=get_plugin,
  142. text="查看仓库插件",
  143. font=FONT,
  144. width=gui_width,
  145. height=gui_height,
  146. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  147. )
  148. row += 1
  149. plugin_box = tkinter.Listbox(SCREEN, width=gui_width * 3, height=gui_height * 5)
  150. plugin_box.grid(
  151. column=column,
  152. row=row,
  153. columnspan=3,
  154. rowspan=5,
  155. sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N,
  156. )
  157. row += 5
  158. (
  159. tkinter.Label(
  160. SCREEN,
  161. text="【插件仓库】",
  162. bg=bg_color,
  163. fg=word_color,
  164. font=FONT,
  165. width=gui_width * 3,
  166. height=gui_height,
  167. ).grid(column=column, row=row, columnspan=3)
  168. )
  169. row += 1
  170. plugin_dir_box = tkinter.Listbox(SCREEN, width=gui_width * 3, height=gui_height * 5)
  171. plugin_dir_box.grid(
  172. column=column,
  173. row=row,
  174. columnspan=3,
  175. rowspan=5,
  176. sticky=tkinter.E + tkinter.W + tkinter.S + tkinter.N,
  177. )
  178. row += 5
  179. (
  180. tkinter.Button(
  181. SCREEN,
  182. bg=botton_color,
  183. fg=word_color,
  184. command=add_plugin,
  185. text="新增插件",
  186. font=FONT,
  187. width=gui_width,
  188. height=gui_height,
  189. ).grid(column=column, row=row, sticky=tkinter.E + tkinter.W)
  190. )
  191. (
  192. tkinter.Button(
  193. SCREEN,
  194. bg=botton_color,
  195. fg=word_color,
  196. command=del_plugin,
  197. text="删除插件",
  198. font=FONT,
  199. width=gui_width,
  200. height=gui_height,
  201. ).grid(column=column + 1, row=row, sticky=tkinter.E + tkinter.W)
  202. )
  203. (
  204. tkinter.Button(
  205. SCREEN,
  206. bg=botton_color,
  207. fg=word_color,
  208. command=show_plugin,
  209. text="查看插件",
  210. font=FONT,
  211. width=gui_width,
  212. height=gui_height,
  213. ).grid(column=column + 2, row=row, sticky=tkinter.E + tkinter.W)
  214. )
  215. (
  216. tkinter.Label(
  217. SCREEN,
  218. text="【日志管理】",
  219. bg=bg_color,
  220. fg=word_color,
  221. font=FONT,
  222. width=gui_width * 3,
  223. height=gui_height,
  224. ).grid(column=column, row=row, columnspan=3)
  225. )
  226. row += 1
  227. (
  228. tkinter.Button(
  229. SCREEN,
  230. bg=botton_color,
  231. fg=word_color,
  232. command=lambda: webbrowser.open(r'E:\SongZihuan\PyProject\CoTan\Log\log_system.log'),
  233. text="查看日记",
  234. font=FONT,
  235. width=gui_width,
  236. height=gui_height,
  237. ).grid(column=column, columnspan=3, row=row, sticky=tkinter.E + tkinter.W)
  238. )