123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709 |
- import tkinter as tk
- from tkinter import ttk
- from tkinter import messagebox as msg
- import tkinter.font as font
- import abc
- import time
- import conf
- from tool.type_ import *
- from sql.db import DB
- from sql.user import creat_new_user, del_user, find_user_by_name
- from sql.garbage import creat_new_garbage, del_garbage_not_use, del_garbage_not_use_many
- from equipment.scan_user import write_uid_qr, write_all_uid_qr
- from equipment.scan_garbage import write_gid_qr
- from core.user import User
- from core.garbage import GarbageBag
- from tk_event import TkEventBase, TkEventMain, TkThreading
- class AdminStationException(Exception):
- ...
- class CreatGarbageError(AdminStationException):
- ...
- class CreatUserError(AdminStationException):
- ...
- class AdminEventBase(TkEventBase):
- def __init__(self, station, title: str = 'unknown'):
- self.station: AdminStationBase = station
- self._db: DB = station.get_db()
- self._title = title
- def get_title(self) -> str:
- return self._title
- def is_end(self) -> bool:
- raise AdminStationException
- def done_after_event(self):
- raise AdminStationException
- class AdminStationBase(TkEventMain, metaclass=abc.ABCMeta):
- def __init__(self, db: DB):
- self._admin: Optional[User] = None
- self._db = db
- super(AdminStationBase, self).__init__()
- def get_db(self):
- return self._db
- def creat_garbage(self, path: str, num: int = 1) -> List[tuple[str, Optional[GarbageBag]]]:
- re = []
- for _ in range(num):
- gar = creat_new_garbage(self._db)
- if gar is None:
- raise CreatGarbageError
- res = write_gid_qr(gar.get_gid(), path, self._db)
- re.append(res)
- return re
- def creat_user(self, name: uname_t, passwd: passwd_t, phone: str, manager: bool) -> Optional[User]:
- user = creat_new_user(name, passwd, phone, manager, self._db)
- if user is None:
- raise CreatUserError
- return user
- def creat_user_from_list(self, user_list: List[Tuple[uname_t, passwd_t, str]], manager: bool) -> List[User]:
- re = []
- for i in user_list:
- user = creat_new_user(i[0], i[1], i[2], manager, self._db)
- if user is None:
- raise CreatUserError
- re.append(user)
- return re
- def get_gid_qrcode(self, gid: gid_t, path: str) -> Tuple[str, Optional[GarbageBag]]:
- return write_gid_qr(gid, path, self._db)
- def get_all_gid_qrcode(self, path: str, where: str = "") -> List[str]:
- return write_all_uid_qr(path, self._db, where=where)
- def get_uid_qrcode(self, uid: uid_t, path: str) -> Tuple[str, Optional[User]]:
- return write_uid_qr(uid, path, self._db)
- def get_all_uid_qrcode(self, path: str, where: str = "") -> List[str]:
- return write_all_uid_qr(path, self._db, where=where)
- def del_garbage(self, gid: gid_t) -> bool:
- return del_garbage_not_use(gid, self._db)
- def del_garbage_many(self, from_: gid_t, to_: gid_t) -> int:
- return del_garbage_not_use_many(from_, to_, self._db)
- def del_user(self, uid: uid_t) -> bool:
- return del_user(uid, self._db)
- @abc.abstractmethod
- def login_call(self):
- ...
- def login(self, user: User) -> bool:
- if user is not None and user.is_manager():
- self._admin = user
- return True
- else:
- return False
- @abc.abstractmethod
- def show_loading(self, title: str):
- ...
- @abc.abstractmethod
- def stop_loading(self):
- ...
- @abc.abstractmethod
- def set_after_run(self, ms, func, *args):
- ...
- class AdminStation(AdminStationBase):
- def set_after_run(self, ms, func, *args): # super.__init__可能会调用
- self.init_after_run_list.append((ms, func, args))
- def __conf_set_after_run(self):
- for ms, func, args in self.init_after_run_list:
- self._window.after(ms, func, *args)
- def set_after_run_now(self, ms, func, *args):
- self._window.after(ms, func, *args)
- def __init__(self, db: DB, refresh_delay: int = conf.tk_refresh_delay):
- self.init_after_run_list: List[Tuple[int, Callable, Tuple]] = []
- super().__init__(db)
- self.refresh_delay = refresh_delay
- self._window = tk.Tk()
- self.login_window = None
- self._sys_height = self._window.winfo_screenheight()
- self._sys_width = self._window.winfo_screenwidth()
- self._win_height = int(self._sys_height * (2 / 3))
- self._win_width = int(self._sys_width * (2 / 3))
- self.__conf_windows()
- self._full_screen = False
- self._is_loading = False
- self._disable_all_btn = False
- self._now_program: Optional[Tuple[str, tk.Frame, AdminProgram]] = None
- self.__conf_font_size()
- self.__conf_creak_tk()
- self.__conf_creak_menu()
- self.__conf_creak_program()
- self.__conf_tk()
- # self.__show_login_window()
- self.__conf_set_after_run()
- def __conf_windows(self):
- self._window.title('HGSSystem: Manage Station')
- self._window.geometry(f'{self._win_width}x{self._win_height}')
- self._window['bg'] = "#F0FFF0"
- self._window.resizable(False, False)
- self._window.protocol("WM_DELETE_WINDOW", lambda: self.main_exit())
- def __conf_creak_tk(self):
- self._win_ctrl_button: List[tk.Button, tk.Button, tk.Button] = [tk.Button(self._window),
- tk.Button(self._window),
- tk.Button(self._window),
- tk.Button(self._window),
- tk.Button(self._window)]
- self._menu_back = tk.Frame(self._window)
- self._menu_line = tk.Label(self._menu_back) # 下划线
- self._menu_title: Tuple[tk.Label, tk.Variable] = tk.Label(self._menu_back), tk.StringVar()
- self._menu_dict: Dict[str, AdminMenu] = {}
- self._menu_list: List[str] = [] # 菜单回溯
- self._program_back = tk.Frame(self._window)
- self._program_title: Tuple[tk.Label, tk.Variable] = tk.Label(self._program_back), tk.StringVar()
- self._program_dict: Dict[str, AdminProgram] = {}
- self._msg_frame = tk.Frame(self._window)
- self._msg_label = tk.Label(self._msg_frame), tk.Label(self._msg_frame), tk.StringVar(), tk.StringVar()
- self._msg_hide = tk.Button(self._msg_frame)
- self._loading_pro = ttk.Progressbar(self._window)
- def __conf_font_size(self, n: int = 1):
- self._login_title_font_size = int(12 * n)
- self._login_btn_font_size = int(11 * n)
- self._win_ctrl_font_size = int(15 * n)
- self._menu_title_font_size = int(17 * n)
- self._program_title_font_size = int(14 * n)
- self._msg_font_size = int(20 * n)
- def __conf_tk(self, n: int = 1):
- self.__conf_win_ctrl_button()
- self.__conf_menu_title()
- self.__conf_menu(n)
- self.__conf_program_title()
- self.__conf_program(n)
- self.__conf_loading()
- self.__conf_msg()
- self.to_menu() # 显示主页面
- self.to_program()
- def __conf_win_ctrl_button(self):
- title_font = self.make_font(size=self._win_ctrl_font_size)
- for bt in self._win_ctrl_button:
- bt: tk.Button
- bt['bg'] = "#B0C4DE" # 浅钢青
- bt['font'] = title_font
- rely = 0.02
- bt_help: tk.Button = self._win_ctrl_button[0]
- bt_help['text'] = 'Back'
- bt_help['bg'] = '#DCDCDC'
- bt_help.place(relx=0.69, rely=rely, relwidth=0.05, relheight=0.05)
- bt_about: tk.Button = self._win_ctrl_button[1]
- bt_about['text'] = 'Main'
- bt_about['bg'] = '#DCDCDC'
- bt_about.place(relx=0.75, rely=rely, relwidth=0.05, relheight=0.05)
- bt_help: tk.Button = self._win_ctrl_button[2]
- bt_help['text'] = 'Help'
- bt_help['bg'] = '#DCDCDC'
- bt_help.place(relx=0.81, rely=rely, relwidth=0.05, relheight=0.05)
- bt_about: tk.Button = self._win_ctrl_button[3]
- bt_about['text'] = 'About'
- bt_about['bg'] = '#DCDCDC'
- bt_about.place(relx=0.87, rely=rely, relwidth=0.05, relheight=0.05)
- bt_exit: tk.Button = self._win_ctrl_button[4]
- bt_exit['text'] = 'Exit'
- bt_exit['bg'] = '#DCDCDC'
- bt_exit['command'] = lambda: self.main_exit()
- bt_exit.place(relx=0.93, rely=rely, relwidth=0.05, relheight=0.05)
- def __conf_creak_menu(self):
- frame_list = [
- MainMenu(self, self._menu_back, '#fffffb')
- ]
- for i in frame_list:
- name, _ = i.get_menu_frame()
- self._menu_dict[name] = i
- def __conf_menu(self, n: int = 1):
- for i in self._menu_dict:
- menu = self._menu_dict[i]
- menu.conf_gui("#DCDCDC", n)
- def __conf_menu_title(self):
- self._menu_back['bg'] = "#fffffb"
- self._menu_back['bd'] = 5
- self._menu_back['relief'] = "ridge"
- title_font = self.make_font(size=self._menu_title_font_size, weight="bold")
- self._menu_title[0]['bg'] = '#fffffb'
- self._menu_title[0]['font'] = title_font
- self._menu_title[0]['textvariable'] = self._menu_title[1]
- self._menu_line['bg'] = '#000000'
- # 不立即显示
- def to_menu(self, name: str = "Main"):
- menu = self._menu_dict.get(name)
- if menu is None:
- ...
- name, frame = menu.get_menu_frame()
- self._menu_title[1].set(name)
- self._menu_back.place(relx=0.02, rely=0.02, relwidth=0.20, relheight=0.96)
- self._menu_line.place(relx=0.06, rely=0.065, relwidth=0.88, height=1) # 一个像素的高度即可
- self._menu_title[0].place(relx=0.02, rely=0.02, relwidth=0.96, relheight=0.03)
- frame.place(relx=0.02, rely=0.07, relwidth=0.96, relheight=0.84)
- self._menu_list.append(name)
- def __conf_program_title(self):
- self._program_back['bg'] = "#fffffb"
- self._program_back['relief'] = "ridge"
- self._program_back['bd'] = 5
- title_font = self.make_font(size=self._program_title_font_size, weight="bold")
- self._program_title[0]['bg'] = '#2468a2'
- self._program_title[0]['fg'] = "#F0F8FF"
- self._program_title[0]['font'] = title_font
- self._program_title[0]['anchor'] = 'w'
- self._program_title[0]['textvariable'] = self._program_title[1]
- # 不立即显示
- def __conf_creak_program(self):
- program_list = [
- WelcomeProgram(self, self._program_back, '#fffffb')
- ]
- for i in program_list:
- name, _ = i.get_program_frame()
- self._program_dict[name] = i
- def __conf_program(self, n: int = 1):
- for i in self._program_dict:
- program = self._program_dict[i]
- program.conf_gui(n)
- def to_program(self, name: str = "Welcome"):
- program = self._program_dict.get(name)
- if program is None:
- ...
- name, frame = program.get_program_frame()
- self.__show_program()
- self._program_title[1].set(f' {name}')
- self._program_title[0].place(relx=0.00, rely=0.00, relwidth=1, relheight=0.05)
- frame.place(relx=0.02, rely=0.12, relwidth=0.96, relheight=0.86)
- self._now_program = name, frame, program
- def __show_program(self):
- self._program_back.place(relx=0.26, rely=0.1, relwidth=0.68, relheight=0.84)
- def __hide_program(self):
- self._program_back.place_forget()
- def __conf_loading(self):
- self._loading_pro['mode'] = 'indeterminate'
- self._loading_pro['orient'] = tk.HORIZONTAL
- self._loading_pro['maximum'] = 50
- def show_loading(self, _):
- self._is_loading = True
- self.set_all_btn_disable()
- self._loading_pro['value'] = 0
- self._loading_pro.place(relx=0.30, rely=0.035, relwidth=0.35, relheight=0.03)
- self._loading_pro.start(50)
- def stop_loading(self):
- self._is_loading = False
- self._loading_pro.place_forget()
- self._loading_pro.stop()
- self.set_reset_all_btn()
- def __conf_msg(self):
- title_font = self.make_font(size=self._msg_font_size + 1, weight="bold")
- info_font = self.make_font(size=self._msg_font_size - 1)
- self._msg_frame['bg'] = "#fffffb"
- self._msg_frame['bd'] = 5
- self._msg_frame['relief'] = "ridge"
- # frame 不会立即显示
- self._msg_label[0]['font'] = title_font
- self._msg_label[0]['bg'] = "#fffffb"
- self._msg_label[0]['anchor'] = 'w'
- self._msg_label[0]['textvariable'] = self._msg_label[2]
- self._msg_label[1]['font'] = info_font
- self._msg_label[1]['bg'] = "#fffffb"
- self._msg_label[1]['anchor'] = 'nw'
- self._msg_label[1]['textvariable'] = self._msg_label[3]
- self._msg_label[1]['justify'] = 'left'
- self._msg_label[0].place(relx=0.05, rely=0.05, relwidth=0.9, relheight=0.1)
- self._msg_label[1].place(relx=0.075, rely=0.2, relwidth=0.85, relheight=0.58)
- self._msg_hide['font'] = info_font
- self._msg_hide['text'] = 'close'
- self._msg_hide['bg'] = "#DCDCDC"
- self._msg_hide['command'] = lambda: self.hide_msg()
- self._msg_hide.place(relx=0.375, rely=0.80, relwidth=0.25, relheight=0.13)
- def show_msg(self, title, info, msg_type='info'):
- assert not self._is_loading # loading 时不显示msg
- self.set_all_btn_disable()
- self._msg_label[2].set(f'{msg_type}: {title}')
- self._msg_label[3].set(f'{info}')
- frame_width = self._win_width * 0.50
- self._msg_label[1]['wraplength'] = frame_width * 0.85 - 5 # 设定自动换行的像素
- self._msg_frame.place(relx=0.30, rely=0.25, relwidth=0.55, relheight=0.50)
- self.__hide_program()
- def hide_msg(self):
- self.set_reset_all_btn()
- self._msg_frame.place_forget()
- self.__show_program()
- def set_all_btn_disable(self):
- for btn in self._win_ctrl_button[:-1]: # Exit 不设置disable
- btn['state'] = 'disable'
- if self._menu_list != 0:
- menu = self._menu_dict.get(self._menu_list[-1], None)
- assert menu is not None
- menu.set_disable()
- if self._now_program is not None:
- self._now_program[2].set_disable()
- def set_reset_all_btn(self):
- for btn in self._win_ctrl_button[:-1]:
- btn['state'] = 'normal'
- if self._menu_list != 0:
- menu = self._menu_dict.get(self._menu_list[-1], None)
- assert menu is not None
- menu.reset_disable()
- if self._now_program is not None:
- self._now_program[2].reset_disable()
- def __show_login_window(self):
- self.login_window: Optional[tk.Toplevel] = tk.Toplevel()
- self.login_window.title("HGSSystem Login")
- height = int(self._sys_height * (1 / 6))
- width = int(height * 2)
- if width > self._sys_width:
- width = int(self._sys_width * (2 / 3))
- height = int(width / 2)
- self.login_window.geometry(f'{width}x{height}')
- self.login_window['bg'] = "#d1d9e0"
- self.login_window.resizable(False, False)
- self.login_window.protocol("WM_DELETE_WINDOW", lambda: self.login_exit())
- self._login_name = [tk.Label(self.login_window), tk.Entry(self.login_window), tk.StringVar()]
- self._login_passwd = [tk.Label(self.login_window), tk.Entry(self.login_window), tk.StringVar()]
- self._login_btn = [tk.Button(self.login_window), tk.Button(self.login_window)]
- self.__conf_login_window()
- self.hide_main()
- def __conf_login_window(self):
- title_font = self.make_font(size=self._login_title_font_size, weight="bold")
- btn_font = self.make_font(size=self._login_btn_font_size, weight="bold")
- for lb, text in zip([self._login_name[0], self._login_passwd[0]], ["User:", "Passwd:"]):
- lb['bg'] = "#d1d9e0" # 蜜瓜绿
- lb['font'] = title_font
- lb['text'] = text
- lb['anchor'] = 'e'
- for lb, var in zip([self._login_name[1], self._login_passwd[1]], [self._login_name[2], self._login_passwd[2]]):
- lb['font'] = title_font
- lb['textvariable'] = var
- self._login_name[0].place(relx=0.00, rely=0.20, relwidth=0.35, relheight=0.15)
- self._login_passwd[0].place(relx=0.00, rely=0.40, relwidth=0.35, relheight=0.15)
- self._login_name[1].place(relx=0.40, rely=0.20, relwidth=0.45, relheight=0.15)
- self._login_passwd[1]['show'] = "*"
- self._login_passwd[1].place(relx=0.40, rely=0.40, relwidth=0.45, relheight=0.15)
- self._login_btn[0]['bg'] = "#a1afc9"
- self._login_btn[0]['font'] = btn_font
- self._login_btn[0]['text'] = 'Login'
- self._login_btn[0]['command'] = lambda: self.login_call()
- self._login_btn[0].place(relx=0.50, rely=0.70, relwidth=0.16, relheight=0.15)
- self._login_btn[1]['bg'] = "#a1afc9"
- self._login_btn[1]['font'] = btn_font
- self._login_btn[1]['text'] = 'Exit'
- self._login_btn[1]['command'] = lambda: self.login_exit()
- self._login_btn[1].place(relx=0.70, rely=0.70, relwidth=0.16, relheight=0.15)
- def login_call(self):
- event = LoginEvent(self).start(self._login_name[2].get(), self._login_passwd[2].get())
- self.push_event(event)
- def login(self, user: User):
- if super(AdminStation, self).login(user):
- self.login_window.destroy()
- self.login_window = None
- self.show_main()
- else:
- msg.showerror("Login error", "Please, try again")
- self._login_name[2].set('')
- self._login_passwd[2].set('')
- def login_exit(self):
- if not msg.askokcancel('Sure?', 'Exit manager system.'):
- return
- if self.login_window is not None:
- self.login_window.destroy()
- self.exit_win()
- def main_exit(self):
- if not msg.askokcancel('Sure?', 'Exit manager system.'):
- return
- self.exit_win()
- def hide_main(self):
- self._window.withdraw()
- def show_main(self):
- self._window.update()
- self._window.deiconify()
- @staticmethod
- def make_font(family: str = 'noto', **kwargs):
- return font.Font(family=conf.font_d[family], **kwargs)
- @staticmethod
- def set_button_disable_from_list(btn_list: List[tk.Button], flat: str = 'disable'):
- for btn in btn_list:
- btn['state'] = flat
- def mainloop(self):
- self._window.mainloop()
- def exit_win(self):
- self._window.destroy()
- class LoginEvent(AdminEventBase):
- def __init__(self, station: AdminStationBase):
- super().__init__(station, "Ranking")
- self.thread: Optional[TkThreading] = None
- def login(self, name, passwd):
- return find_user_by_name(name, passwd, self._db)
- def start(self, name, passwd):
- self.thread = TkThreading(self.login, name, passwd)
- return self
- def is_end(self) -> bool:
- return not self.thread.is_alive()
- def done_after_event(self):
- self.station.login(self.thread.wait_event())
- class TestProgressEvent(AdminEventBase):
- @staticmethod
- def func(sleep_time):
- time.sleep(sleep_time)
- def __init__(self, station, db):
- super(TestProgressEvent, self).__init__(station, db)
- self.thread = TkThreading(self.func, 5)
- def is_end(self) -> bool:
- return not self.thread.is_alive()
- def done_after_event(self):
- ...
- class AdminMenu(metaclass=abc.ABCMeta):
- def __init__(self, station: AdminStation, win: Union[tk.Frame, tk.Toplevel, tk.Tk], color: str):
- self.station = station
- self.win = win
- self.color = color
- @abc.abstractmethod
- def set_disable(self):
- ...
- @abc.abstractmethod
- def reset_disable(self):
- ...
- @abc.abstractmethod
- def conf_gui(self, color: str, n: int = 1):
- ...
- @abc.abstractmethod
- def get_menu_frame(self) -> Tuple[str, tk.Frame]:
- ...
- class AdminProgram(metaclass=abc.ABCMeta):
- def __init__(self, station: AdminStation, win: Union[tk.Frame, tk.Toplevel, tk.Tk], color: str):
- self.station = station
- self.win = win
- self.color = color
- @abc.abstractmethod
- def set_disable(self):
- ...
- @abc.abstractmethod
- def reset_disable(self):
- ...
- @abc.abstractmethod
- def conf_gui(self, n: int = 1):
- ...
- @abc.abstractmethod
- def get_program_frame(self) -> tk.Frame:
- ...
- class MainMenu(AdminMenu):
- def __init__(self, station, win, color):
- super(MainMenu, self).__init__(station, win, color)
- self.frame = tk.Frame(self.win)
- self.frame['bg'] = color
- self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(5)]
- self.__conf_font()
- def __conf_font(self, n: int = 1):
- self.btn_font_size = int(16 * n)
- def conf_gui(self, color: str, n: int = 1):
- self.__conf_font(n)
- btn_font = self.station.make_font(size=self.btn_font_size, weight="bold")
- height = 0.02
- for btn, text in zip(self.btn, ["Creat", "Delete", "Search", "Update", "Logout"]):
- btn['font'] = btn_font
- btn['text'] = text
- btn['bg'] = color
- btn.place(relx=0.02, rely=height, relwidth=0.96, relheight=0.1)
- height += 0.1 + 0.02
- def get_menu_frame(self) -> Tuple[str, tk.Frame]:
- return "Main", self.frame
- def set_disable(self):
- self.station.set_button_disable_from_list(self.btn)
- def reset_disable(self):
- self.station.set_button_disable_from_list(self.btn, flat='normal')
- class WelcomeProgram(AdminProgram):
- def __init__(self, station, win, color):
- super(WelcomeProgram, self).__init__(station, win, color)
- self.frame = tk.Frame(self.win)
- self.frame['bg'] = color
- self.title = tk.Label(self.frame)
- self.btn: List[tk.Button] = [tk.Button(self.frame) for _ in range(2)]
- self.__conf_font()
- def __conf_font(self, n: int = 1):
- self.title_font_size = int(25 * n)
- self.btn_font_size = int(14 * n)
- def conf_gui(self, n: int = 1):
- self.__conf_font(n)
- title_font = self.station.make_font(size=self.title_font_size, weight="bold")
- btn_font = self.station.make_font(size=self.btn_font_size)
- for btn, text in zip(self.btn, ["TestMSG", "TestProgress"]):
- btn['font'] = btn_font
- btn['text'] = text
- btn['bg'] = '#d3d7d4'
- self.title['text'] = 'Welcome to HGSSystem Manager'
- self.title['font'] = title_font
- self.title['bg'] = self.color
- self.btn[0]['command'] = lambda: self.test_msg()
- self.btn[1]['command'] = lambda: self.test_progress()
- self.title.place(relx=0.1, rely=0.3, relwidth=0.8, relheight=0.2)
- self.btn[0].place(relx=0.2, rely=0.7, relwidth=0.2, relheight=0.1)
- self.btn[1].place(relx=0.6, rely=0.7, relwidth=0.2, relheight=0.1)
- def test_progress(self):
- event = TestProgressEvent(self.station, "Sleep(5)")
- self.station.push_event(event)
- def test_msg(self):
- self.station.show_msg("Test Msg", "test msg")
- def get_program_frame(self) -> Tuple[str, tk.Frame]:
- return "Welcome", self.frame
- def set_disable(self):
- self.station.set_button_disable_from_list(self.btn)
- def reset_disable(self):
- self.station.set_button_disable_from_list(self.btn, flat='normal')
- if __name__ == '__main__':
- mysql_db = DB()
- station_ = AdminStation(mysql_db)
- station_.mainloop()
|