admin.py 24 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709
  1. import tkinter as tk
  2. from tkinter import ttk
  3. from tkinter import messagebox as msg
  4. import tkinter.font as font
  5. import abc
  6. import time
  7. import conf
  8. from tool.type_ import *
  9. from sql.db import DB
  10. from sql.user import creat_new_user, del_user, find_user_by_name
  11. from sql.garbage import creat_new_garbage, del_garbage_not_use, del_garbage_not_use_many
  12. from equipment.scan_user import write_uid_qr, write_all_uid_qr
  13. from equipment.scan_garbage import write_gid_qr
  14. from core.user import User
  15. from core.garbage import GarbageBag
  16. from tk_event import TkEventBase, TkEventMain, TkThreading
  17. class AdminStationException(Exception):
  18. ...
  19. class CreatGarbageError(AdminStationException):
  20. ...
  21. class CreatUserError(AdminStationException):
  22. ...
  23. class AdminEventBase(TkEventBase):
  24. def __init__(self, station, title: str = 'unknown'):
  25. self.station: AdminStationBase = station
  26. self._db: DB = station.get_db()
  27. self._title = title
  28. def get_title(self) -> str:
  29. return self._title
  30. def is_end(self) -> bool:
  31. raise AdminStationException
  32. def done_after_event(self):
  33. raise AdminStationException
  34. class AdminStationBase(TkEventMain, metaclass=abc.ABCMeta):
  35. def __init__(self, db: DB):
  36. self._admin: Optional[User] = None
  37. self._db = db
  38. super(AdminStationBase, self).__init__()
  39. def get_db(self):
  40. return self._db
  41. def creat_garbage(self, path: str, num: int = 1) -> List[tuple[str, Optional[GarbageBag]]]:
  42. re = []
  43. for _ in range(num):
  44. gar = creat_new_garbage(self._db)
  45. if gar is None:
  46. raise CreatGarbageError
  47. res = write_gid_qr(gar.get_gid(), path, self._db)
  48. re.append(res)
  49. return re
  50. def creat_user(self, name: uname_t, passwd: passwd_t, phone: str, manager: bool) -> Optional[User]:
  51. user = creat_new_user(name, passwd, phone, manager, self._db)
  52. if user is None:
  53. raise CreatUserError
  54. return user
  55. def creat_user_from_list(self, user_list: List[Tuple[uname_t, passwd_t, str]], manager: bool) -> List[User]:
  56. re = []
  57. for i in user_list:
  58. user = creat_new_user(i[0], i[1], i[2], manager, self._db)
  59. if user is None:
  60. raise CreatUserError
  61. re.append(user)
  62. return re
  63. def get_gid_qrcode(self, gid: gid_t, path: str) -> Tuple[str, Optional[GarbageBag]]:
  64. return write_gid_qr(gid, path, self._db)
  65. def get_all_gid_qrcode(self, path: str, where: str = "") -> List[str]:
  66. return write_all_uid_qr(path, self._db, where=where)
  67. def get_uid_qrcode(self, uid: uid_t, path: str) -> Tuple[str, Optional[User]]:
  68. return write_uid_qr(uid, path, self._db)
  69. def get_all_uid_qrcode(self, path: str, where: str = "") -> List[str]:
  70. return write_all_uid_qr(path, self._db, where=where)
  71. def del_garbage(self, gid: gid_t) -> bool:
  72. return del_garbage_not_use(gid, self._db)
  73. def del_garbage_many(self, from_: gid_t, to_: gid_t) -> int:
  74. return del_garbage_not_use_many(from_, to_, self._db)
  75. def del_user(self, uid: uid_t) -> bool:
  76. return del_user(uid, self._db)
  77. @abc.abstractmethod
  78. def login_call(self):
  79. ...
  80. def login(self, user: User) -> bool:
  81. if user is not None and user.is_manager():
  82. self._admin = user
  83. return True
  84. else:
  85. return False
  86. @abc.abstractmethod
  87. def show_loading(self, title: str):
  88. ...
  89. @abc.abstractmethod
  90. def stop_loading(self):
  91. ...
  92. @abc.abstractmethod
  93. def set_after_run(self, ms, func, *args):
  94. ...
  95. class AdminStation(AdminStationBase):
  96. def set_after_run(self, ms, func, *args): # super.__init__可能会调用
  97. self.init_after_run_list.append((ms, func, args))
  98. def __conf_set_after_run(self):
  99. for ms, func, args in self.init_after_run_list:
  100. self._window.after(ms, func, *args)
  101. def set_after_run_now(self, ms, func, *args):
  102. self._window.after(ms, func, *args)
  103. def __init__(self, db: DB, refresh_delay: int = conf.tk_refresh_delay):
  104. self.init_after_run_list: List[Tuple[int, Callable, Tuple]] = []
  105. super().__init__(db)
  106. self.refresh_delay = refresh_delay
  107. self._window = tk.Tk()
  108. self.login_window = None
  109. self._sys_height = self._window.winfo_screenheight()
  110. self._sys_width = self._window.winfo_screenwidth()
  111. self._win_height = int(self._sys_height * (2 / 3))
  112. self._win_width = int(self._sys_width * (2 / 3))
  113. self.__conf_windows()
  114. self._full_screen = False
  115. self._is_loading = False
  116. self._disable_all_btn = False
  117. self._now_program: Optional[Tuple[str, tk.Frame, AdminProgram]] = None
  118. self.__conf_font_size()
  119. self.__conf_creak_tk()
  120. self.__conf_creak_menu()
  121. self.__conf_creak_program()
  122. self.__conf_tk()
  123. # self.__show_login_window()
  124. self.__conf_set_after_run()
  125. def __conf_windows(self):
  126. self._window.title('HGSSystem: Manage Station')
  127. self._window.geometry(f'{self._win_width}x{self._win_height}')
  128. self._window['bg'] = "#F0FFF0"
  129. self._window.resizable(False, False)
  130. self._window.protocol("WM_DELETE_WINDOW", lambda: self.main_exit())
  131. def __conf_creak_tk(self):
  132. self._win_ctrl_button: List[tk.Button, tk.Button, tk.Button] = [tk.Button(self._window),
  133. tk.Button(self._window),
  134. tk.Button(self._window),
  135. tk.Button(self._window),
  136. tk.Button(self._window)]
  137. self._menu_back = tk.Frame(self._window)
  138. self._menu_line = tk.Label(self._menu_back) # 下划线
  139. self._menu_title: Tuple[tk.Label, tk.Variable] = tk.Label(self._menu_back), tk.StringVar()
  140. self._menu_dict: Dict[str, AdminMenu] = {}
  141. self._menu_list: List[str] = [] # 菜单回溯
  142. self._program_back = tk.Frame(self._window)
  143. self._program_title: Tuple[tk.Label, tk.Variable] = tk.Label(self._program_back), tk.StringVar()
  144. self._program_dict: Dict[str, AdminProgram] = {}
  145. self._msg_frame = tk.Frame(self._window)
  146. self._msg_label = tk.Label(self._msg_frame), tk.Label(self._msg_frame), tk.StringVar(), tk.StringVar()
  147. self._msg_hide = tk.Button(self._msg_frame)
  148. self._loading_pro = ttk.Progressbar(self._window)
  149. def __conf_font_size(self, n: int = 1):
  150. self._login_title_font_size = int(12 * n)
  151. self._login_btn_font_size = int(11 * n)
  152. self._win_ctrl_font_size = int(15 * n)
  153. self._menu_title_font_size = int(17 * n)
  154. self._program_title_font_size = int(14 * n)
  155. self._msg_font_size = int(20 * n)
  156. def __conf_tk(self, n: int = 1):
  157. self.__conf_win_ctrl_button()
  158. self.__conf_menu_title()
  159. self.__conf_menu(n)
  160. self.__conf_program_title()
  161. self.__conf_program(n)
  162. self.__conf_loading()
  163. self.__conf_msg()
  164. self.to_menu() # 显示主页面
  165. self.to_program()
  166. def __conf_win_ctrl_button(self):
  167. title_font = self.make_font(size=self._win_ctrl_font_size)
  168. for bt in self._win_ctrl_button:
  169. bt: tk.Button
  170. bt['bg'] = "#B0C4DE" # 浅钢青
  171. bt['font'] = title_font
  172. rely = 0.02
  173. bt_help: tk.Button = self._win_ctrl_button[0]
  174. bt_help['text'] = 'Back'
  175. bt_help['bg'] = '#DCDCDC'
  176. bt_help.place(relx=0.69, rely=rely, relwidth=0.05, relheight=0.05)
  177. bt_about: tk.Button = self._win_ctrl_button[1]
  178. bt_about['text'] = 'Main'
  179. bt_about['bg'] = '#DCDCDC'
  180. bt_about.place(relx=0.75, rely=rely, relwidth=0.05, relheight=0.05)
  181. bt_help: tk.Button = self._win_ctrl_button[2]
  182. bt_help['text'] = 'Help'
  183. bt_help['bg'] = '#DCDCDC'
  184. bt_help.place(relx=0.81, rely=rely, relwidth=0.05, relheight=0.05)
  185. bt_about: tk.Button = self._win_ctrl_button[3]
  186. bt_about['text'] = 'About'
  187. bt_about['bg'] = '#DCDCDC'
  188. bt_about.place(relx=0.87, rely=rely, relwidth=0.05, relheight=0.05)
  189. bt_exit: tk.Button = self._win_ctrl_button[4]
  190. bt_exit['text'] = 'Exit'
  191. bt_exit['bg'] = '#DCDCDC'
  192. bt_exit['command'] = lambda: self.main_exit()
  193. bt_exit.place(relx=0.93, rely=rely, relwidth=0.05, relheight=0.05)
  194. def __conf_creak_menu(self):
  195. frame_list = [
  196. MainMenu(self, self._menu_back, '#fffffb')
  197. ]
  198. for i in frame_list:
  199. name, _ = i.get_menu_frame()
  200. self._menu_dict[name] = i
  201. def __conf_menu(self, n: int = 1):
  202. for i in self._menu_dict:
  203. menu = self._menu_dict[i]
  204. menu.conf_gui("#DCDCDC", n)
  205. def __conf_menu_title(self):
  206. self._menu_back['bg'] = "#fffffb"
  207. self._menu_back['bd'] = 5
  208. self._menu_back['relief'] = "ridge"
  209. title_font = self.make_font(size=self._menu_title_font_size, weight="bold")
  210. self._menu_title[0]['bg'] = '#fffffb'
  211. self._menu_title[0]['font'] = title_font
  212. self._menu_title[0]['textvariable'] = self._menu_title[1]
  213. self._menu_line['bg'] = '#000000'
  214. # 不立即显示
  215. def to_menu(self, name: str = "Main"):
  216. menu = self._menu_dict.get(name)
  217. if menu is None:
  218. ...
  219. name, frame = menu.get_menu_frame()
  220. self._menu_title[1].set(name)
  221. self._menu_back.place(relx=0.02, rely=0.02, relwidth=0.20, relheight=0.96)
  222. self._menu_line.place(relx=0.06, rely=0.065, relwidth=0.88, height=1) # 一个像素的高度即可
  223. self._menu_title[0].place(relx=0.02, rely=0.02, relwidth=0.96, relheight=0.03)
  224. frame.place(relx=0.02, rely=0.07, relwidth=0.96, relheight=0.84)
  225. self._menu_list.append(name)
  226. def __conf_program_title(self):
  227. self._program_back['bg'] = "#fffffb"
  228. self._program_back['relief'] = "ridge"
  229. self._program_back['bd'] = 5
  230. title_font = self.make_font(size=self._program_title_font_size, weight="bold")
  231. self._program_title[0]['bg'] = '#2468a2'
  232. self._program_title[0]['fg'] = "#F0F8FF"
  233. self._program_title[0]['font'] = title_font
  234. self._program_title[0]['anchor'] = 'w'
  235. self._program_title[0]['textvariable'] = self._program_title[1]
  236. # 不立即显示
  237. def __conf_creak_program(self):
  238. program_list = [
  239. WelcomeProgram(self, self._program_back, '#fffffb')
  240. ]
  241. for i in program_list:
  242. name, _ = i.get_program_frame()
  243. self._program_dict[name] = i
  244. def __conf_program(self, n: int = 1):
  245. for i in self._program_dict:
  246. program = self._program_dict[i]
  247. program.conf_gui(n)
  248. def to_program(self, name: str = "Welcome"):
  249. program = self._program_dict.get(name)
  250. if program is None:
  251. ...
  252. name, frame = program.get_program_frame()
  253. self.__show_program()
  254. self._program_title[1].set(f' {name}')
  255. self._program_title[0].place(relx=0.00, rely=0.00, relwidth=1, relheight=0.05)
  256. frame.place(relx=0.02, rely=0.12, relwidth=0.96, relheight=0.86)
  257. self._now_program = name, frame, program
  258. def __show_program(self):
  259. self._program_back.place(relx=0.26, rely=0.1, relwidth=0.68, relheight=0.84)
  260. def __hide_program(self):
  261. self._program_back.place_forget()
  262. def __conf_loading(self):
  263. self._loading_pro['mode'] = 'indeterminate'
  264. self._loading_pro['orient'] = tk.HORIZONTAL
  265. self._loading_pro['maximum'] = 50
  266. def show_loading(self, _):
  267. self._is_loading = True
  268. self.set_all_btn_disable()
  269. self._loading_pro['value'] = 0
  270. self._loading_pro.place(relx=0.30, rely=0.035, relwidth=0.35, relheight=0.03)
  271. self._loading_pro.start(50)
  272. def stop_loading(self):
  273. self._is_loading = False
  274. self._loading_pro.place_forget()
  275. self._loading_pro.stop()
  276. self.set_reset_all_btn()
  277. def __conf_msg(self):
  278. title_font = self.make_font(size=self._msg_font_size + 1, weight="bold")
  279. info_font = self.make_font(size=self._msg_font_size - 1)
  280. self._msg_frame['bg'] = "#fffffb"
  281. self._msg_frame['bd'] = 5
  282. self._msg_frame['relief'] = "ridge"
  283. # frame 不会立即显示
  284. self._msg_label[0]['font'] = title_font
  285. self._msg_label[0]['bg'] = "#fffffb"
  286. self._msg_label[0]['anchor'] = 'w'
  287. self._msg_label[0]['textvariable'] = self._msg_label[2]
  288. self._msg_label[1]['font'] = info_font
  289. self._msg_label[1]['bg'] = "#fffffb"
  290. self._msg_label[1]['anchor'] = 'nw'
  291. self._msg_label[1]['textvariable'] = self._msg_label[3]
  292. self._msg_label[1]['justify'] = 'left'
  293. self._msg_label[0].place(relx=0.05, rely=0.05, relwidth=0.9, relheight=0.1)
  294. self._msg_label[1].place(relx=0.075, rely=0.2, relwidth=0.85, relheight=0.58)
  295. self._msg_hide['font'] = info_font
  296. self._msg_hide['text'] = 'close'
  297. self._msg_hide['bg'] = "#DCDCDC"
  298. self._msg_hide['command'] = lambda: self.hide_msg()
  299. self._msg_hide.place(relx=0.375, rely=0.80, relwidth=0.25, relheight=0.13)
  300. def show_msg(self, title, info, msg_type='info'):
  301. assert not self._is_loading # loading 时不显示msg
  302. self.set_all_btn_disable()
  303. self._msg_label[2].set(f'{msg_type}: {title}')
  304. self._msg_label[3].set(f'{info}')
  305. frame_width = self._win_width * 0.50
  306. self._msg_label[1]['wraplength'] = frame_width * 0.85 - 5 # 设定自动换行的像素
  307. self._msg_frame.place(relx=0.30, rely=0.25, relwidth=0.55, relheight=0.50)
  308. self.__hide_program()
  309. def hide_msg(self):
  310. self.set_reset_all_btn()
  311. self._msg_frame.place_forget()
  312. self.__show_program()
  313. def set_all_btn_disable(self):
  314. for btn in self._win_ctrl_button[:-1]: # Exit 不设置disable
  315. btn['state'] = 'disable'
  316. if self._menu_list != 0:
  317. menu = self._menu_dict.get(self._menu_list[-1], None)
  318. assert menu is not None
  319. menu.set_disable()
  320. if self._now_program is not None:
  321. self._now_program[2].set_disable()
  322. def set_reset_all_btn(self):
  323. for btn in self._win_ctrl_button[:-1]:
  324. btn['state'] = 'normal'
  325. if self._menu_list != 0:
  326. menu = self._menu_dict.get(self._menu_list[-1], None)
  327. assert menu is not None
  328. menu.reset_disable()
  329. if self._now_program is not None:
  330. self._now_program[2].reset_disable()
  331. def __show_login_window(self):
  332. self.login_window: Optional[tk.Toplevel] = tk.Toplevel()
  333. self.login_window.title("HGSSystem Login")
  334. height = int(self._sys_height * (1 / 6))
  335. width = int(height * 2)
  336. if width > self._sys_width:
  337. width = int(self._sys_width * (2 / 3))
  338. height = int(width / 2)
  339. self.login_window.geometry(f'{width}x{height}')
  340. self.login_window['bg'] = "#d1d9e0"
  341. self.login_window.resizable(False, False)
  342. self.login_window.protocol("WM_DELETE_WINDOW", lambda: self.login_exit())
  343. self._login_name = [tk.Label(self.login_window), tk.Entry(self.login_window), tk.StringVar()]
  344. self._login_passwd = [tk.Label(self.login_window), tk.Entry(self.login_window), tk.StringVar()]
  345. self._login_btn = [tk.Button(self.login_window), tk.Button(self.login_window)]
  346. self.__conf_login_window()
  347. self.hide_main()
  348. def __conf_login_window(self):
  349. title_font = self.make_font(size=self._login_title_font_size, weight="bold")
  350. btn_font = self.make_font(size=self._login_btn_font_size, weight="bold")
  351. for lb, text in zip([self._login_name[0], self._login_passwd[0]], ["User:", "Passwd:"]):
  352. lb['bg'] = "#d1d9e0" # 蜜瓜绿
  353. lb['font'] = title_font
  354. lb['text'] = text
  355. lb['anchor'] = 'e'
  356. for lb, var in zip([self._login_name[1], self._login_passwd[1]], [self._login_name[2], self._login_passwd[2]]):
  357. lb['font'] = title_font
  358. lb['textvariable'] = var
  359. self._login_name[0].place(relx=0.00, rely=0.20, relwidth=0.35, relheight=0.15)
  360. self._login_passwd[0].place(relx=0.00, rely=0.40, relwidth=0.35, relheight=0.15)
  361. self._login_name[1].place(relx=0.40, rely=0.20, relwidth=0.45, relheight=0.15)
  362. self._login_passwd[1]['show'] = "*"
  363. self._login_passwd[1].place(relx=0.40, rely=0.40, relwidth=0.45, relheight=0.15)
  364. self._login_btn[0]['bg'] = "#a1afc9"
  365. self._login_btn[0]['font'] = btn_font
  366. self._login_btn[0]['text'] = 'Login'
  367. self._login_btn[0]['command'] = lambda: self.login_call()
  368. self._login_btn[0].place(relx=0.50, rely=0.70, relwidth=0.16, relheight=0.15)
  369. self._login_btn[1]['bg'] = "#a1afc9"
  370. self._login_btn[1]['font'] = btn_font
  371. self._login_btn[1]['text'] = 'Exit'
  372. self._login_btn[1]['command'] = lambda: self.login_exit()
  373. self._login_btn[1].place(relx=0.70, rely=0.70, relwidth=0.16, relheight=0.15)
  374. def login_call(self):
  375. event = LoginEvent(self).start(self._login_name[2].get(), self._login_passwd[2].get())
  376. self.push_event(event)
  377. def login(self, user: User):
  378. if super(AdminStation, self).login(user):
  379. self.login_window.destroy()
  380. self.login_window = None
  381. self.show_main()
  382. else:
  383. msg.showerror("Login error", "Please, try again")
  384. self._login_name[2].set('')
  385. self._login_passwd[2].set('')
  386. def login_exit(self):
  387. if not msg.askokcancel('Sure?', 'Exit manager system.'):
  388. return
  389. if self.login_window is not None:
  390. self.login_window.destroy()
  391. self.exit_win()
  392. def main_exit(self):
  393. if not msg.askokcancel('Sure?', 'Exit manager system.'):
  394. return
  395. self.exit_win()
  396. def hide_main(self):
  397. self._window.withdraw()
  398. def show_main(self):
  399. self._window.update()
  400. self._window.deiconify()
  401. @staticmethod
  402. def make_font(family: str = 'noto', **kwargs):
  403. return font.Font(family=conf.font_d[family], **kwargs)
  404. @staticmethod
  405. def set_button_disable_from_list(btn_list: List[tk.Button], flat: str = 'disable'):
  406. for btn in btn_list:
  407. btn['state'] = flat
  408. def mainloop(self):
  409. self._window.mainloop()
  410. def exit_win(self):
  411. self._window.destroy()
  412. class LoginEvent(AdminEventBase):
  413. def __init__(self, station: AdminStationBase):
  414. super().__init__(station, "Ranking")
  415. self.thread: Optional[TkThreading] = None
  416. def login(self, name, passwd):
  417. return find_user_by_name(name, passwd, self._db)
  418. def start(self, name, passwd):
  419. self.thread = TkThreading(self.login, name, passwd)
  420. return self
  421. def is_end(self) -> bool:
  422. return not self.thread.is_alive()
  423. def done_after_event(self):
  424. self.station.login(self.thread.wait_event())
  425. class TestProgressEvent(AdminEventBase):
  426. @staticmethod
  427. def func(sleep_time):
  428. time.sleep(sleep_time)
  429. def __init__(self, station, db):
  430. super(TestProgressEvent, self).__init__(station, db)
  431. self.thread = TkThreading(self.func, 5)
  432. def is_end(self) -> bool:
  433. return not self.thread.is_alive()
  434. def done_after_event(self):
  435. ...
  436. class AdminMenu(metaclass=abc.ABCMeta):
  437. def __init__(self, station: AdminStation, win: Union[tk.Frame, tk.Toplevel, tk.Tk], color: str):
  438. self.station = station
  439. self.win = win
  440. self.color = color
  441. @abc.abstractmethod
  442. def set_disable(self):
  443. ...
  444. @abc.abstractmethod
  445. def reset_disable(self):
  446. ...
  447. @abc.abstractmethod
  448. def conf_gui(self, color: str, n: int = 1):
  449. ...
  450. @abc.abstractmethod
  451. def get_menu_frame(self) -> Tuple[str, tk.Frame]:
  452. ...
  453. class AdminProgram(metaclass=abc.ABCMeta):
  454. def __init__(self, station: AdminStation, win: Union[tk.Frame, tk.Toplevel, tk.Tk], color: str):
  455. self.station = station
  456. self.win = win
  457. self.color = color
  458. @abc.abstractmethod
  459. def set_disable(self):
  460. ...
  461. @abc.abstractmethod
  462. def reset_disable(self):
  463. ...
  464. @abc.abstractmethod
  465. def conf_gui(self, n: int = 1):
  466. ...
  467. @abc.abstractmethod
  468. def get_program_frame(self) -> tk.Frame:
  469. ...
  470. class MainMenu(AdminMenu):
  471. def __init__(self, station, win, color):
  472. super(MainMenu, self).__init__(station, win, color)
  473. self.frame = tk.Frame(self.win)
  474. self.frame['bg'] = color
  475. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(5)]
  476. self.__conf_font()
  477. def __conf_font(self, n: int = 1):
  478. self.btn_font_size = int(16 * n)
  479. def conf_gui(self, color: str, n: int = 1):
  480. self.__conf_font(n)
  481. btn_font = self.station.make_font(size=self.btn_font_size, weight="bold")
  482. height = 0.02
  483. for btn, text in zip(self.btn, ["Creat", "Delete", "Search", "Update", "Logout"]):
  484. btn['font'] = btn_font
  485. btn['text'] = text
  486. btn['bg'] = color
  487. btn.place(relx=0.02, rely=height, relwidth=0.96, relheight=0.1)
  488. height += 0.1 + 0.02
  489. def get_menu_frame(self) -> Tuple[str, tk.Frame]:
  490. return "Main", self.frame
  491. def set_disable(self):
  492. self.station.set_button_disable_from_list(self.btn)
  493. def reset_disable(self):
  494. self.station.set_button_disable_from_list(self.btn, flat='normal')
  495. class WelcomeProgram(AdminProgram):
  496. def __init__(self, station, win, color):
  497. super(WelcomeProgram, self).__init__(station, win, color)
  498. self.frame = tk.Frame(self.win)
  499. self.frame['bg'] = color
  500. self.title = tk.Label(self.frame)
  501. self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)]
  502. self.__conf_font()
  503. def __conf_font(self, n: int = 1):
  504. self.title_font_size = int(25 * n)
  505. self.btn_font_size = int(14 * n)
  506. def conf_gui(self, n: int = 1):
  507. self.__conf_font(n)
  508. title_font = self.station.make_font(size=self.title_font_size, weight="bold")
  509. btn_font = self.station.make_font(size=self.btn_font_size)
  510. for btn, text in zip(self.btn, ["TestMSG", "TestProgress"]):
  511. btn['font'] = btn_font
  512. btn['text'] = text
  513. btn['bg'] = '#d3d7d4'
  514. self.title['text'] = 'Welcome to HGSSystem Manager'
  515. self.title['font'] = title_font
  516. self.title['bg'] = self.color
  517. self.btn[0]['command'] = lambda: self.test_msg()
  518. self.btn[1]['command'] = lambda: self.test_progress()
  519. self.title.place(relx=0.1, rely=0.3, relwidth=0.8, relheight=0.2)
  520. self.btn[0].place(relx=0.2, rely=0.7, relwidth=0.2, relheight=0.1)
  521. self.btn[1].place(relx=0.6, rely=0.7, relwidth=0.2, relheight=0.1)
  522. def test_progress(self):
  523. event = TestProgressEvent(self.station, "Sleep(5)")
  524. self.station.push_event(event)
  525. def test_msg(self):
  526. self.station.show_msg("Test Msg", "test msg")
  527. def get_program_frame(self) -> Tuple[str, tk.Frame]:
  528. return "Welcome", self.frame
  529. def set_disable(self):
  530. self.station.set_button_disable_from_list(self.btn)
  531. def reset_disable(self):
  532. self.station.set_button_disable_from_list(self.btn, flat='normal')
  533. if __name__ == '__main__':
  534. mysql_db = DB()
  535. station_ = AdminStation(mysql_db)
  536. station_.mainloop()