toolbox.py 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400
  1. import os
  2. from tkinter.colorchooser import askcolor
  3. from newtkinter import asksaveasfilename, askopenfilename
  4. import tkinter.messagebox
  5. from draftboard import drawingfunction
  6. SCREEN = None
  7. pen_weight_input = None
  8. span_input = None
  9. background_image = None
  10. func_logger = drawingfunction.Logger()
  11. coordinate_system_drawing_method = None
  12. background_color = None
  13. pen_weight = None
  14. pen_color = None
  15. increasing_color = None
  16. subtraction_color = None
  17. save_dir = None
  18. gui_width = 20
  19. gui_height = 3
  20. span = None
  21. bg_color = "#FFFAFA" # 主颜色
  22. bottom_color = "#FFFAFA" # 按钮颜色
  23. word_color = "#000000" # 文字颜色
  24. help_doc = """
  25. *快捷键:
  26. d-不用点击左键画线(再次点击关闭)
  27. g-画直线(2)
  28. f-画填充矩阵3
  29. s-画矩阵边框4
  30. k-画横线5
  31. l-画竖线6
  32. j-画多段线7
  33. i-横线多段线打点(再次点击结束绘制)8
  34. u-竖线多段线打点(再次点击结束绘制)9
  35. h-横线和竖线多段线打点并由虚线标注(再次点击结束绘制)10
  36. q-绘制虚线11
  37. c-绘制填充圆形12
  38. v-绘制圆形边框(13)
  39. n和m-绘制多边形(14)
  40. n-再次点击完成填充多边形绘制(14)
  41. m-再次点击完成多边形边框绘制(14)
  42. o-捕捉坐标原点(请先点击功能快捷键)
  43. x-捕捉坐标x轴(请先点击功能快捷键并选择起点)
  44. y-捕捉坐标y轴(同上)
  45. b-关闭当前所有快捷键操作
  46. e-绘制填充椭圆(15)
  47. r-绘制椭圆边框(16)
  48. w-再次保存(前提是现在工具箱点击过一次保存)
  49. *鼠标操作:
  50. 左键-按下画曲线
  51. 中键-快捷键启动后,用于选择点
  52. 右键-打开工具箱
  53. *视图
  54. 顶部-显示鼠标坐标,按键点击模式,笔的大小,坐标系位置和颜色系统以及坐标系原点的位置(处于快捷键状态时,显示中键当前选择了的点)
  55. 底部-显示当前时间(处于快捷键状态时,显示快捷键提示mod:yes None xxx,其中yes表示快捷键d启动,None表示快捷键注释,xxx表示快捷功能解释)
  56. *工具箱操作:
  57. 选择颜色-画线颜色
  58. 选择增函数颜色-绘制函数时增函数颜色
  59. 选择减函数颜色-绘制函数时减函数颜色
  60. 选择笔的大小(刷子)-画线的粗细
  61. 清空-清空所有笔记并可以选择新的背景颜色
  62. 绘制坐标系-三点绘制坐标系(使用中键选择点)
  63. 保存-保存笔记为图片格式,保存一次后快捷键w可重复保存
  64. 绘制函数-绘制基本初等函数和字定义解析函数
  65. """
  66. class UIAPI:
  67. @staticmethod
  68. def askok_gui(message):
  69. return tkinter.messagebox.askokcancel('提示', message)
  70. class API:
  71. @staticmethod
  72. def increasing_func_color():
  73. global increasing_color
  74. increasing_color = askcolor(title="选择颜色")[0]
  75. @staticmethod
  76. def subtraction_func_color():
  77. global subtraction_color
  78. subtraction_color = askcolor(title="选择颜色")[0]
  79. @staticmethod
  80. def select_color():
  81. global pen_color
  82. pen_color = askcolor(title="选择颜色")[0]
  83. @staticmethod
  84. def choose_save():
  85. global save_dir
  86. save_dir = asksaveasfilename(
  87. title="选择保存位置", filetypes=[("PNG", ".png")]
  88. )
  89. if not save_dir:
  90. save_dir = None
  91. else:
  92. save_dir += ".png"
  93. @staticmethod
  94. def choose_open():
  95. global background_image
  96. background_image = askopenfilename(
  97. title="选择载入图片", filetypes=[("PNG", ".png"), ("JPG", ".jpg")]
  98. )
  99. if not background_image:
  100. background_image = None
  101. @staticmethod
  102. def switch_brush():
  103. global pen_weight
  104. if UIAPI.askok_gui("要切换到刷子吗(可当橡皮使用)"):
  105. pen_weight = 10
  106. @staticmethod
  107. def switch_big():
  108. global pen_weight
  109. if UIAPI.askok_gui("要切换到大笔吗"):
  110. pen_weight = 3
  111. @staticmethod
  112. def set_pen():
  113. global pen_weight, pen_weight_input
  114. pen = pen_weight_input.get().replace(" ", "")
  115. try:
  116. pen = int(pen)
  117. except ValueError:
  118. if UIAPI.askok_gui("设置失败,是否要切换到中笔吗"):
  119. pen_weight = 2
  120. else:
  121. if UIAPI.askok_gui(f"是否设定大小为{pen}(系统默认大小为:2)"):
  122. pen_weight = pen
  123. @staticmethod
  124. def switch_stroke():
  125. global pen_weight
  126. if UIAPI.askok_gui("要切换到中笔吗"):
  127. pen_weight = 2
  128. @staticmethod
  129. def switch_small():
  130. global pen_weight
  131. if UIAPI.askok_gui("要切换到小笔吗?"):
  132. pen_weight = 1
  133. @staticmethod
  134. def plot_coordinate():
  135. global coordinate_system_drawing_method
  136. if tkinter.messagebox.askokcancel(
  137. "提示", "是否绘制坐标系,确定后返回草图界面任一点三点开始绘制(点击取消可撤销未执行的清空)"
  138. ):
  139. coordinate_system_drawing_method = 1
  140. else:
  141. coordinate_system_drawing_method = None
  142. @staticmethod
  143. def plot_coordinate_small():
  144. global coordinate_system_drawing_method
  145. if tkinter.messagebox.askokcancel(
  146. "提示", "是否绘制小跨度的坐标系,确定后返回草图界面任一点三点开始绘制(点击取消可撤销未执行的清空)"
  147. ):
  148. coordinate_system_drawing_method = 2
  149. else:
  150. coordinate_system_drawing_method = None
  151. @staticmethod
  152. def plot_coordinate_big_span():
  153. global coordinate_system_drawing_method
  154. if tkinter.messagebox.askokcancel(
  155. "提示", "是否绘制大跨度的坐标系,确定后返回草图界面任一点三点开始绘制(点击取消可撤销未执行的清空)"
  156. ):
  157. coordinate_system_drawing_method = 3
  158. else:
  159. coordinate_system_drawing_method = None
  160. @staticmethod
  161. def set_span():
  162. global coordinate_system_drawing_method, span, span_input
  163. span_input_str = span_input.get().replace(" ", "")
  164. try:
  165. span_input_str = int(span_input_str)
  166. except ValueError:
  167. span = None
  168. if tkinter.messagebox.askokcancel(
  169. "提示", "是否绘制大跨度的坐标系,确定后返回草图界面任一点三点开始绘制(点击取消可撤销未执行的清空)"
  170. ):
  171. coordinate_system_drawing_method = 3
  172. else:
  173. coordinate_system_drawing_method = None
  174. else:
  175. if tkinter.messagebox.askokcancel(
  176. "提示", f"是否设定跨度为{span_input_str}(跨度代表坐标系一个单位大小的实际像素,系统默认大跨度为:120)"
  177. ):
  178. span = span_input_str
  179. coordinate_system_drawing_method = 1
  180. else:
  181. coordinate_system_drawing_method = None
  182. span = None
  183. @staticmethod
  184. def empty():
  185. global background_color
  186. if UIAPI.askok_gui("是否清空草稿(点击取消可撤销未执行的清空)"):
  187. background_color = askcolor(title="选择背景颜色")[0]
  188. else:
  189. background_color = None
  190. @staticmethod
  191. def open_func_box():
  192. global func_logger
  193. func_logger = drawingfunction.func_box()
  194. @staticmethod
  195. def show_help():
  196. global help_doc
  197. tkinter.messagebox.showinfo(title="帮助", message=help_doc)
  198. def tool_box():
  199. global SCREEN, span_input, pen_weight_input # 初始化屏幕
  200. SCREEN = tkinter.Tk() # 设置屏幕
  201. SCREEN["bg"] = bg_color
  202. SCREEN.title("Tool")
  203. SCREEN.resizable(width=False, height=False)
  204. SCREEN.geometry(f"+10+10")
  205. SCREEN.iconbitmap(bitmap=f'Pic{os.sep}favicon.ico', default=f'Pic{os.sep}favicon.ico')
  206. tkinter.Button(
  207. SCREEN,
  208. text="选择颜色",
  209. bg=bg_color,
  210. fg=word_color,
  211. command=API.select_color,
  212. width=gui_width,
  213. height=gui_height,
  214. ).pack()
  215. tkinter.Button(
  216. SCREEN,
  217. text="选择增函数颜色",
  218. bg=bg_color,
  219. fg=word_color,
  220. command=API.increasing_func_color,
  221. width=gui_width,
  222. height=1,
  223. ).pack()
  224. tkinter.Button(
  225. SCREEN,
  226. text="选择减函数颜色",
  227. bg=bg_color,
  228. fg=word_color,
  229. command=API.subtraction_func_color,
  230. width=gui_width,
  231. height=1,
  232. ).pack()
  233. tkinter.Button(
  234. SCREEN,
  235. text="使用中笔(默认笔)",
  236. bg=bg_color,
  237. fg=word_color,
  238. command=API.switch_stroke,
  239. width=gui_width,
  240. height=gui_height,
  241. ).pack()
  242. tkinter.Button(
  243. SCREEN,
  244. text="使用大笔",
  245. bg=bg_color,
  246. fg=word_color,
  247. command=API.switch_big,
  248. width=gui_width,
  249. height=1,
  250. ).pack() # 切换到大笔
  251. tkinter.Button(
  252. SCREEN,
  253. text="使用小笔",
  254. bg=bg_color,
  255. fg=word_color,
  256. command=API.switch_small,
  257. width=gui_width,
  258. height=1,
  259. ).pack() # 切换笔
  260. tkinter.Button(
  261. SCREEN,
  262. text="使用刷子",
  263. bg=bg_color,
  264. fg=word_color,
  265. command=API.switch_brush,
  266. width=gui_width,
  267. height=1,
  268. ).pack() # 切换笔
  269. pen_weight_input = tkinter.Entry(SCREEN, width=gui_width - 2)
  270. pen_weight_input.pack(fill=tkinter.BOTH)
  271. tkinter.Button(
  272. SCREEN,
  273. text="使用自定义大小",
  274. bg=bg_color,
  275. fg=word_color,
  276. command=API.set_pen,
  277. width=gui_width,
  278. height=1,
  279. ).pack() # 切换笔
  280. tkinter.Button(
  281. SCREEN,
  282. text="清空草稿",
  283. bg=bg_color,
  284. fg=word_color,
  285. command=API.empty,
  286. width=gui_width,
  287. height=gui_height,
  288. ).pack() # 填充背景
  289. tkinter.Button(
  290. SCREEN,
  291. text="绘制坐标系",
  292. bg=bg_color,
  293. fg=word_color,
  294. command=API.plot_coordinate,
  295. width=gui_width,
  296. height=gui_height,
  297. ).pack()
  298. tkinter.Button(
  299. SCREEN,
  300. text="绘制坐标系(小跨度)",
  301. bg=bg_color,
  302. fg=word_color,
  303. command=API.plot_coordinate_small,
  304. width=gui_width,
  305. height=1,
  306. ).pack()
  307. tkinter.Button(
  308. SCREEN,
  309. text="绘制坐标系(大跨度)",
  310. command=API.plot_coordinate_big_span,
  311. width=gui_width,
  312. height=1,
  313. bg=bg_color,
  314. fg=word_color,
  315. ).pack() # 绘制坐标系
  316. span_input = tkinter.Entry(SCREEN, width=gui_width - 2)
  317. span_input.pack(fill=tkinter.BOTH)
  318. tkinter.Button(
  319. SCREEN,
  320. text="使用自定义跨度",
  321. bg=bg_color,
  322. fg=word_color,
  323. command=API.set_span,
  324. width=gui_width,
  325. height=1,
  326. ).pack() # 切换笔
  327. tkinter.Button(
  328. SCREEN,
  329. text="绘制函数",
  330. bg=bg_color,
  331. fg=word_color,
  332. command=API.open_func_box,
  333. width=gui_width,
  334. height=gui_height,
  335. ).pack()
  336. tkinter.Button(
  337. SCREEN,
  338. text="保存",
  339. bg=bg_color,
  340. fg=word_color,
  341. command=API.choose_save,
  342. width=gui_width,
  343. height=1,
  344. ).pack()
  345. tkinter.Button(
  346. SCREEN,
  347. text="载入",
  348. bg=bg_color,
  349. fg=word_color,
  350. command=API.choose_open,
  351. width=gui_width,
  352. height=1,
  353. ).pack()
  354. tkinter.Button(
  355. SCREEN,
  356. text="帮助",
  357. bg=bg_color,
  358. fg=word_color,
  359. command=API.show_help,
  360. width=gui_width,
  361. height=1,
  362. ).pack() # help是系统保留关键词,用_help代替
  363. SCREEN.mainloop()
  364. func = func_logger()
  365. return [
  366. pen_color,
  367. pen_weight,
  368. background_color,
  369. coordinate_system_drawing_method,
  370. func,
  371. save_dir,
  372. increasing_color,
  373. subtraction_color,
  374. span,
  375. background_image,
  376. ]