def __init__(self): self.app = Tk() self.app.maxsize(900, 700) self.app.minsize(900, 700) self.app.title('Passport Seva') font11 = "-family Calibri -size 15 -weight bold -slant roman " \ "-underline 0 -overstrike 0" self.v = StringVar() Label(self.app, text="Appointment Availability", font="Calibri 26", fg="blue").place(x=20, y=10) Label(self.app, text="Passport Office", font="Arial 18").place(x=20, y=100) city = [ 'Amritsar', 'Bhopal', 'Chandigarh', 'Chennai', 'Delhi', 'Goa', 'Hyderabad', 'Jaipur', 'Jammu', 'Kolkata', 'Lucknow', 'Mumbai', 'Ranchi', 'Shimla', 'Trivandrum', 'Visakhapatnam' ] TCombobox1 = Combobox(self.app, values=city, takefocus="", textvariable=self.v, font=font11) TCombobox1.configure(state="readonly") TCombobox1.place(x=200, y=100, relheight=0.051, relwidth=0.280) TCombobox1.bind("<<ComboboxSelected>>", self.fetch) self.app.mainloop()
class FilterSelectionFrame(LabelFrame): def __init__(self, parent, get_all, get_selection, set_selection): log.debug(f"creating {type(self).__name__}...") super().__init__(parent, text=" Filters ") self.parent = parent self.get_all = get_all self.get_selection = get_selection self.set_selection = set_selection Label(self, text="Country: ").grid(row=0, column=0, padx=PAD_X, pady=PAD_Y, sticky=EW) self.cb_country = Combobox(self, state="readonly", values=("All",), width=30) self.cb_country.bind("<<ComboboxSelected>>", self.apply_country_filter) self.cb_country.grid(row=0, column=1, padx=PAD_X, pady=PAD_Y, sticky=EW) self.cb_country.current(0) Label(self, text="Tournament: ").grid(row=0, column=2, padx=PAD_X, pady=PAD_Y, sticky=EW) self.cb_tournament = Combobox(self, state="readonly", values=("All",), width=50) self.cb_tournament.bind("<<ComboboxSelected>>", self.apply_tournament_filter) self.cb_tournament.current(0) self.cb_tournament.grid(row=0, column=3, padx=PAD_X, pady=PAD_Y, sticky=EW) Button(self, text="Reset", command=self.reset_filters).grid(row=0, column=4) def set_countries(self, countries): values = (ALL,) if countries: values += tuple(countries) self.cb_country.configure(values=values) def set_tournaments(self, tournaments): values = (ALL,) if tournaments: values += tuple(tournaments) self.cb_tournament.configure(values=values) def apply_country_filter(self, _): country = self.cb_country.get() selection = self.get_all() if country == ALL else self.get_selection().with_country(country) self.set_selection(selection) def apply_tournament_filter(self, _): tournament = self.cb_tournament.get() selection = self.get_all() if tournament == ALL else self.get_selection().with_tournament(tournament) self.set_selection(selection) def reset_filters(self): self.set_selection(self.get_all()) self.cb_country.current(0) self.cb_tournament.current(0)
class SerialPort(Frame): def __init__(self, parent, controller): Frame.__init__(self, parent, bg='white') Config.Readconfig() baudrateindex = self.find_index(Config.localserialconfig['baudrate'], Config.cbaudrates) if baudrateindex < 0: baudrateindex = 0 comportindex = self.find_index(Config.localserialconfig['comport'], get_serial_ports()) if comportindex < 0: comportindex = 0 self.tc_baudrate = StringVar() self.tc_baudrate = Combobox(self, textvariable=self.tc_baudrate) self.tc_baudrate['values'] = Config.cbaudrates self.tc_baudrate.current(baudrateindex) self.tc_baudrate.bind('<<ComboboxSelected>>', self.set_baudrate) self.tc_baudrate.configure(takefocus="") self.tc_baudrate.grid(row=1, column=0) self.tc_comports = StringVar() self.tc_comport = Combobox(self, textvariable=self.tc_comports) self.tc_comport['values'] = get_serial_ports() self.tc_comport.current(comportindex) self.tc_comport.bind('<<ComboboxSelected>>', self.set_comport) self.tc_comport.configure(takefocus="") self.tc_comport.grid(row=2, column=0) self.save = Button(self, text="save", command=Config.Close) self.save.grid(row=3, column=0) # print('baudrate: ', self.tc_baudrate['values']) # print('ports: ', get_serial_ports()) def set_baudrate(self, event): Config.localserialconfig["baudrate"] = self.tc_baudrate.get() # print('Set baudrate ', config.localserialconfig["baudrate"]) # print(config.localserialconfig) def set_comport(self, event): Config.localserialconfig["comport"] = self.tc_comports.get() # print('Set comport', config.localserialconfig["comport"]) # print(config.localserialconfig) def find_index(self, value, qlist): try: idx = qlist.index(value) except ValueError: idx = -1 # print('find_index: ', idx, ' Value: ', value, ' list: ', qlist) return idx
def import_iron_condor(self): self.imp_wd: Tk = Tk() self.imp_wd.title('Paper trading') window_width: int = self.imp_wd.winfo_reqwidth() window_height: int = self.imp_wd.winfo_reqheight() position_right: int = int(self.imp_wd.winfo_screenwidth() / 2 - window_width / 2) position_down: int = int(self.imp_wd.winfo_screenheight() / 2 - window_height / 2) self.imp_wd.geometry("600x300+300+200") bot_frame: Frame = Frame(self.imp_wd,width=800, height=300) bot_frame.pack(anchor='nw', fill='both',expand=True, side=TOP) bot_frame.pack_propagate(0) json_data = self.nse_adapter.get_oc_data() match_date = self.date_combo_box_stock.get() strike_prices: List[float] = [data['strikePrice'] for data in json_data['records']['data'] \ if (str(data['expiryDate']).lower() == str(match_date).lower())] self.imp_cbox: List[Combobox] = [] self.imp_tbox: List[tk.Text] = [] imp_vars: List[StringVar] = [] imp_lbls: List[Label] = [] imp_lbls_txt: List[Label] = ['buy PUT','sell PUT','sell CALL','buy CALL'] imp_lbls_color: List[Label] = ['green','red','red','green'] row_idx = 0 for i in enumerate(imp_lbls_txt): str_var = StringVar() str_var.set(' ') lbl: Label = Label(bot_frame,text=i[1],justify=LEFT,font=("TkDefaultFont", 10,"bold"),fg=imp_lbls_color[i[0]],width=20) lbl.grid(row=i[0],column=0,sticky=N+S+W) cb = Combobox(bot_frame,width=10,textvariable=str_var) cb.grid(row=i[0],column=1,sticky=N+S+W) cb.configure(state='readonly') cb['values'] = strike_prices self.imp_cbox.append(cb) txt = tk.Text(bot_frame,width=10,bg='yellow',height=2) txt.grid(row=i[0],column=2,sticky=N+S+W) self.imp_tbox.append(txt) row_idx = i[0]+1 ok_button: Button = tk.Button(bot_frame,text='OK!',command=self.export_iron_condor,width=20,bg='green',fg='white',font=("TkDefaultFont", 10, "bold")) ok_button.grid(row=row_idx,column=4,sticky=N+S+W) load_button: Button = tk.Button(bot_frame,text='Load',command=self.open_file,width=20,bg='green',fg='white',font=("TkDefaultFont", 10, "bold")) load_button.grid(row=row_idx+1,column=4,sticky=N+S+W)
class AConsumo: def __init__(self, master): self.master = master master.title("Adicionar Consumo") master.geometry("600x700") master.configure(background='green') #-----------------------------ITEMS---------------------------- Items = [] connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("Select * from listar_itens_comida") ra = curs.fetchall() i = 0 for item in ra: Items.append(item[0]) i + 1 curs.close() connection.close() #------------------------------------------------------------------ #-----------------------------Restaurante-------------------------- TRr = [] connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT * FROM public.listar_restaurantes") ra = curs.fetchall() i = 0 for item in ra: TRr.append(item[0]) i + 1 curs.close() connection.close() #----------------------------------------------------------------- #-----------------------------Clientes---------------------------- Clientess = [] connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT * FROM public.listar_restaurantes") ra = curs.fetchall() i = 0 for item in ra: Clientess.append(item[0]) i + 1 curs.close() connection.close() #------------------------------------------------------------------ #-----------------------------Clientes----------------------------- Clientess = [] connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT nif FROM public.listar_clientes;") ra = curs.fetchall() i = 0 for item in ra: Clientess.append(item[0]) i + 1 curs.close() connection.close() #------------------------------------------------------------------ self.labelR = Label(master, text="Restaurante", height=1, width=600) self.labelR.pack() self.labelR.configure(background='green') self.comboRest = Combobox(master, values=TRr, width=600) self.comboRest.pack() self.comboRest.bind('<<ComboboxSelected>>', self.comboRest.get()) self.labelR = Label(master, text="Funcionario : ", height=1, width=600) self.labelR.pack() self.labelR.configure(background='green') self.comboDS = Combobox(master, width=600) self.comboDS.pack() self.comboDS.bind('<<ComboboxSelected>>', self.comboDS.get()) self.labelR = Label(master, text="Cliente :", height=1, width=600) self.labelR.pack() self.labelR.configure(background='green') self.comboA = Combobox(master, values=Clientess, width=600) self.comboA.pack() self.comboA.bind('<<ComboboxSelected>>', self.comboA.get()) self.labelR = Label(master, text="", height=2, width=600) self.labelR.pack() self.labelR.configure(background='green') self.btnlogin = Button(master, text="Refresh local de consumo e empregado ", command=lambda: self.refresh(), height=1, width=100) self.btnlogin.pack() self.labeli = Label(master, text="Local consumo:", height=2, width=600) self.labeli.pack() self.labeli.configure(background='green') self.Lconsumo = Combobox(master, width=600) self.Lconsumo.pack() self.Lconsumo.bind('<<ComboboxSelected>>', self.Lconsumo.get()) self.labeli = Label(master, text="Items:", height=2, width=600) self.labeli.pack() self.labeli.configure(background='green') self.Items = Combobox(master, values=Items, width=600) self.Items.pack() self.Items.bind('<<ComboboxSelected>>', self.comboA.get()) self.btnlogin = Button(master, text="Adicionar Ementa", command=lambda: self.Inserts(), height=1, width=100) self.btnlogin.pack() self.btnlogin = Button(master, text="Voltar", command=lambda: self.new_window4(), height=1, width=100) self.btnlogin.pack() def refresh(self): connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() a = [] b = [] curs.execute("SELECT public.listar_l_consumo('" + str(self.IdRest()) + "')") resta = curs.fetchall() i = 0 for item in resta: a.append(item[0]) i + 1 curs.execute("SELECT public.mostrar_funcionarios_restaurante('" + str(self.IdRest()) + "')") resta = curs.fetchall() i = 0 for item in resta: b.append(item[0]) i + 1 curs.close() connection.close() self.Lconsumo.configure(value=a) self.comboDS.configure(value=b) def new_window4(self): self.master.destroy() self.master = tk.Tk() self.app = Index_Ger_V.IndexGer(self.master) self.master.mainloop() def IdRest(self): connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT public.saber_id_restaurante('" + self.comboRest.get() + "')") resta = curs.fetchall() val = 0 i = 0 for item in resta: val = item[0] i + 1 curs.close() connection.close() return val def idItens(self): connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT saber_id_item_nome('" + self.Items.get() + "')") resta = curs.fetchall() val = 0 i = 0 for item in resta: val = item[0] i + 1 curs.close() connection.close() return val def idCliente(self): connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT public.saber_id_cliente('" + self.comboA.get() + "')") resta = curs.fetchall() val = 0 i = 0 for item in resta: val = item[0] i + 1 curs.close() connection.close() return val def idFuncionario(self): connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT public.saber_id_funcuinario('" + self.comboDS.get() + "')") resta = curs.fetchall() val = 0 i = 0 for item in resta: val = item[0] i + 1 curs.close() connection.close() return val def idConsumo(self): connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT max FROM public.saber_id_consumo;") resta = curs.fetchall() val = 0 i = 0 for item in resta: val = item[0] i + 1 curs.close() connection.close() return val def idLocalConsumo(self): connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("SELECT public.saber_id_l_consumo('" + self.Lconsumo.get() + "'," + str(self.IdRest()) + ")") resta = curs.fetchall() val = 0 i = 0 for item in resta: val = item[0] i + 1 curs.close() connection.close() return val def Inserts(self): connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("CALL public.insertconsumo(" + str(self.idLocalConsumo()) + "," + str(self.idFuncionario()) + "," + str(self.idCliente()) + ")") connection.commit() curs.close() connection.close() connection = psycopg2.connect(user="******", password="******", host="127.0.0.1", port="5432", database="RandR") curs = connection.cursor() curs.execute("CALL public.insertconsumo_itens(" + str(self.idConsumo()) + "," + str(self.idItens()) + ")") connection.commit() curs.close() connection.close()
class _full_combo: def __init__(self, master): grid_frame = Frame( master ) self.grid_frame = grid_frame grid_frame.pack(expand=1, fill=BOTH) self.master = master self.x, self.y, self.w, self.h = 10, 10, 519, 326 self.master.title("full_combo") self.RadioGroup_1_StringVar = StringVar() self.make_Button_1( self.grid_frame ) # Button: at Main(1,1) self.make_Notebook_1( self.grid_frame ) # Notebook: at Main(1,2) self.make_Tab_1( self.Notebook_1 ) # Tab: Small : at Notebook_1(1,1) self.make_Tab_2( self.Notebook_1 ) # Tab: Medium : at Notebook_1(1,2) self.make_Tab_3( self.Notebook_1 ) # Tab: Large : at Notebook_1(1,3) self.make_Canvas_1( self.Tab_1 ) # Canvas: at Tab_1(1,3) self.make_Frame_1( self.Tab_1 ) # Frame: at Tab_1(1,2) self.make_Checkbutton_2( self.Frame_1 ) # Checkbutton: at Frame_1(1,1) self.make_Combobox_2( self.Frame_1 ) # Combobox: Mine Yours Ours : at Frame_1(2,1) self.make_Entry_2( self.Frame_1 ) # Entry: at Frame_1(3,1) self.make_LabelFrame_1( self.Tab_2 ) # LabelFrame: Left : at Tab_2(1,1) self.make_LabelFrame_2( self.Tab_2 ) # LabelFrame: Right : at Tab_2(1,2) self.make_Listbox_1( self.LabelFrame_1 ) # Listbox: at LabelFrame_1(1,1) self.make_Message_1( self.LabelFrame_1 ) # Message: at LabelFrame_1(2,1) self.make_Menubutton_1( self.LabelFrame_2 ) # Menubutton: at LabelFrame_2(1,1) self.make_Notebook_2( self.LabelFrame_2 ) # Notebook: at LabelFrame_2(2,1) self.make_Tab_4( self.Notebook_2 ) # Tab: at Notebook_2(1,1) self.make_Tab_5( self.Notebook_2 ) # Tab: at Notebook_2(1,2) self.make_RadioGroup_1( self.Tab_4 ) # RadioGroup: at Tab_4(1,1) self.make_Radiobutton_1( self.RadioGroup_1 ) # Radiobutton: 1 : at RadioGroup_1(2,1) self.make_Radiobutton_2( self.RadioGroup_1 ) # Radiobutton: 2 : at RadioGroup_1(3,1) self.make_Radiobutton_3( self.RadioGroup_1 ) # Radiobutton: 3 : at RadioGroup_1(4,1) self.make_Radiobutton_4( self.RadioGroup_1 ) # Radiobutton: 4 : at RadioGroup_1(5,1) self.make_Scale_1( self.Tab_5 ) # Scale: 2.5 to 7.5 : at Tab_5(2,1) self.make_Spinbox_1( self.Tab_5 ) # Spinbox: 1 to 10 : at Tab_5(3,1) self.make_Button_2( self.Tab_3 ) # Button: at Tab_3(3,1) self.make_Text_1( self.Tab_3 ) # Text: at Tab_3(2,1) self.make_Treeview_1( self.Tab_3 ) # Treeview: at Tab_3(2,2) self.grid_frame.rowconfigure(1, weight=1) self.Tab_1.rowconfigure(1, weight=1) self.Tab_2.rowconfigure(1, weight=1) self.LabelFrame_1.columnconfigure(1, weight=1) self.grid_frame.columnconfigure(2, weight=1) self.Tab_2.columnconfigure(2, weight=1) self.Tab_1.columnconfigure(3, weight=1) self.Tab_2.columnconfigure(1, weight=1) self.RadioGroup_1_StringVar.set("1") self.RadioGroup_1_StringVar_traceName = self.RadioGroup_1_StringVar.trace_variable("w", self.RadioGroup_1_StringVar_Callback) # >>>>>>insert any user code below this comment for section "top_of_init" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Button_1" def make_Button_1(self, frame): """ Button: at Main(1,1)""" self.Button_1 = Button( frame , text="Button_1", width="15", anchor="e") self.Button_1.grid(row=1, column=1, sticky="s") # >>>>>>insert any user code below this comment for section "make_Button_1" self.Button_1.bind("<ButtonRelease-1>", self.Button_1_Click) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Notebook_1" def make_Notebook_1(self, frame): """ Notebook: at Main(1,2)""" self.Notebook_1 = Notebook ( frame , width="400", height="300") self.Notebook_1.grid(row=1, column=2, sticky="nsew") # >>>>>>insert any user code below this comment for section "make_Notebook_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_1" def make_Tab_1(self, frame): """ Tab: Small : at Notebook_1(1,1)""" self.Tab_1 = Frame( frame ) self.Notebook_1.add( self.Tab_1, text="Small" ) # >>>>>>insert any user code below this comment for section "make_Tab_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_2" def make_Tab_2(self, frame): """ Tab: Medium : at Notebook_1(1,2)""" self.Tab_2 = Frame( frame ) self.Notebook_1.add( self.Tab_2, text="Medium" ) # >>>>>>insert any user code below this comment for section "make_Tab_2" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_3" def make_Tab_3(self, frame): """ Tab: Large : at Notebook_1(1,3)""" self.Tab_3 = Frame( frame ) self.Notebook_1.add( self.Tab_3, text="Large" ) # >>>>>>insert any user code below this comment for section "make_Tab_3" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Canvas_1" def make_Canvas_1(self, frame): """ Canvas: at Tab_1(1,3)""" self.Canvas_1 = Canvas( frame , height="50", width="60") self.Canvas_1.grid(row=1, column=3, sticky="nsew") # >>>>>>insert any user code below this comment for section "make_Canvas_1" self.Canvas_1.config(bg='#ffffcc') self.Canvas_1.bind("<ButtonRelease-1>", self.Canvas_1_Click) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Frame_1" def make_Frame_1(self, frame): """ Frame: at Tab_1(1,2)""" self.Frame_1 = Frame( frame , width="60", height="50") self.Frame_1.grid(row=1, column=2, sticky="n") # >>>>>>insert any user code below this comment for section "make_Frame_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Checkbutton_2" def make_Checkbutton_2(self, frame): """ Checkbutton: at Frame_1(1,1)""" self.Checkbutton_2 = Checkbutton( frame , text="Checkbutton_2", width="15", anchor="e") self.Checkbutton_2.grid(row=1, column=1) self.Checkbutton_2_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Checkbutton_2" self.Checkbutton_2.configure(variable=self.Checkbutton_2_StringVar, onvalue="yes", offvalue="no") self.Checkbutton_2_StringVar.set("no") self.Checkbutton_2_StringVar_traceName = self.Checkbutton_2_StringVar.trace_variable("w", self.Checkbutton_2_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_2" def make_Combobox_2(self, frame): """ Combobox: Mine Yours Ours : at Frame_1(2,1)""" self.Combobox_2 = Combobox( frame , text="Combobox_2", values="Mine Yours Ours") self.Combobox_2.grid(row=2, column=1) self.Combobox_2_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Combobox_2" self.Combobox_2.configure(textvariable=self.Combobox_2_StringVar) self.Combobox_2_StringVar.set( "Mine" ) self.Combobox_2_StringVar_traceName = self.Combobox_2_StringVar.trace_variable("w", self.Combobox_2_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Entry_2" def make_Entry_2(self, frame): """ Entry: at Frame_1(3,1)""" self.Entry_2 = Entry( frame , width="15") self.Entry_2.grid(row=3, column=1) self.Entry_2_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Entry_2" self.Entry_2.configure(textvariable=self.Entry_2_StringVar) self.Entry_2_StringVar_traceName = self.Entry_2_StringVar.trace_variable("w", self.Entry_2_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_LabelFrame_1" def make_LabelFrame_1(self, frame): """ LabelFrame: Left : at Tab_2(1,1)""" self.LabelFrame_1 = LabelFrame( frame , text="Left", width="60", height="50") self.LabelFrame_1.grid(row=1, column=1, sticky="nsew") # >>>>>>insert any user code below this comment for section "make_LabelFrame_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_LabelFrame_2" def make_LabelFrame_2(self, frame): """ LabelFrame: Right : at Tab_2(1,2)""" self.LabelFrame_2 = LabelFrame( frame , text="Right", width="60", height="50") self.LabelFrame_2.grid(row=1, column=2, sticky="nsew") # >>>>>>insert any user code below this comment for section "make_LabelFrame_2" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Listbox_1" def make_Listbox_1(self, frame): """ Listbox: at LabelFrame_1(1,1)""" self.Listbox_1 = Listbox( frame , height="12", width="30") self.Listbox_1.grid(row=1, column=1) # >>>>>>insert any user code below this comment for section "make_Listbox_1" # Edit the Listbox Entries self.Listbox_1.insert(END, "apples") self.Listbox_1.insert(END, "oranges") self.Listbox_1.insert(END, "grapes") self.Listbox_1.bind("<ButtonRelease-1>", self.Listbox_1_Click) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Message_1" def make_Message_1(self, frame): """ Message: at LabelFrame_1(2,1)""" self.Message_1 = Message( frame , text="Message_1", width="55", anchor="e") self.Message_1.grid(row=2, column=1, sticky="ew") # >>>>>>insert any user code below this comment for section "make_Message_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Menubutton_1" def make_Menubutton_1(self, frame): """ Menubutton: at LabelFrame_2(1,1)""" self.Menubutton_1 = Menubutton( frame , text="Menubutton_1", width="15", anchor="e") self.Menubutton_1.grid(row=1, column=1) self.Menubutton_1_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Menubutton_1" self.Menubutton_1.configure(textvariable=self.Menubutton_1_StringVar, text="Select") self.Menubutton_1_StringVar.set("Select") self.Menubutton_1_StringVar_traceName = self.Menubutton_1_StringVar.trace_variable("w", self.Menubutton_1_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Notebook_2" def make_Notebook_2(self, frame): """ Notebook: at LabelFrame_2(2,1)""" self.Notebook_2 = Notebook ( frame , width="400", height="300") self.Notebook_2.grid(row=2, column=1) # >>>>>>insert any user code below this comment for section "make_Notebook_2" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_4" def make_Tab_4(self, frame): """ Tab: at Notebook_2(1,1)""" self.Tab_4 = Frame( frame ) self.Notebook_2.add( self.Tab_4, text="Tab_4" ) # >>>>>>insert any user code below this comment for section "make_Tab_4" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Tab_5" def make_Tab_5(self, frame): """ Tab: at Notebook_2(1,2)""" self.Tab_5 = Frame( frame ) self.Notebook_2.add( self.Tab_5, text="Tab_5" ) # >>>>>>insert any user code below this comment for section "make_Tab_5" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_RadioGroup_1" def make_RadioGroup_1(self, frame): """ RadioGroup: at Tab_4(1,1)""" self.RadioGroup_1 = LabelFrame( frame , width="60", height="50") self.RadioGroup_1.grid(row=1, column=1) # >>>>>>insert any user code below this comment for section "make_RadioGroup_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_1" def make_Radiobutton_1(self, frame): """ Radiobutton: 1 : at RadioGroup_1(2,1)""" self.Radiobutton_1 = Radiobutton( frame , text="Radiobutton_1", value="1", width="15", anchor="e") self.Radiobutton_1.grid(row=2, column=1) # >>>>>>insert any user code below this comment for section "make_Radiobutton_1" self.Radiobutton_1.configure(variable=self.RadioGroup_1_StringVar) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_2" def make_Radiobutton_2(self, frame): """ Radiobutton: 2 : at RadioGroup_1(3,1)""" self.Radiobutton_2 = Radiobutton( frame , text="Radiobutton_2", value="2", width="15") self.Radiobutton_2.grid(row=3, column=1) # >>>>>>insert any user code below this comment for section "make_Radiobutton_2" self.Radiobutton_2.configure(variable=self.RadioGroup_1_StringVar) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_3" def make_Radiobutton_3(self, frame): """ Radiobutton: 3 : at RadioGroup_1(4,1)""" self.Radiobutton_3 = Radiobutton( frame , text="Radiobutton_3", value="3", width="15") self.Radiobutton_3.grid(row=4, column=1) # >>>>>>insert any user code below this comment for section "make_Radiobutton_3" self.Radiobutton_3.configure(variable=self.RadioGroup_1_StringVar) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Radiobutton_4" def make_Radiobutton_4(self, frame): """ Radiobutton: 4 : at RadioGroup_1(5,1)""" self.Radiobutton_4 = Radiobutton( frame , text="Radiobutton_4", value="4", width="15") self.Radiobutton_4.grid(row=5, column=1) # >>>>>>insert any user code below this comment for section "make_Radiobutton_4" self.Radiobutton_4.configure(variable=self.RadioGroup_1_StringVar) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Scale_1" def make_Scale_1(self, frame): """ Scale: 2.5 to 7.5 : at Tab_5(2,1)""" self.Scale_1 = Scale( frame , digits="3", tickinterval="1", to="7.5", from_="2.5", resolution=".5") self.Scale_1.grid(row=2, column=1) self.Scale_1_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Scale_1" self.Scale_1.configure(variable=self.Scale_1_StringVar) self.Scale_1_StringVar_traceName = self.Scale_1_StringVar.trace_variable("w", self.Scale_1_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Spinbox_1" def make_Spinbox_1(self, frame): """ Spinbox: 1 to 10 : at Tab_5(3,1)""" self.Spinbox_1 = Spinbox( frame , to="10", text="Spinbox_1", width="15", from_="1") self.Spinbox_1.grid(row=3, column=1) self.Spinbox_1_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Spinbox_1" self.Spinbox_1.configure(textvariable=self.Spinbox_1_StringVar, to="10", from_="1") self.Spinbox_1_StringVar.set("1") self.Spinbox_1_StringVar_traceName = self.Spinbox_1_StringVar.trace_variable("w", self.Spinbox_1_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Button_2" def make_Button_2(self, frame): """ Button: at Tab_3(3,1)""" self.Button_2 = Button( frame , text="Button_2", width="15") self.Button_2.grid(row=3, column=1) # >>>>>>insert any user code below this comment for section "make_Button_2" self.Button_2.bind("<ButtonRelease-1>", self.Button_2_Click) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Text_1" def make_Text_1(self, frame): """ Text: at Tab_3(2,1)""" lbframe = Frame( frame ) self.Text_1_frame = lbframe vbar=Scrollbar(lbframe, orient=VERTICAL) self.Text_1 = Text(lbframe, width="40", height="12", yscrollcommand=vbar.set) vbar.config(command=self.Text_1.yview) vbar.grid(row=0, column=1, sticky='ns') self.Text_1.grid(row=0, column=0) self.Text_1_frame.grid(row=2, column=1) # >>>>>>insert any user code below this comment for section "make_Text_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Treeview_1" def make_Treeview_1(self, frame): """ Treeview: at Tab_3(2,2)""" self.Treeview_1 = Treeview( frame ) self.Treeview_1.grid(row=2, column=2) # >>>>>>insert any user code below this comment for section "make_Treeview_1" self.Treeview_1.insert('', 'end', 'widgets', text='Widget Tour') # Same thing, but inserted as first child: self.Treeview_1.insert('', 0, 'gallery', text='Treeview_1') # Inserted underneath an existing node: self.Treeview_1.insert('widgets', 'end', text='Button') self.Treeview_1.insert('widgets', 'end', text='Canvas') self.Treeview_1.insert('widgets', 'end', text='Checkbutton') self.Treeview_1.insert('widgets', 'end', text='Combobox') self.Treeview_1.insert('widgets', 'end', text='Entry') self.Treeview_1.insert('widgets', 'end', text='Frame') self.Treeview_1.insert('widgets', 'end', text='Label') self.Treeview_1.insert('widgets', 'end', text='LabelFrame') self.Treeview_1.insert('widgets', 'end', text='Listbox') self.Treeview_1.insert('widgets', 'end', text='Menubutton') self.Treeview_1.insert('widgets', 'end', text='Message') self.Treeview_1.insert('widgets', 'end', text='Notebook') self.Treeview_1.insert('widgets', 'end', text='OptionMenu') self.Treeview_1.insert('widgets', 'end', text='Progressbar') self.Treeview_1.insert('widgets', 'end', text='RadioGroup') self.Treeview_1.insert('widgets', 'end', text='Radiobutton') self.Treeview_1.insert('widgets', 'end', text='Scale') self.Treeview_1.insert('widgets', 'end', text='Separator') self.Treeview_1.insert('widgets', 'end', text='Spinbox') self.Treeview_1.insert('widgets', 'end', text='Tab') self.Treeview_1.insert('widgets', 'end', text='Text') self.Treeview_1.insert('widgets', 'end', text='Treeview') # Treeview chooses the id: id = self.Treeview_1.insert('', 'end', text='Tutorial') self.Treeview_1.insert(id, 'end', text='Tree') self.Treeview_1.bind("<ButtonRelease-1>", self.Treeview_1_Click) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Button_1_Click" def Button_1_Click(self, event): #bind method for component ID=Button_1 """ Button: at Main(1,1)""" pass # >>>>>>insert any user code below this comment for section "Button_1_Click" # replace, delete, or comment-out the following print( "executed method Button_1_Click" ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Canvas_1_Click" def Canvas_1_Click(self, event): #bind method for component ID=Canvas_1 """ Canvas: at Tab_1(1,3)""" pass # >>>>>>insert any user code below this comment for section "Canvas_1_Click" # replace, delete, or comment-out the following print( "executed method Canvas_1_Click" ) print( "clicked in canvas at x,y =",event.x,event.y ) w = int(self.Canvas_1.cget("width")) h = int(self.Canvas_1.cget("height")) self.Canvas_1.create_rectangle((2, 2, w+1, h+1), outline="blue") self.Canvas_1.create_line(0, 0, w+2, h+2, fill="red") x = int(event.x) y = int(event.y) print( "event x,y=",x,y ) self.Canvas_1.create_text(x,y, text="NE", fill="green", anchor=NE) self.Canvas_1.create_text(x,y, text="SW", fill="magenta", anchor=SW) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Listbox_1_Click" def Listbox_1_Click(self, event): #bind method for component ID=Listbox_1 """ Listbox: at LabelFrame_1(1,1)""" pass # >>>>>>insert any user code below this comment for section "Listbox_1_Click" # replace, delete, or comment-out the following print( "executed method Listbox_1_Click" ) print( "current selection(s) =",self.Listbox_1.curselection() ) labelL = [] for i in self.Listbox_1.curselection(): labelL.append( self.Listbox_1.get(i)) print( "current label(s) =",labelL ) # use self.Listbox_1.insert(0, "item zero") # self.Listbox_1.insert(index, "item i") # OR # self.Listbox_1.insert(END, "item end") # to insert items into the list box # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Button_2_Click" def Button_2_Click(self, event): #bind method for component ID=Button_2 """ Button: at Tab_3(3,1)""" pass # >>>>>>insert any user code below this comment for section "Button_2_Click" # replace, delete, or comment-out the following print( "executed method Button_2_Click" ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Treeview_1_Click" def Treeview_1_Click(self, event): #bind method for component ID=Treeview_1 """ Treeview: at Tab_3(2,2)""" pass # >>>>>>insert any user code below this comment for section "Treeview_1_Click" # replace, delete, or comment-out the following print( "executed method Treeview_1_Click" ) curItem = self.Treeview_1.focus() print( "current Treeview item(s) =",self.Treeview_1.item( curItem ) ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Checkbutton_2_StringVar_traceName" def Checkbutton_2_StringVar_Callback(self, varName, index, mode): """ Checkbutton: at Frame_1(1,1)""" pass # >>>>>>insert any user code below this comment for section "Checkbutton_2_StringVar_traceName" # replace, delete, or comment-out the following print( "Checkbutton_2_StringVar_Callback varName, index, mode",varName, index, mode ) print( " new StringVar value =",self.Checkbutton_2_StringVar.get() ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_2_StringVar_traceName" def Combobox_2_StringVar_Callback(self, varName, index, mode): """ Combobox: Mine Yours Ours : at Frame_1(2,1)""" pass # >>>>>>insert any user code below this comment for section "Combobox_2_StringVar_traceName" # replace, delete, or comment-out the following print( "Combobox_2_StringVar_Callback varName, index, mode",varName, index, mode ) print( " new StringVar value =",self.Combobox_2_StringVar.get() ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Entry_2_StringVar_traceName" def Entry_2_StringVar_Callback(self, varName, index, mode): """ Entry: at Frame_1(3,1)""" pass # >>>>>>insert any user code below this comment for section "Entry_2_StringVar_traceName" # replace, delete, or comment-out the following print( "Entry_2_StringVar_Callback varName, index, mode",varName, index, mode ) print( " new StringVar value =",self.Entry_2_StringVar.get() ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Menubutton_1_StringVar_traceName" def Menubutton_1_StringVar_Callback(self, varName, index, mode): """ Menubutton: at LabelFrame_2(1,1)""" pass # >>>>>>insert any user code below this comment for section "Menubutton_1_StringVar_traceName" # replace, delete, or comment-out the following print( "Menubutton_1_StringVar_Callback varName, index, mode",varName, index, mode ) print( " new StringVar value =",self.Menubutton_1_StringVar.get() ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Scale_1_StringVar_traceName" def Scale_1_StringVar_Callback(self, varName, index, mode): """ Scale: 2.5 to 7.5 : at Tab_5(2,1)""" pass # >>>>>>insert any user code below this comment for section "Scale_1_StringVar_traceName" # replace, delete, or comment-out the following print( "Scale_1_StringVar_Callback varName, index, mode",varName, index, mode ) print( " new StringVar value =",self.Scale_1_StringVar.get() ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Spinbox_1_StringVar_traceName" def Spinbox_1_StringVar_Callback(self, varName, index, mode): """ Spinbox: 1 to 10 : at Tab_5(3,1)""" pass # >>>>>>insert any user code below this comment for section "Spinbox_1_StringVar_traceName" # replace, delete, or comment-out the following print( "Spinbox_1_StringVar_Callback varName, index, mode",varName, index, mode ) print( " new StringVar value =",self.Spinbox_1_StringVar.get() ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "RadioGroup_1_StringVar_traceName" def RadioGroup_1_StringVar_Callback(self, varName, index, mode): """ RadioGroup: at Tab_4(1,1)""" pass # >>>>>>insert any user code below this comment for section "RadioGroup_1_StringVar_traceName" # replace, delete, or comment-out the following print( "RadioGroup_1_StringVar_Callback varName, index, mode",varName, index, mode ) print( " new StringVar value =",self.RadioGroup_1_StringVar.get() )
class SearchFrame: def __init__(self, parent): self.parent = parent self.topFrame = Frame(self.parent.windowFrame, relief=GROOVE, highlightbackground="grey", highlightcolor="grey", highlightthickness=1) self.middleFrame = Frame(self.parent.windowFrame, relief=GROOVE, highlightbackground="grey", highlightcolor="grey", highlightthickness=1) self.bottomFrame = Frame(self.parent.windowFrame, relief=GROOVE, highlightbackground="grey", highlightcolor="grey", highlightthickness=1) self.bottomestFrame = Frame(self.parent.windowFrame) self.site = StringVar() self.currentTeam = StringVar() self.filterFrame = Frame(self.topFrame) self.appliedFilterFrame = Frame(self.topFrame) self.appliedFilterButtonFrame = Frame(self.topFrame) self.selectedStreamsFrame = Frame(self.middleFrame) self.streamButtonFrame = Frame(self.middleFrame) self.urlFrame = Frame(self.bottomFrame) self.streamStartButtonFrame = Frame(self.bottomestFrame) self.comboboxTeam = None self.buttonTeam = None self.comboboxTag = None self.buttonTag = None self.appliedFiltersListbox = None self.buttonRemove = None self.buttonReset = None self.selectedStreamsListbox = None self.buttonClearAllStreams = None self.buttonRemoveSelectedStreams = None self.siteDropdown = None self.buttonOk = None self.gridFrames() self.populateFilterFrame() self.populateAppliedFilterFrame() self.populateButtonFrame() self.populateSelectedStreamsFrame() self.populateStreamButtonFrame() self.populateUrlFrame() self.populateStreamStartButtonFrame() def gridFrames(self): self.filterFrame.grid(row=0, sticky=NSEW) self.appliedFilterFrame.grid(row=1, sticky=NSEW) self.appliedFilterButtonFrame.grid(row=2, sticky=NSEW) self.selectedStreamsFrame.grid(row=0, sticky=NSEW) self.streamButtonFrame.grid(row=1, sticky=NSEW) self.urlFrame.grid(row=0, sticky=NSEW) self.streamStartButtonFrame.grid(row=0, sticky=NSEW) def populateFilterFrame(self): labelFilters = Label(self.filterFrame, text=LabelConstants.FILTERS) labelFilters.grid(row=0, column=0, sticky=W, columnspan=2, padx=4, pady=4) labelTeam = Label(self.filterFrame, text=LabelConstants.SEARCH_TEAMS) labelTeam.grid(row=1, column=0, sticky=W, columnspan=2, padx=4, pady=4) self.comboboxTeam = Combobox(self.filterFrame, textvariable=self.currentTeam, values=list(self.parent.teams.keys()), state="readonly", width=32) self.comboboxTeam.current(0) self.comboboxTeam.grid(row=2, column=0, columnspan=2, padx=4, pady=4) def populateAppliedFilterFrame(self): labelAppliedFilters = Label(self.appliedFilterFrame, text=LabelConstants.SEARCH_TAG) labelAppliedFilters.grid(row=0, column=0, sticky=W, columnspan=2, padx=4, pady=4) scrollbarAppliedFilters = Scrollbar(self.appliedFilterFrame) scrollbarAppliedFilters.grid(row=1, column=1, sticky="NWS") self.appliedFiltersListbox = Listbox(self.appliedFilterFrame, selectmode=MULTIPLE, yscrollcommand=scrollbarAppliedFilters.set, activestyle=NONE, width=33) scrollbarAppliedFilters.config(command=self.appliedFiltersListbox.yview) self.populateTwitchTagsListbox() self.appliedFiltersListbox.grid(row=1, column=0, sticky=NSEW, padx=(4, 0)) self.appliedFiltersListbox.configure(exportselection=False) def populateTwitchTagsListbox(self): self.appliedFiltersListbox.delete(0, END) activeTags = [tag for tag in self.parent.tags if tag.isActive] for tag in list(map(lambda x: x.localizationNames['en-us'], activeTags)): self.appliedFiltersListbox.insert(END, tag) def populateButtonFrame(self): self.buttonRemove = Button(self.appliedFilterButtonFrame, text=LabelConstants.RESET, width=10, command=lambda: self.clearAllTags()) self.buttonRemove.grid(row=0, column=0, sticky=NSEW, padx=4, pady=4) self.buttonReset = Button(self.appliedFilterButtonFrame, text=LabelConstants.REFRESH_STREAMS, width=16, command=lambda: self.parent.scrollableFrame.refresh()) self.buttonReset.grid(row=0, column=1, sticky=NSEW, padx=4, pady=4) def populateSelectedStreamsFrame(self): labelSelectedStreamsFrame = Label(self.selectedStreamsFrame, text=LabelConstants.SELECTED_STREAMS) labelSelectedStreamsFrame.grid(row=0, column=0, sticky=W, columnspan=2, padx=4, pady=4) scrollbarSelectedStreams = Scrollbar(self.selectedStreamsFrame) scrollbarSelectedStreams.grid(row=1, column=1, sticky="NWS") self.selectedStreamsListbox = Listbox(self.selectedStreamsFrame, selectmode=MULTIPLE, yscrollcommand=scrollbarSelectedStreams.set, activestyle=NONE, width=33) scrollbarSelectedStreams.config(command=self.selectedStreamsListbox.yview) self.selectedStreamsListbox.grid(row=1, column=0, sticky=NSEW, padx=(4, 0)) self.selectedStreamsListbox.configure(exportselection=False) def populateStreamButtonFrame(self): self.buttonClearAllStreams = Button(self.streamButtonFrame, text=LabelConstants.RESET, width=10, command=lambda: self.resetStreams()) self.buttonClearAllStreams.grid(row=0, column=0, sticky=NSEW, padx=4, pady=4) self.buttonRemoveSelectedStreams = Button(self.streamButtonFrame, text=LabelConstants.REMOVE, width=16, command=lambda: self.removeStreams()) self.buttonRemoveSelectedStreams.grid(row=0, column=1, sticky=NSEW, padx=4, pady=4) def populateUrlFrame(self): labelSiteDropdown = Label(self.urlFrame, text=LabelConstants.STREAM_DROPDOWN) labelSiteDropdown.grid(row=0, column=0, sticky=W, padx=4, pady=4) self.siteDropdown = Combobox(self.urlFrame, textvariable=self.site, state="readonly", values=list(URLConstants.ORDERED_STREAMING_SITES.keys()), width=32) self.siteDropdown.bind("<<ComboboxSelected>>", self.updateURLSetting) self.siteDropdown.grid(row=1, column=0, sticky=NSEW, padx=4, pady=4) def populateStreamStartButtonFrame(self): self.buttonOk = Button(self.streamStartButtonFrame, text=LabelConstants.OPEN_STREAMS, width=32, height=2, command=lambda: self.openURL()) self.buttonOk.grid(row=0, column=0, sticky="new", pady=(0,4)) def clearAllTags(self): self.appliedFiltersListbox.selection_clear(0, END) def resetStreams(self): self.selectedStreamsListbox.delete(0, END) self.parent.scrollableFrame.updateStreamFrameBorders([]) def removeStreams(self): for idx in reversed(self.selectedStreamsListbox.curselection()): self.selectedStreamsListbox.delete(idx) self.parent.scrollableFrame.updateStreamFrameBorders(self.selectedStreamsListbox.get(0, END)) def updateURLSetting(self, event=None): self.parent.settings[LabelConstants.SETTINGS_JSON][MiscConstants.KEY_OPEN_STREAMS_ON] = self.siteDropdown.get() writeSettings(self.parent.settings) def openURL(self): finalURL = URLConstants.ORDERED_STREAMING_SITES.get(self.siteDropdown.get()) isRareDrop = finalURL == URLConstants.RAREDROP watchingSingleStreamOnTwitch = False if len(self.selectedStreamsListbox.get(0, END)) == 1 and finalURL != URLConstants.TWITCH and messagebox.askyesno(LabelConstants.TWITCH, MessageConstants.WATCH_ON_TWITCH): finalURL = URLConstants.TWITCH watchingSingleStreamOnTwitch = True if not watchingSingleStreamOnTwitch and not self.siteDropdown.get(): messagebox.showerror(LabelConstants.ERROR, MessageConstants.NO_SITE_SELECTED) elif len(self.selectedStreamsListbox.get(0, END)) > 0: if finalURL == URLConstants.TWITCH: for stream in self.selectedStreamsListbox.get(0, END): webbrowser.open(finalURL + stream, new=2) else: for stream in self.selectedStreamsListbox.get(0, END): if isRareDrop: finalURL += "t" + stream + "/" else: finalURL += stream + "/" webbrowser.open(finalURL, new=2) else: messagebox.showerror(LabelConstants.ERROR, MessageConstants.NO_STREAMS_SELECTED) def updateComboboxTeam(self): self.comboboxTeam.configure(values=list(self.parent.teams.keys())) self.comboboxTeam.current(0) def getAllSelectedTags(self) -> List[Tag]: tagDict = dict(zip([t.localizationNames["en-us"] for t in self.parent.tags], [tag for tag in self.parent.tags])) selectedTags = [] for idx in self.appliedFiltersListbox.curselection(): selectedTags.append(tagDict[self.appliedFiltersListbox.get(idx)]) return selectedTags
class NewNoteFrame(Frame): """"Window that provides UI(input fields and buttons) necessary for creating new note Derives from class Frame""" # class variables ipadx_val = 1 ipady_val = 10 label_font = '"Century Gothic" 10 bold' lbl_ctgr_text = 'Category:' lbl_dscr_text = 'Description:' lbl_date_text = 'Date:' lbl_prrt_text = 'Priority:' data_font = '"Segoe Print" 11' btn_width = 6 btn_conf_text = 'Confirm' btn_cancel_text = 'Cancel' btn_font = 'Arial 9' btn_padx = 25 btn_pady = 35 def __init__(self, master): """ctor""" super().__init__(master) self.pack(fill=BOTH, expand=True) # setting default priority to Normal, corresponding background color is lightyellow bgcolor = prrt2color_dict[ priority_names_lst[1]] # 'Normal':'lightyellow' self.create_widgets(master, bgcolor) def create_widgets(self, master, bg_color): """This method defines UI of the New Note window""" self.frm_main_newnote = Frame(self, bg=bg_color) self.frm_main_newnote.pack(fill=BOTH) self.lbl_category = Label(self.frm_main_newnote, bg=bg_color, font=__class__.label_font, text=__class__.lbl_ctgr_text) self.lbl_category.grid(row=0, column=0, sticky=W, ipadx=__class__.ipadx_val, ipady=__class__.ipady_val) self.cmbx_category = Combobox(self.frm_main_newnote, width=12, font=__class__.data_font) # ttk.Combobox self.cmbx_category.configure( values=category_names_lst ) # the values are: Personal, College, Work, Home self.cmbx_category.current(0) # i.e. default value is 'Personal' self.cmbx_category.grid(row=0, column=1, columnspan=2, sticky=W, ipadx=__class__.ipadx_val) self.lbl_description = Label(self.frm_main_newnote, bg=bg_color, font=__class__.label_font, text=__class__.lbl_dscr_text) self.lbl_description.grid(row=2, column=0, sticky=W, ipadx=__class__.ipadx_val, ipady=__class__.ipady_val) self.entry_description = Entry(self.frm_main_newnote, width=14, font=__class__.data_font) self.entry_description.grid(row=2, column=1, columnspan=2, sticky=W, ipadx=__class__.ipadx_val) self.lbl_date = Label(self.frm_main_newnote, bg=bg_color, font=__class__.label_font, text=__class__.lbl_date_text) self.lbl_date.grid(row=4, column=0, sticky=W, ipadx=__class__.ipadx_val, ipady=__class__.ipady_val) self.entry_date = Entry(self.frm_main_newnote, width=14, font=__class__.data_font) self.entry_date.grid(row=4, column=1, columnspan=2, sticky=W, ipadx=__class__.ipadx_val) self.lbl_priority = Label(self.frm_main_newnote, bg=bg_color, font=__class__.label_font, text=__class__.lbl_prrt_text) self.lbl_priority.grid(row=6, column=0, sticky=W, ipadx=__class__.ipadx_val, ipady=__class__.ipady_val) self.cmbx_priority = Combobox(self.frm_main_newnote, width=12, font=__class__.data_font) # ttk.Combobox self.cmbx_priority.configure( values=priority_names_lst) # the values are: High, Normal, Low self.cmbx_priority.current(1) # i.e. default value is 'Normal' self.cmbx_priority.bind("<<ComboboxSelected>>", self.action_priority2bgcolor) self.cmbx_priority.grid(row=6, column=1, columnspan=2, sticky=W, ipadx=__class__.ipadx_val) btn_confirm = Button( self.frm_main_newnote, font=__class__.btn_font, width=__class__.btn_width, text=__class__.btn_conf_text, command=master.destroy) # master is NewNote dialog btn_confirm.bind('<Button-1>', self.action_add_note) btn_confirm.grid(row=8, column=1, sticky=E, padx=__class__.btn_padx, pady=__class__.btn_pady) self.btn_cancel = Button( self.frm_main_newnote, font=__class__.btn_font, width=__class__.btn_width, text=__class__.btn_cancel_text, command=master.destroy ) # master = dlgNewNote #self.frm_buttons_view self.btn_cancel.grid(row=8, column=2, sticky=W, pady=__class__.btn_pady) def action_add_note(self, event): """This method registers new note; activated by click on button Confirm""" # reading note details from UI category_str = self.cmbx_category.get().strip() descr_str = self.entry_description.get().strip() date_str = self.entry_date.get().strip() priority_str = self.cmbx_priority.get().strip() new_note_obj = NotePureData( category_str, descr_str, date_str, priority_str) # object of class NotePureData notes_dict[ new_note_obj. id] = new_note_obj # adding new note object to the notes dictionary aux_filter_notes(category_filter_ctrlvar.get(), descr_filter_ctrlvar.get()) display_notes() db_insert_note(new_note_obj) # adding new note to the database def action_priority2bgcolor(self, event): """This method defines background color of the frame according to currently selected priority; activated by selection of a value from the Priority combo-box""" priority = self.cmbx_priority.get() # setting value of the background color according to the current task priority bgcolor = prrt2color_dict[ priority] # {'Low':'lightgreen', 'Normal':'lightyellow', 'High':'lightpink'} # setting background color of the NewNote frame and of the relevant widgets self.frm_main_newnote.configure(bg=bgcolor) widgets_lst = [ w for w in self.frm_main_newnote.winfo_children() if isinstance(w, Label) ] for w in widgets_lst: w.configure(bg=bgcolor)
class _propellants(_Dialog): def body(self, master): dialogframe = Frame(master, width=350, height=135) self.dialogframe = dialogframe dialogframe.pack() self.make_Combobox_1( self.dialogframe) # Combobox: Oxidizer : at Main(3,1) self.make_Combobox_2( self.dialogframe) # Combobox: Fuel : at Main(3,2) self.make_Label_1( self.dialogframe) # Label: Oxidizer : at Main(2,1) self.make_Label_2(self.dialogframe) # Label: Fuel : at Main(2,2) self.make_Label_3( self.dialogframe ) # Label: Select Oxidizer and Fuel : at Main(1,1) self.make_Label_4(self.dialogframe) # Label: at Main(0,1) self.make_Label_5(self.dialogframe) # Label: at Main(2,0) self.make_Label_6(self.dialogframe) # Label: at Main(2,3) # >>>>>>insert any user code below this comment for section "top_of_init" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_1" def make_Combobox_1(self, frame): """ Combobox: Oxidizer : at Main(3,1)""" self.Combobox_1 = Combobox(frame, values="Mine Yours Ours", text="Oxidizer") self.Combobox_1.grid(row=3, column=1) self.Combobox_1_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Combobox_1" self.Combobox_1.configure(values=' '.join(oxidizerL)) self.Combobox_1.configure(textvariable=self.Combobox_1_StringVar) self.Combobox_1_StringVar.set(self.dialogOptions['oxName']) self.Combobox_1_StringVar_traceName = self.Combobox_1_StringVar.trace_variable( "w", self.Combobox_1_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_2" def make_Combobox_2(self, frame): """ Combobox: Fuel : at Main(3,2)""" self.Combobox_2 = Combobox(frame, values="Mine Yours Ours", text="Fuel") self.Combobox_2.grid(row=3, column=2) self.Combobox_2_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Combobox_2" self.Combobox_2.configure(values=' '.join(fuelL)) self.Combobox_2.configure(textvariable=self.Combobox_2_StringVar) self.Combobox_2_StringVar.set(self.dialogOptions['fuelName']) self.Combobox_2_StringVar_traceName = self.Combobox_2_StringVar.trace_variable( "w", self.Combobox_2_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_1" def make_Label_1(self, frame): """ Label: Oxidizer : at Main(2,1)""" self.Label_1 = Label(frame, text="Oxidizer", width="15") self.Label_1.grid(row=2, column=1) # >>>>>>insert any user code below this comment for section "make_Label_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_2" def make_Label_2(self, frame): """ Label: Fuel : at Main(2,2)""" self.Label_2 = Label(frame, text="Fuel", width="15") self.Label_2.grid(row=2, column=2) # >>>>>>insert any user code below this comment for section "make_Label_2" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_3" def make_Label_3(self, frame): """ Label: Select Oxidizer and Fuel : at Main(1,1)""" self.Label_3 = Label(frame, text="Select Oxidizer and Fuel", width="30") self.Label_3.grid(row=1, column=1, columnspan="2") # >>>>>>insert any user code below this comment for section "make_Label_3" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_4" def make_Label_4(self, frame): """ Label: at Main(0,1)""" self.Label_4 = Label(frame, text="", width="15", height="2") self.Label_4.grid(row=0, column=1) # >>>>>>insert any user code below this comment for section "make_Label_4" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_5" def make_Label_5(self, frame): """ Label: at Main(2,0)""" self.Label_5 = Label(frame, text="", width="8") self.Label_5.grid(row=2, column=0) # >>>>>>insert any user code below this comment for section "make_Label_5" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_6" def make_Label_6(self, frame): """ Label: at Main(2,3)""" self.Label_6 = Label(frame, text="", width="8") self.Label_6.grid(row=2, column=3) # >>>>>>insert any user code below this comment for section "make_Label_6" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_1_StringVar_traceName" def Combobox_1_StringVar_Callback(self, varName, index, mode): """ Combobox: Oxidizer : at Main(3,1)""" pass # >>>>>>insert any user code below this comment for section "Combobox_1_StringVar_traceName" # replace, delete, or comment-out the following print("Combobox_1_StringVar_Callback varName, index, mode", varName, index, mode) print(" new StringVar value =", self.Combobox_1_StringVar.get()) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_2_StringVar_traceName" def Combobox_2_StringVar_Callback(self, varName, index, mode): """ Combobox: Fuel : at Main(3,2)""" pass # >>>>>>insert any user code below this comment for section "Combobox_2_StringVar_traceName" # replace, delete, or comment-out the following print("Combobox_2_StringVar_Callback varName, index, mode", varName, index, mode) print(" new StringVar value =", self.Combobox_2_StringVar.get()) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "dialog_validate" def validate(self): self.result = {} # return a dictionary of results #self.result["Combobox_1"] = self.Combobox_1_StringVar.get() #self.result["Combobox_2"] = self.Combobox_2_StringVar.get() # >>>>>>insert any user code below this comment for section "dialog_validate" # set values in "self.result" dictionary for return # for example... # self.result["age"] = self.Entry_2_StringVar.get() self.result["oxName"] = self.Combobox_1_StringVar.get() self.result["fuelName"] = self.Combobox_2_StringVar.get() """ # for testing, reinstate this code below dialog = _propellants(self.master, "Propellants Dialog", dialogOptions={'oxName':'LOX', 'fuelName':'MMH'}) """ #self.result["test"] = "test message" return 1 # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "end" def apply(self): pass
class CombatManager(Tk): def __init__(self): Tk.__init__(self) self.title("Combat Manager") # allows row 0 (=frame, textframe) to expand vertically self.rowconfigure(0, weight=1) # allows column 5 (=buttonframe) to expand horizontally self.columnconfigure(5, weight=1) self.entities = [] self.queue = EntityQueue() self.started = False self.textcommandhistory = [] self.commandhistory = CommandHistory() self.names = dict() self.damage = 1 # Menu self.menubar = Menu(self) # File Menu self.filemenu = Menu(self.menubar, tearoff=0) self.filemenu.add_command(label="Load Entity", command=self.loadEntityCallback) self.filemenu.add_command(label="Load Players", command=self.loadPlayersCallback) self.filemenu.add_separator() self.filemenu.add_command(label="Save Fight", command=self.saveFightCallback, state="disable") self.filemenu.add_command(label="Load Fight", command=self.loadFightCallback) self.filemenu.add_separator() self.filemenu.add_command(label="Settings", command=self.settingsCallback) self.filemenu.add_separator() self.filemenu.add_command(label="Exit", command=self.exitCallback) #Tools Menu self.toolsmenu = Menu(self.menubar, tearoff=0) self.toolsmenu.add_command(label="Die Roll", command=self.dierollCallback) self.toolsmenu.add_command(label="Group Damage", command=self.groupdamageCallback, state="disable") self.menubar.add_cascade(label="Menu", menu=self.filemenu) self.menubar.add_cascade(label="Tools", menu=self.toolsmenu) self.config(menu=self.menubar) #VerticalScrolledFrame containing EntityFrames self.frame = VerticalScrolledFrame(self, borderwidth=2, relief=RIDGE) self.frame.grid(row=0, column=0, columnspan=4, sticky=NSEW) # start, add, clear and load buttons self.startButton = Button(self, text="Start", command=self.startCallback) # self.startButton.grid(row=1,column=0,sticky=EW,padx=5,pady=5) self.startButton.grid(row=1, column=0, rowspan=2, sticky=NSEW, padx=5, pady=5) self.loadButton = Button(self, text="Load Entity", command=self.loadEntityCallback) # self.loadButton.grid(row=1,column=1,sticky=EW,padx=5,pady=5) self.loadButton.grid(row=1, column=1, rowspan=2, sticky=NSEW, padx=5, pady=5) self.clearButton = Button(self, text="Clear", command=self.clearCallback) # self.clearButton.grid(row=1,column=2,sticky=EW,padx=5,pady=5) self.clearButton.grid(row=1, column=2, rowspan=2, sticky=NSEW, padx=5, pady=5) self.addButton = Button(self, text="+", command=self.addCallback) # self.addButton.grid(row=1,column=3,sticky=E,padx=5,pady=5) self.addButton.grid(row=1, column=3, rowspan=2, sticky=NSEW, padx=5, pady=5) #EntityQueueuFrame containing the EntityQueue self.eqf = EntityQueueFrame(self, self) self.eqf.grid(row=0, column=4, columnspan=2, sticky=NSEW) #Damage entry, half damage tickbox, in seperate frame self.damageFrame = Frame(self) self.damageFrame.grid(row=1, column=4, padx=5, pady=5, rowspan=2) self.damageFrame['bd'] = 1 self.damageFrame['relief'] = 'ridge' Label(self.damageFrame, text="Damage:").grid(row=0, column=0, sticky=W, padx=5, pady=5) self.damageVar = IntVar() self.damageVar.set(1) self.damageVar.trace('w', self.damageCallback) self.damageEntry = Entry(self.damageFrame, width=2, textvariable=self.damageVar, state='disabled') self.damageEntry.bind('<ButtonRelease-1>', self.damageEntryCallback) self.damageEntry.grid(row=0, column=1, sticky=W, padx=5, pady=5) Label(self.damageFrame, text="Half Damage:").grid(row=1, column=0, sticky=W, padx=5, pady=5) self.halfdamage = BooleanVar() self.halfdamage.set(False) self.halfdamage.trace('w', self.damageCallback) self.halfdamageCheckbutton = Checkbutton(self.damageFrame, variable=self.halfdamage, state='disabled') self.halfdamageCheckbutton.grid(row=1, column=1, sticky=W, padx=5, pady=5) # command line, run ,undo, redo and next buttons in seperate frame self.buttonFrame = Frame(self) self.buttonFrame.grid(row=1, column=5, padx=5, pady=5, rowspan=2, sticky=EW) for i in range(5): self.buttonFrame.columnconfigure(i, weight=1) self.nextButton = Button(self.buttonFrame, text="Next", command=self.nextCallback, state='disabled') self.nextButton.grid(row=0, column=0, columnspan=5, sticky=EW, padx=5, pady=5) self.commandstring = StringVar() Label(self.buttonFrame, text="Command:").grid(row=1, column=0, sticky=E, padx=5, pady=5) self.commandEntry = Combobox(self.buttonFrame, textvariable=self.commandstring, state='disabled', postcommand=self.updateHistory) self.commandEntry.bind('<Return>', self.runCallback) self.commandEntry.bind('<KP_Enter>', self.runCallback) self.commandEntry.grid(row=1, column=1, sticky=EW, padx=5, pady=5) self.runButton = Button(self.buttonFrame, text="Run", command=self.runCallback, state='disabled') self.runButton.grid(row=1, column=2, sticky=EW, padx=5, pady=5) self.undoButton = Button(self.buttonFrame, text="Undo", command=self.undoCallback, state='disabled') self.undoButton.grid(row=1, column=3, sticky=EW, padx=5, pady=5) self.redoButton = Button(self.buttonFrame, text="Redo", command=self.redoCallback, state='disabled') self.redoButton.grid(row=1, column=4, sticky=EW, padx=5, pady=5) # General Key Bindings self.bind('<Control-q>', self.exitCallback) self.bind('<Control-z>', self.undoCallback) self.bind('<Control-Z>', self.redoCallback) self.bind('<Control-n>', self.nextCallback) self.bind('<Control-o>', self.loadFightCallback) self.bind('<Control-s>', self.saveFightCallback) self.bind('<Control-c>', self.focusCallback) # Load Settings self.loadSettings() def configureCanvas(self, event): self.canvas.configure(scrollregion=self.canvas.bbox("all")) def updatename(self, name): for e in self.queue: if e.name == name: e.name = name + ' 1' def loadSettings(self): if os.path.exists('settings.json'): try: f = open('settings.json', 'r') self.settings = json.load(f) f.close() except OSError: messagebox.showerror('Load Settings', 'Could not load settings') except (KeyError, TypeError): messagebox.showerror('Load Settings', 'Settings file not in correct format') else: self.initializeSettings() def initializeSettings(self): currentdir = os.getcwd() self.settings = dict() self.settings['fightdir'] = currentdir self.settings['entitydir'] = currentdir self.settings['playerfiles'] = [] try: f = open('settings.json', 'w') json.dump(self.settings, f) f.close() except OSError: messagebox.showerror("Save Settings", "Could not save settings") def updateHistory(self): # use splicing to reverse list self.commandEntry.configure(values=[''] + self.textcommandhistory[::-1]) def addCallback(self): e = EntryFrame(self.frame.interior, self) e.pack(padx=5, pady=5) index = len(self.entities) self.entities.append(e) e.setIndex(index) return e def updateIndices(self): for i in range(len(self.entities)): self.entities[i].setIndex(i) # enables certain widgets on start def enableWidgetsOnStart(self): self.damageEntry['state'] = 'normal' self.halfdamageCheckbutton['state'] = 'normal' self.commandEntry['state'] = 'normal' self.runButton['state'] = 'normal' # self.undoButton['state']='normal' # self.redoButton['state']='normal' self.nextButton['state'] = 'normal' for ef in self.entities: if not ef.player.get(): ef.addToCombatButton['state'] = 'normal' # ef.autoroll.set(False) self.filemenu.entryconfig("Save Fight", state='normal') self.toolsmenu.entryconfig("Group Damage", state='normal') # disables certain widgets on stop def disableWidgetsOnStop(self): self.damageEntry['state'] = 'disabled' self.halfdamageCheckbutton['state'] = 'disabled' self.commandEntry['state'] = 'disabled' self.runButton['state'] = 'disabled' self.undoButton['state'] = 'disabled' self.redoButton['state'] = 'disabled' self.nextButton['state'] = 'disabled' for ef in self.entities: if not ef.player.get(): ef.addToCombatButton['state'] = 'disabled' # ef.autoroll.set(True) self.filemenu.entryconfig("Save Fight", state='disable') self.toolsmenu.entryconfig("Group Damage", state='disable') #external callbacks (=called from object other than combatmanager) def addToCombat(self, e): if e.hasError(): messagebox.showwarning("Add Entity", "One or more entries contain errors.") return rd = RollDialog(self, [e], self.names) if rd.rolls == None: return else: i = 0 entities = [] for j in range(e.amount.get()): entities.append( Entity(rd.names[i], e.bonus.get(), dice.getHealth(e.health.get()), rd.rolls[i], e.ac.get(), e.player.get())) i += 1 command = AddCommand(self.queue, entities) self.executeCommand(command) def startCallback(self): error = False if len(self.entities) == 0: return # two passes: one to check if any errors popped up, if not: one to actually make entities and append # entities for e in self.entities: if e.hasError(): error = True if error: messagebox.showwarning("Start", "One or more entries contain errors.") else: if self.started: if messagebox.askyesno( "Start", "Are you sure you want to restart combat? Progress will be lost." ): self.queue.clear() self.names.clear() else: return # second pass rd = RollDialog(self, self.entities, self.names) # print(self.names) if rd.rolls == None: self.names.clear() return else: i = 0 for e in self.entities: for j in range(e.amount.get()): self.queue.append( Entity(rd.names[i], e.bonus.get(), dice.getHealth(e.health.get()), rd.rolls[i], e.ac.get(), e.player.get())) i += 1 #self.queue.sort() self.refreshDisplay() self.enableWidgetsOnStart() self.started = True def damageEntryCallback(self, event=None): self.halfdamage.set(False) self.damageEntry.selection_range(0, END) return 'break' def damageCallback(self, *args): try: if self.halfdamage.get(): self.damage = int(self.damageVar.get() / 2) else: self.damage = self.damageVar.get() self.refreshDisplay() except: pass def nextCallback(self, event=None): if self.started: command = NextCommand(self.queue) command.execute() self.commandhistory.append(command) self.checkCommandHistory() self.refreshDisplay() def runCallback(self, event=None): commandstring = self.commandstring.get() commandstring = commandstring.split() command = None if len(commandstring) == 0: pass # usage: next # make the next active entity in the queue, the acting entity elif (commandstring[0] == commands[0] or commandstring[0] == shortcuts[0]) and len(commandstring) == 1: command = NextCommand(self.queue) # usage: heal n hp # heals entity with index n hp points elif (commandstring[0] == commands[1] or commandstring[0] == shortcuts[1]) and len(commandstring) == 3: try: command = HealCommand(self.queue, int(commandstring[1]) - 1, int(commandstring[2])) except ValueError: messagebox.showwarning("Run", 'Not a valid number.') # usage: damage n hp # damages entity with index n hp points elif (commandstring[0] == commands[2] or commandstring[0] == shortcuts[2]) and len(commandstring) == 3: try: command = DamageCommand(self.queue, int(commandstring[1]) - 1, int(commandstring[2])) except ValueError: messagebox.showwarning("Run", 'Not a valid number.') # usage: remove n # remove entity with number n from queue elif (commandstring[0] == commands[3] or commandstring[0] == shortcuts[3]) and len(commandstring) == 2: try: command = RemoveCommand(self.queue, int(commandstring[1]) - 1) except ValueError: messagebox.showwarning("Run", 'Not a valid number.') # usage: restore n # revive a previously removed entity from the queue elif (commandstring[0] == commands[4] or commandstring[0] == shortcuts[4]) and len(commandstring) == 2: try: command = RestoreCommand(self.queue, int(commandstring[1]) - 1) except ValueError: messagebox.showwarning("Run", 'Not a valid number.') # usage: delay n up/down # delay entity with number n up or down elif (commandstring[0] == commands[5] or commandstring[0] == shortcuts[5]) and len(commandstring) == 3: try: if commandstring[2] == 'down': down = True elif commandstring[2] == 'up': down = False else: messagebox.showwarning("Run", "Use Up/Down") return command = DelayCommand(self.queue, int(commandstring[1]) - 1, down) except ValueError: messagebox.showwarning("Run", 'Not a valid number.') # help elif (commandstring[0] == commands[6] or commandstring[0] == shortcuts[6]) and len(commandstring) == 1: s = helpdict['help'] + '\nCommands:\n' for i in commands: s += i + '\n' messagebox.showinfo("Help", s) return elif (commandstring[0] == commands[6] or commandstring[0] == shortcuts[6]) and len(commandstring) == 2: try: messagebox.showinfo("Help", helpdict[commandstring[1]]) except KeyError: s = 'Not a command\nCommands:\n' for i in commands: s += i + '\n' messagebox.showinfo("Help", s) # stop elif (commandstring[0] == commands[7] or commandstring[0] == shortcuts[7]) and len(commandstring) == 1: self.exitCallback() else: messagebox.showwarning( "Run", 'Unknown Command or Wrong Syntax. Use help command for, you know, help.' ) # execute command if command is not None: try: self.executeCommand(command) self.textcommandhistory.append(self.commandstring.get()) self.commandstring.set('') except IndexError: messagebox.showwarning("Run", "Index Out of Range.") # check if there are any enemies left if self.queue.activeEnemies() == 0 and self.started: messagebox.showinfo("Run", 'All enemies defeated.') def undoCallback(self, event=None): if self.started: self.commandhistory.undo() self.checkCommandHistory() self.refreshDisplay() def redoCallback(self, event=None): if self.started: self.commandhistory.redo() self.checkCommandHistory() self.refreshDisplay() def checkCommandHistory(self): # disable undo if at begin of commandhistory if self.commandhistory.atBegin(): self.undoButton['state'] = 'disabled' else: self.undoButton['state'] = 'normal' # disable redo if at end of commandhistory if self.commandhistory.atEnd(): self.redoButton['state'] = 'disabled' else: self.redoButton['state'] = 'normal' # refresh display of entityqueue def refreshDisplay(self): self.eqf.refresh() # clear display of entityqueue def clearDisplay(self): self.eqf.clear() def clearCallback(self): self.queue.clear() self.commandhistory.clear() self.names.clear() self.clearDisplay() for e in self.entities: e.destroy() self.entities = [] self.started = False self.disableWidgetsOnStop() def executeCommand(self, command): command.execute() self.refreshDisplay() self.commandhistory.append(command) self.checkCommandHistory() # Menu Callbacks def loadEntityCallback(self): filenames = filedialog.askopenfilenames( initialdir=self.settings['entitydir']) for filename in filenames: try: f = open(filename, 'r') d = json.load(f) f.close() e = self.addCallback() e.fillIn(d) except OSError: messagebox.showerror('Load Entity', 'Could not open file ' + filename) e.destroyCallback() except (KeyError, TypeError): messagebox.showerror( 'Load Entity', 'File ' + filename + ' not in correct format') e.destroyCallback() def saveEntityCallback(self, e): if e.name.get() == "": messagebox.showwarning("Save", "No name given.") return try: filename = os.path.join(self.settings['entitydir'], e.name.get() + ".json") f = open(filename, 'w') d = e.toJson() d['amount'] = 1 json.dump(d, f) f.close() messagebox.showinfo("Save", "Entity saved as " + filename) except OSError: messagebox.showerror("Save", "Could not save file") def loadPlayersCallback(self): for p in self.settings['playerfiles']: try: f = open(p, 'r') d = json.load(f) f.close() e = self.addCallback() e.fillIn(d) except OSError: messagebox.showerror('Load Player', 'Could not open file ' + p) except (KeyError, TypeError): messagebox.showerror('Load Player', 'File ' + p + ' not in correct format') def saveFightCallback(self, event=None): if self.started: filename = filedialog.asksaveasfilename( initialdir=self.settings['fightdir'], defaultextension=".json") if filename: try: d = dict() d["position"] = self.queue.position d["round"] = self.queue.round # iterate over entities in EntityQueue and save their dictionary representation to a list entitiesList = [] for e in self.queue.queue: entitiesList.append(e.__dict__) d["queue"] = entitiesList # iterate over EntityFrames and save their dictionary representation to a list entityFramesList = [] for ef in self.entities: entityFramesList.append(ef.toJson()) d["frames"] = entityFramesList d["names"] = self.names f = open(filename, 'w') json.dump(d, f) f.close() messagebox.showinfo("Save Fight", "Fight saved as " + filename) except OSError: messagebox.showerror("Save Fight", "Could not save file") def loadFightCallback(self, event=None): if self.started: if not messagebox.askyesno( "Start", "Are you sure you want to restart combat? Progress will be lost." ): return filename = filedialog.askopenfilename( initialdir=self.settings['fightdir']) if filename: try: f = open(filename, 'r') d = json.load(f) f.close() self.queue.clear() self.queue.position = d["position"] self.queue.round = d["round"] for e in d["queue"]: self.queue.append(Entity.fromDict(e)) #self.queue.sort() self.refreshDisplay() for ef in d["frames"]: e = self.addCallback() e.fillIn(ef) self.names = d["names"] self.started = True self.enableWidgetsOnStart() except OSError: messagebox.showerror('Load Fight', 'Could not open file ' + filename) except (KeyError, TypeError): messagebox.showerror( 'Load Fight', 'File ' + filename + ' not in correct format') def settingsCallback(self): sd = SettingsDialog(self, self.settings) print(sd.settings) if sd.settings is not None: self.settings = sd.settings try: f = open('settings.json', 'w') json.dump(self.settings, f) f.close() except OSError: messagebox.showerror("Save Settings", "Could not save settings") def dierollCallback(self): dr = DiceDialog(self) def groupdamageCallback(self): gdd = GroupDamageDialog(self, self.queue) def focusCallback(self, event=None): self.commandEntry.focus() def exitCallback(self, event=None): if messagebox.askyesno("Exit", "Are you sure you want to exit?"): self.destroy()
class CsvFrame: """ Display csv data in a tkinter TreeView """ def __init__(self, parent, manager): """ CsvFrame constructor """ top = self.top = tkinter.Toplevel(parent) self.__parent = parent self.__manager = manager top_frame = tkinter.Frame(top, borderwidth=2, relief=tkinter.GROOVE) top_frame.pack(side=tkinter.TOP, fill=tkinter.X, padx=5, pady=5) label_data = Label(top_frame, text="Data: ") label_data.grid(row=1, column=1, padx=5, pady=5) data_select_combo3 = tkinter.StringVar() self.combo_data = Combobox(top_frame, textvariable=data_select_combo3, values=manager.get_field_names(), state='readonly', postcommand=lambda: self.combo_data.configure(values=manager.get_field_names())) self.combo_data.grid(row=1, column=2, padx=5, pady=5) edit_button = Button(top_frame, text="Edit header", command=self.edit_header, width=20) edit_button.grid(row=1, column=3, columnspan=1, rowspan=1, padx=5, pady=5) # TODO change values for combobox transform_select_combo4 = tkinter.StringVar() self.combo_transform = Combobox(top_frame, textvariable=transform_select_combo4, values=["rad_to_deg", "deg_to_rad"], state='readonly') self.combo_transform.grid(row=1, column=4, padx=5, pady=5) transform_button = Button(top_frame, text="Transform data", command=self.transform_data, width=20) transform_button.grid(row=1, column=5, columnspan=1, rowspan=1, padx=5, pady=5) table_frame = Frame(top) table_frame.pack(side=tkinter.BOTTOM, expand=True, fill=tkinter.BOTH) scrollbar_x = Scrollbar(table_frame, orient=tkinter.HORIZONTAL) scrollbar_y = Scrollbar(table_frame, orient=tkinter.VERTICAL) self.tree = Treeview(table_frame, columns=manager.get_field_names(), show="headings", selectmode="extended", yscrollcommand=scrollbar_y.set, xscrollcommand=scrollbar_x.set) scrollbar_y.config(command=self.tree.yview) scrollbar_y.pack(side=tkinter.RIGHT, fill=tkinter.Y) scrollbar_x.config(command=self.tree.xview) scrollbar_x.pack(side=tkinter.BOTTOM, fill=tkinter.X) self.fill_data() self.tree.pack(expand=True, fill=tkinter.BOTH) self.top.protocol("WM_DELETE_WINDOW", self.quit) def edit_header(self): """ Edit the header a data column """ if self.combo_data.get() != "": answer = simpledialog.askstring("Input", "What is the new header?", parent=self.top) if answer is not None: self.__manager.edit_header(answer, self.combo_data.get()) self.fill_data() self.combo_data.set('') else: logger.log(logging.INFO, "[CsvFrame] No new header entered") else: logger.log(logging.ERROR, "[CsvFrame] No data field selected") def clear_data(self): """ Clear data in Treeview """ logger.log(logging.INFO, "[CsvFrame] Clear data in TreeView") for i in self.tree.get_children(): self.tree.delete(i) def fill_data(self): """ Fill data in Treeview """ logger.log(logging.INFO, "[CsvFrame] Fill data in TreeView") self.clear_data() self.tree.config(columns=self.__manager.get_field_names()) for field_name in self.__manager.get_field_names(): self.tree.heading(field_name, text=field_name, anchor=tkinter.W) self.tree.column(field_name, stretch=tkinter.YES) for entry in self.__manager.get_data_tuple(): self.tree.insert("", 'end', values=entry) def transform_data(self): """ Transform data and add in Treeview """ # TODO to be completed data_field_name = self.combo_data.get() if data_field_name != "": if self.combo_transform.get() != "": data = self.__manager.get_data_from_field_name(data_field_name) transformed_data = transform_data(self.combo_transform.get(), self.combo_data.get(), data) if transformed_data[0] != "": self.__manager.add_data(transformed_data[0], transformed_data[1], transformed_data[2]) self.fill_data() else: logger.log(logging.ERROR, "[CsvFrame] Data has not been transformed") else: logger.log(logging.ERROR, "[CsvFrame] No transform operation selected") else: logger.log(logging.ERROR, "[CsvFrame] No data field selected") def quit(self): """ Destroy the frame """ self.__parent.reset_csvframe() self.top.destroy()
### On ajoute le bouton et la variable contenant notre liste de villes à global, pour pouvoir les modifier de partout global BDepart, villeDepartList ###On crée notre variable vierge villeDepartList = () ###On crée notre Combobox ###On lui associe une fonction lorsqu'on la sélectionne ###On configure sa taille et son état BDepart = Combobox(sub1, textvariable=villeDepart, values=villeDepartList, state='readonly') BDepart.bind("<<ComboboxSelected>>", Depart) BDepart.pack(fill=X, padx=2, pady=2) BDepart.configure(state=DISABLED) ###On crée un espace entre les deux Combobox Label(sub1, text='\n\n\n\n').pack(padx=2, pady=2) ###Même chose que pour la ville de départ, mais cette fois ci pour l'arrivée Label(sub1, text='''Ville d'arrivée : \n''').pack(fill=X, padx=2, pady=2) global villeArrivee villeArrivee = StringVar() villeArrivee.set('''Ville d'arrivée ''') global BArrivee global villeArriveeList villeArriveeList = () BArrivee = Combobox(sub1,
class RAnalysisFrame(tkinter.Tk): """ Main GUI window: Display menu and PlotFrame """ def __init__(self, parent): """ MainFrame constructor """ tkinter.Tk.__init__(self, parent) self.__parent = parent self.geometry("+50+50") self.__logger_frame = None self.__plot_frame_combo = None self.__variable1_combo = None self.__variable2_combo = None self.__plot_frame_select_combo = tkinter.StringVar() self.__plot_frame = {} self.__plot_frame_list = ["all"] self.__counter = 0 self.__data_manager = DataManager() self.__csv_frame = None self.initialize() def initialize(self): """ Initialize all the tkinter objects of the frame """ self.title('RGINE Data Analysis') # frame top_frame = tkinter.Frame(self) top_frame.pack(side=tkinter.TOP, fill=tkinter.X) data_frame = tkinter.Frame(top_frame) data_frame.pack(side=tkinter.TOP, fill=tkinter.X) data_frame_csv = tkinter.Frame(data_frame, borderwidth=2, relief=tkinter.GROOVE) data_frame_csv.pack(side=tkinter.LEFT, fill=tkinter.X, padx=5, pady=5) data_frame_data = tkinter.Frame(data_frame, borderwidth=2, relief=tkinter.GROOVE) data_frame_data.pack(side=tkinter.RIGHT, fill=tkinter.X, padx=5, pady=5) plot_frame = tkinter.Frame(top_frame, borderwidth=2, relief=tkinter.GROOVE) plot_frame.pack(side=tkinter.LEFT, fill=tkinter.X, padx=5, pady=5) action_frame = tkinter.Frame(top_frame, borderwidth=2, relief=tkinter.GROOVE) action_frame.pack(side=tkinter.RIGHT, fill=tkinter.X, padx=5, pady=5) # button load_button = Button(data_frame_csv, text="Load CSV file", command=self.load_data, width=20) load_button.grid(row=1, column=1, columnspan=1, rowspan=1, padx=5, pady=5) refresh_file_button = Button(data_frame_csv, text="Refresh CSV file", command=self.refresh_file, width=20) refresh_file_button.grid(row=1, column=2, padx=5, pady=5) display_button = Button(data_frame_data, text="Display data", command=self.display_data, width=20) display_button.grid(row=1, column=3, padx=5, pady=5) save_button = Button(data_frame_data, text="Save data", command=self.save_data, width=20) save_button.grid(row=1, column=4, padx=5, pady=5) clear_button = Button(data_frame_data, text="Clear data", command=self.clear_data, width=20) clear_button.grid(row=1, column=5, padx=5, pady=5) add_button = Button(action_frame, text="Add plot", command=self.add_plot, width=20) add_button.grid(row=1, column=3, rowspan=1, padx=5, pady=5) function_button = Button(action_frame, text="Plot math function", command=self.add_plot_function, width=20) function_button.grid(row=2, column=3, columnspan=1, rowspan=1, padx=5, pady=5) add_plot_button = Button(plot_frame, text="Add Plot frame", command=self.add_plot_frame, width=20) add_plot_button.grid(row=1, column=1, columnspan=1, rowspan=1, padx=5, pady=5) clear_plot_button = Button(plot_frame, text="Clear all plots", command=self.clear_all_plots, width=20) clear_plot_button.grid(row=1, column=2, columnspan=1, rowspan=1, padx=5, pady=5) remove_plot_button = Button(plot_frame, text="Remove all plots", command=self.remove_all_plots, width=20) remove_plot_button.grid(row=2, column=2, columnspan=1, rowspan=1, padx=5, pady=5) # label label_x = Label(action_frame, text="Choose X axis data: ", width=20) label_x.grid(row=1, column=1, padx=5, pady=5) label_y = Label(action_frame, text="Choose Y axis data: ", width=20) label_y.grid(row=2, column=1, padx=5, pady=5) # combo self.__plot_frame_combo = Combobox( plot_frame, textvariable=self.__plot_frame_select_combo, values=self.__plot_frame_list, state='readonly', postcommand=lambda: self.__plot_frame_combo.configure( values=self.__plot_frame_list), width=17) self.__plot_frame_combo.current(0) self.__plot_frame_combo.grid(row=2, column=1, padx=5, pady=5) data_select_combo1 = tkinter.StringVar() self.__variable1_combo = Combobox( action_frame, textvariable=data_select_combo1, values=self.__data_manager.get_field_names(), state='readonly', postcommand=lambda: self.__variable1_combo.configure( values=self.__data_manager.get_field_names()), width=19) self.__variable1_combo.grid(row=1, column=2, padx=5, pady=5) data_select_combo2 = tkinter.StringVar() self.__variable2_combo = Combobox( action_frame, textvariable=data_select_combo2, values=self.__data_manager.get_field_names(), state='readonly', postcommand=lambda: self.__variable2_combo.configure( values=self.__data_manager.get_field_names()), width=19) self.__variable2_combo.grid(row=2, column=2, padx=5, pady=5) # menu frame_menu = tkinter.Menu(self) help_menu = tkinter.Menu(frame_menu, tearoff=0) help_menu.add_command(label="Logger", command=self.open_logger_command) help_menu.add_separator() help_menu.add_command(label="How to", command=self.how_to_command) help_menu.add_command(label="About", command=self.about_command) frame_menu.add_cascade(label="Help", menu=help_menu) self.config(menu=frame_menu) def open_logger_command(self): """ Display or hide the LoggerFrame """ logger.log(logging.INFO, "[MainFrame] Opening Logger frame") if self.__logger_frame is not None: self.__logger_frame.quit() self.__logger_frame = None self.__logger_frame = LoggerFrame(self) def how_to_command(self): """ Displaying some "how to" questions """ messagebox.showinfo( "How to ?", " - Create independent plots frame to analyze data\n" " - Load data\n" " - Choose x and y axis then add the graph to the list\n" " - Select in the list, all the graphs to display") def about_command(self): """ Displaying RAnalysis informations """ messagebox.showinfo( "About", "RAnalaysis v0.1\n\nhttp://gitlab-dtis.onera/s2im/rgine/ranalysis") def add_plot_frame(self): """ Creating new plot frame """ plot_frame_id = "Plot frame " + str(self.__counter) plot_frame = PlotFrame(self, plot_frame_id) self.__plot_frame[plot_frame_id] = plot_frame self.__plot_frame_list.append(plot_frame_id) self.__counter += 1 logger.log(logging.INFO, "[MainFrame] Opening Plot frame: " + plot_frame_id) def load_data(self): """ Load data from a csv file """ filename = askopenfilename(title="Open data file", filetypes=[('csv files', '.csv'), ('out files', '.out'), ('all files', '.*')]) if filename is not None and len(filename) > 0: input_dialog = InputDialog(self) self.wait_window(input_dialog.top) logger.log(logging.INFO, "[MainFrame] loading file " + str(filename)) if self.__data_manager is not None: if input_dialog.get_input_options()['clear']: self.clear_data() else: self.__data_manager = DataManager() self.__data_manager.read_csv_file(filename, input_dialog.get_input_options()) else: logger.log(logging.ERROR, "[MainFrame] No file selected") def refresh_file(self): """ Refresh data from the same csv file """ if self.__data_manager.manager_have_data(): logger.log(logging.INFO, "[MainFrame] Refreshing file") self.__data_manager.refresh_data() if self.__csv_frame is not None: self.__csv_frame.fill_data() else: logger.log(logging.ERROR, "[MainFrame] No data to refresh") def display_data(self): """ Display csv data in a CsvFrame """ if self.__data_manager.manager_have_data(): logger.log(logging.INFO, "[MainFrame] Displaying data") self.__csv_frame = CsvFrame(self, self.__data_manager) else: logger.log( logging.ERROR, "[MainFrame] Could not display data, data manager does not have data" ) def clear_data(self): """ Clear data """ if self.__data_manager is not None: logger.log(logging.INFO, "[MainFrame] Clearing data") self.__data_manager.reset_manager() else: logger.log(logging.ERROR, "[MainFrame] No data to clear") self.__variable1_combo.set('') self.__variable2_combo.set('') def save_data(self): """ Save data in a CSV file """ file_type = [('csv files', '.csv'), ('out files', '.out'), ('all files', '.*')] file = asksaveasfile(filetypes=file_type, defaultextension=file_type) if file is None: logger.log(logging.ERROR, "[PlotFrame] No save file selected") else: logger.log(logging.INFO, "[MainFrame] Saving data") self.__data_manager.save_csv_file(file.name) def reset_csvframe(self): """ Reset csv frame """ self.__csv_frame = None def reset_plot_frame(self, plot_frame_id): """ Reset plot frame """ self.__plot_frame_combo.current(0) self.__plot_frame_list.remove(plot_frame_id) del self.__plot_frame[plot_frame_id] def add_plot(self): """ Add_button action to add created plot in the list """ if len(self.__plot_frame) > 0: if self.__variable1_combo.get( ) != "" and self.__variable2_combo.get() != "": if self.__data_manager.manager_have_data(): plot = PlotCreator.get_instance().plot_from_fieldnames( self.__data_manager, self.__variable1_combo.get(), [self.__variable2_combo.get()]) logger.log(logging.INFO, "[MainFrame] Creating plot " + str(plot[0])) if self.__plot_frame_combo.get() == "all": for item in list(self.__plot_frame.values()): item.add_plot(plot[0]) else: self.__plot_frame[ self.__plot_frame_combo.get()].add_plot(plot[0]) else: logger.log(logging.ERROR, "[MainFrame] Data manager does not have data") else: logger.log(logging.ERROR, "[MainFrame] No variables selected") else: logger.log(logging.ERROR, "[MainFrame] No Plot frame opened") def add_plot_function(self): """ Create plot from math functions to validate data """ if len(self.__plot_frame) > 0: function_dialog = FunctionDialog(self) self.wait_window(function_dialog.top) if function_dialog.get_plot() is not None: logger.log( logging.INFO, "[MainFrame] Creating math plot " + str(function_dialog.get_plot())) if self.__plot_frame_combo.get() == "all": for item in list(self.__plot_frame.values()): item.add_plot(function_dialog.get_plot()) else: self.__plot_frame[self.__plot_frame_combo.get()].add_plot( function_dialog.get_plot()) else: logger.log(logging.ERROR, "[MainFrame] No math plot created") else: logger.log(logging.ERROR, "[MainFrame] No Plot frame opened") def clear_all_plots(self): """ Clear/reset the plot frame """ logger.log(logging.INFO, "[MainFrame] Clearing all plots") for item in list(self.__plot_frame.values()): item.clear_all_plots() def remove_all_plots(self): """ Remove all the plots from the plot list """ logger.log(logging.INFO, "[MainFrame] Remove all plots") for item in list(self.__plot_frame.values()): item.remove_all_plots()
class STKKApplication(tk.Frame): colorButtons = [] # List of the tkinter Buttons that select colors lights_buffer = [] # List of integers containing color values + 1 int header header_value = MK1_HEADER_VAL # Header value for lights buffer buffer_scale = 3 # Integer scale value for indexing into the buffer color_list = [] # List of tuples containing the currently selected colors off_color = (0x00,) # Tuple for turning off a light kb_hid_id = S61_MK1_ID # Keyboard identifier used when opening HID kb_num_keys = 61 # Number of keys on the keyboard kb_note_offset = -36 # Offset to convert MIDI note value to buffer index # Calculated as 60 - number of keys below Middle C connected = False # Boolean to indicate if currently connected listen = True # Boolean to control threaded listen loop kb_device = None # HID keyboard device handle port_name = "" # Name of LoopBe1 MIDI loopback port thread_handle = None # Handle for thread map_palette_dialog = None # Handle for Map Palette dialog map_palette_index = None # Handle for index label map_palette_color = None # Handle for color swatch map_palette_dict = None # Dictionary containing mapped palette values def __init__(self, master=None): tk.Frame.__init__(self, master) if master != None: master.title("Synthesia To Komplete Kontrol") master.geometry("640x420") self.grid(column=0, row=0) self.createWidgets() def createWidgets(self): """Creates the GUI widgets""" # Read user prefs from the .ini file uprefs = self.readUserPrefs() # Keyboard combobox label self.kb_combobox_label = tk.Label(self) self.kb_combobox_label["text"] = "Komplete Kontrol model" self.kb_combobox_label.grid(column=0, row=0, padx=10, pady=5, columnspan=2, sticky='W') # Keyboard listbox self.kb_combobox = Combobox(self) self.kb_combobox['values'] = [ "Komplete Kontrol S61 MK2", "Komplete Kontrol S88 MK2", "Komplete Kontrol S49 MK2", "Komplete Kontrol S61 MK1", "Komplete Kontrol S88 MK1", "Komplete Kontrol S49 MK1", "Komplete Kontrol S25 MK1"] self.kb_combobox.current(uprefs['selectedkeyboard']) self.kb_combobox.grid(column=0, row=1, ipadx=10, padx=10, pady=5, columnspan=2, sticky='W') # Color labels & buttons self.colors_label = tk.Label(self) self.colors_label["text"] = "Key Colors:" self.colors_label.grid(column=0, row=2, padx=10, sticky='W') self.color0_label = tk.Label(self) self.color0_label["text"] = "Default (Unknown hand/finger)" self.color0_label.grid(column=1, row=3, padx=5, sticky='W') self.color0_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(0), bg=uprefs['defaultcolor']) self.color0_button.grid(column=0, row=3, pady=1, sticky='E') self.colorButtons.append(self.color0_button) self.color1_label = tk.Label(self) self.color1_label["text"] = "Left thumb" self.color1_label.grid(column=1, row=4, padx=5, sticky='W') self.color1_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(1), bg=uprefs['leftthumb']) self.color1_button.grid(column=0, row=4, pady=1, sticky='E') self.colorButtons.append(self.color1_button) self.color2_label = tk.Label(self) self.color2_label["text"] = "Left index" self.color2_label.grid(column=1, row=5, padx=5, sticky='W') self.color2_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(2), bg=uprefs['leftindex']) self.color2_button.grid(column=0, row=5, pady=1, sticky='E') self.colorButtons.append(self.color2_button) self.color3_label = tk.Label(self) self.color3_label["text"] = "Left middle" self.color3_label.grid(column=1, row=6, padx=5, sticky='W') self.color3_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(3), bg=uprefs['leftmiddle']) self.color3_button.grid(column=0, row=6, pady=1, sticky='E') self.colorButtons.append(self.color3_button) self.color4_label = tk.Label(self) self.color4_label["text"] = "Left ring" self.color4_label.grid(column=1, row=7, padx=5, sticky='W') self.color4_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(4), bg=uprefs['leftring']) self.color4_button.grid(column=0, row=7, pady=1, sticky='E') self.colorButtons.append(self.color4_button) self.color5_label = tk.Label(self) self.color5_label["text"] = "Left pinky" self.color5_label.grid(column=1, row=8, padx=5, sticky='W') self.color5_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(5), bg=uprefs['leftpinky']) self.color5_button.grid(column=0, row=8, pady=1, sticky='E') self.colorButtons.append(self.color5_button) self.color6_label = tk.Label(self) self.color6_label["text"] = "Right thumb" self.color6_label.grid(column=3, row=4, padx=5, sticky='W') self.color6_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(6), bg=uprefs['rightthumb']) self.color6_button.grid(column=2, row=4, pady=1, sticky='E') self.colorButtons.append(self.color6_button) self.color7_label = tk.Label(self) self.color7_label["text"] = "Right index" self.color7_label.grid(column=3, row=5, padx=5, sticky='W') self.color7_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(7), bg=uprefs['rightindex']) self.color7_button.grid(column=2, row=5, pady=1, sticky='E') self.colorButtons.append(self.color7_button) self.color8_label = tk.Label(self) self.color8_label["text"] = "Right middle" self.color8_label.grid(column=3, row=6, padx=5, sticky='W') self.color8_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(8), bg=uprefs['rightmiddle']) self.color8_button.grid(column=2, row=6, pady=1, sticky='E') self.colorButtons.append(self.color8_button) self.color9_label = tk.Label(self) self.color9_label["text"] = "Right ring" self.color9_label.grid(column=3, row=7, padx=5, sticky='W') self.color9_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(9), bg=uprefs['rightring']) self.color9_button.grid(column=2, row=7, pady=1, sticky='E') self.colorButtons.append(self.color9_button) self.color10_label = tk.Label(self) self.color10_label["text"] = "Right pinky" self.color10_label.grid(column=3, row=8, padx=5, sticky='W') self.color10_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(10), bg=uprefs['rightpinky']) self.color10_button.grid(column=2, row=8, pady=1, sticky='E') self.colorButtons.append(self.color10_button) self.color11_label = tk.Label(self) self.color11_label["text"] = "Left hand (Unknown finger)" self.color11_label.grid(column=1, row=9, padx=5, sticky='W') self.color11_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(11), bg=uprefs['lefthand']) self.color11_button.grid(column=0, row=9, pady=1, sticky='E') self.colorButtons.append(self.color11_button) self.color12_label = tk.Label(self) self.color12_label["text"] = "Right hand (Unknown finger)" self.color12_label.grid(column=3, row=9, padx=5, sticky='W') self.color12_button = tk.Button(self, width=5, command=lambda:self.colorButtonClick(12), bg=uprefs['righthand']) self.color12_button.grid(column=2, row=9, pady=1, sticky='E') self.colorButtons.append(self.color12_button) # Control buttons self.connectButton = tk.Button(self, text=" Connect ", command=self.start, bg='#fefefe') self.connectButton.grid(column=0, row=10, pady=10) self.disconnectButton = tk.Button(self, text="Disconnect", command=self.stop, bg='#fefefe', state='disabled') self.disconnectButton.grid(column=1, row=10, pady=10) self.exitButton = tk.Button(self, text=" Exit ", command=self.quit, bg='#fefefe') self.exitButton.grid(column=2, row=10, pady=10) self.mapPaletteButton = tk.Button(self, text="Map Palette", state='disabled', command=self.mapPalette, bg='#fefefe') self.mapPaletteButton.grid(column=3, row=10, pady=10) def colorButtonClick(self, button_num): """Color button click handler, opens color picker to set button's color""" start_color = self.colorButtons[button_num].cget('bg') result = askcolor(start_color) if result[1]: self.colorButtons[button_num].configure(bg=result[1]) def enableGUIControls(self, enable = True): """Enable or disable GUI elements while connected""" for button in self.colorButtons: if enable: button.configure(state = 'normal') else: button.configure(state = 'disabled') if enable: self.kb_combobox.configure(state='normal') else: self.kb_combobox.configure(state='disabled') def start(self): """Connect button click handler""" if not self.connected: self.setAttributes() self.connected = self.connectToKeyboard() if self.connected: if self.findMIDIPort(): self.enableGUIControls(False) self.disconnectButton.configure(state='normal') self.mapPaletteButton.configure(state='normal') self.listen = True self.lightsOut() self.thread_handle = threading.Thread(target=self.lightKeyboardThread, args=()) self.thread_handle.daemon = True self.thread_handle.start() else: self.kb_device.close() self.connected = False def stop(self): """Disconnect button click handler""" self.listen = False self.connected = False # Disconnect from keyboard is handled in thread self.thread_handle.join() self.thread_handle = None self.enableGUIControls() self.mapPaletteButton.configure(state='disabled') self.disconnectButton.configure(state='disabled') def quit(self): """Exit button click handler""" self.listen = False self.writeUserPrefs() if self.thread_handle: self.thread_handle.join() if self.map_palette_dialog: self.map_palette_dialog.destroy() root.destroy() def setAttributes(self): """Sets the object's attributes based on KK model""" # Get the index of the currently selected keyboard selected = self.kb_combobox.current() # Setup variables according to keyboard model if selected == 0: # Komplete Kontrol S61 MK2 self.kb_num_keys = 61 self.kb_note_offset = -36 self.kb_hid_id = S61_MK2_ID self.header_value = MK2_HEADER_VAL self.buffer_scale = 1 self.off_color = (0x00,) self.color_list = self.ButtonsToPaletteColorList() elif selected == 1: # Komplete Kontrol S88 MK2 self.kb_num_keys = 88 self.kb_note_offset = -21 self.kb_hid_id = S88_MK2_ID self.header_value = MK2_HEADER_VAL self.buffer_scale = 1 self.off_color = (0x00,) self.color_list = self.ButtonsToPaletteColorList() elif selected == 2: # Komplete Kontrol S49 MK2 self.kb_num_keys = 49 self.kb_note_offset = -36 self.kb_hid_id = S49_MK2_ID self.header_value = MK2_HEADER_VAL self.buffer_scale = 1 self.off_color = (0x00,) self.color_list = self.ButtonsToPaletteColorList() elif selected == 3: # Komplete Kontrol S61 MK1 self.kb_num_keys = 61 self.kb_note_offset = -36 self.kb_hid_id = S61_MK1_ID self.header_value = MK1_HEADER_VAL self.buffer_scale = 3 self.off_color = (0x00,0x00,0x00) self.color_list = self.ButtonsToRGBColorList() elif selected == 4: # Komplete Kontrol S88 MK1 self.kb_num_keys = 88 self.kb_note_offset = -21 self.kb_hid_id = S88_MK1_ID self.header_value = MK1_HEADER_VAL self.buffer_scale = 3 self.off_color = (0x00,0x00,0x00) self.color_list = self.ButtonsToRGBColorList() elif selected == 5: # Komplete Kontrol S49 MK1 self.kb_num_keys = 49 self.kb_note_offset = -36 self.kb_hid_id = S49_MK1_ID self.header_value = MK1_HEADER_VAL self.buffer_scale = 3 self.off_color = (0x00,0x00,0x00) self.color_list = self.ButtonsToRGBColorList() elif selected == 6: # Komplete Kontrol S25 MK1 self.kb_num_keys = 25 self.kb_note_offset = -48 self.kb_hid_id = S25_MK1_ID self.header_value = MK1_HEADER_VAL self.buffer_scale = 3 self.off_color = (0x00,0x00,0x00) self.color_list = self.ButtonsToRGBColorList() else: return False # Create the buffer for the color values self.lights_buffer = [0x00] * (self.kb_num_keys * self.buffer_scale + 1) self.lights_buffer[0] = self.header_value return True def connectToKeyboard(self): """Attempts to connect to keyboard as HID""" self.kb_device=hid.device() try: self.kb_device.open(NI_HID_ID, self.kb_hid_id) except Exception as e: showerror("Could not connect to KK", 'Connection error: ' + str(e)) return False # Set the keyboard to receive Light Guide data self.kb_device.write([LIGHT_GUIDE_CMD]) return True def findMIDIPort(self): """Looks for the LoopBe1 MIDI port""" ports = mido.get_input_names() for port in ports: if "LoopBe" in port: self.port_name = port if self.port_name == "": showerror("MIDI Port Error", "Please install LoopBe1 from http://www.nerds.de/en/download.html.") return False return True def lightsOut(self): """Turn off all lights""" for i in range(1, len(self.lights_buffer)): self.lights_buffer[i] = 0x00 self.kb_device.write(self.lights_buffer) def MIDIMsgToLightGuide(self, note, status, channel, velocity): """Use MIDI messages to update KK's Light Guide""" # Turn off light if status == 'note_off': self.writeColorToBuffer(self.off_color, note + self.kb_note_offset) # Turn on light elif status == 'note_on' and channel >= 0 and channel < len(self.color_list): self.writeColorToBuffer(self.color_list[channel], note + self.kb_note_offset) # Write the buffer to the keyboard device self.kb_device.write(self.lights_buffer) def writeColorToBuffer(self, color, index): """Writes a color to the lights buffer - color should be a tuple - index should be an int between 0 and (number of keys - 1), inclusive""" # Calculate the index for the lights buffer index = 1 + (index * self.buffer_scale) # Check the index is within range of the buffer if index < 1 or index > (len(self.lights_buffer) - self.buffer_scale): return # Write the color value to the lights buffer for color_val in color: self.lights_buffer[index] = color_val index += 1 def krSweep(self, loopcount): """Performs a red light sweep across Light Guide""" speed = 0.01 if self.buffer_scale == 3: color1 = (0x7F, 0x00, 0x00) color2 = (0x3F, 0x00, 0x00) color3 = (0x0F, 0x00, 0x00) else: color1 = (0x07,) color2 = (0x05,) color3 = (0x04,) while loopcount > 0: # Forward for x in range(0, self.kb_num_keys): for i in range(1, len(self.lights_buffer)): self.lights_buffer[i] = 0x00 self.writeColorToBuffer(color1, x) if x + 1 < self.kb_num_keys: self.writeColorToBuffer(color2, x + 1) if x + 2 < self.kb_num_keys: self.writeColorToBuffer(color3, x + 2) if x - 1 >= 0: self.writeColorToBuffer(color2, x - 1) if x - 2 >= 0: self.writeColorToBuffer(color3, x - 2) self.kb_device.write(self.lights_buffer) time.sleep(speed) # Backward for x in range(self.kb_num_keys - 1, -1, -1): for i in range(1, len(self.lights_buffer)): self.lights_buffer[i] = 0x00 self.writeColorToBuffer(color1, x) if x + 1 < self.kb_num_keys: self.writeColorToBuffer(color2, x + 1) if x + 2 < self.kb_num_keys: self.writeColorToBuffer(color3, x + 2) if x - 1 >= 0: self.writeColorToBuffer(color2, x - 1) if x - 2 >= 0: self.writeColorToBuffer(color3, x - 2) self.kb_device.write(self.lights_buffer) time.sleep(speed) loopcount -= 1 self.lightsOut() def lightKeyboardThread(self): """Threaded method to update KK Light Guide""" self.krSweep(2) midiPort = mido.open_input(self.port_name) while self.listen: for message in midiPort.iter_pending(): if message.type in ('note_on', 'note_off'): self.MIDIMsgToLightGuide(message.note, message.type, message.channel, message.velocity) self.lightsOut() self.kb_device.close() midiPort.close() def readUserPrefs(self): """Reads user preferences from STKKConfig.ini""" prefs = {} prefs_file = cfg.ConfigParser() files = prefs_file.read('STKKConfig.ini') if len(files) == 1 and 'UserPrefs' in prefs_file: up = prefs_file['UserPrefs'] prefs['selectedkeyboard'] = up.getint('selectedkeyboard', fallback=3) prefs['defaultcolor'] = up.get('defaultcolor', fallback='#ff0000') prefs['leftthumb'] = up.get('leftthumb', fallback='#00ff00') prefs['leftindex'] = up.get('leftindex', fallback='#00ff00') prefs['leftmiddle'] = up.get('leftmiddle', fallback='#00ff00') prefs['leftring'] = up.get('leftring', fallback='#00ff00') prefs['leftpinky'] = up.get('leftpinky', fallback='#00ff00') prefs['lefthand'] = up.get('lefthand', fallback='#00ff00') prefs['rightthumb'] = up.get('rightthumb', fallback='#0000ff') prefs['rightindex'] = up.get('rightindex', fallback='#0000ff') prefs['rightmiddle'] = up.get('rightmiddle', fallback='#0000ff') prefs['rightring'] = up.get('rightring', fallback='#0000ff') prefs['rightpinky'] = up.get('rightpinky', fallback='#0000ff') prefs['righthand'] = up.get('righthand', fallback='#0000ff') else: # STKKConfig.ini not found, set defaults prefs['selectedkeyboard'] = 3 prefs['defaultcolor'] = '#ff0000' prefs['leftthumb'] = '#00ffff' prefs['leftindex'] = '#0099ff' prefs['leftmiddle'] = '#0000ff' prefs['leftring'] = '#6600ff' prefs['leftpinky'] = '#ff00ff' prefs['lefthand'] = '#0000ff' prefs['rightthumb'] = '#ff8000' prefs['rightindex'] = '#ffd900' prefs['rightmiddle'] = '#b3ff00' prefs['rightring'] = '#00ff00' prefs['rightpinky'] = '#00ffbf' prefs['righthand'] = '#00ff00' return prefs def writeUserPrefs(self): """Writes user preferences to STKKConfig.ini""" config = cfg.ConfigParser() config['UserPrefs'] = {} up = config['UserPrefs'] up['selectedkeyboard'] = str(self.kb_combobox.current()) up['defaultcolor'] = self.colorButtons[0].cget('bg') up['leftthumb'] = self.colorButtons[1].cget('bg') up['leftindex'] = self.colorButtons[2].cget('bg') up['leftmiddle'] = self.colorButtons[3].cget('bg') up['leftring'] = self.colorButtons[4].cget('bg') up['leftpinky'] = self.colorButtons[5].cget('bg') up['lefthand'] = self.colorButtons[11].cget('bg') up['rightthumb'] = self.colorButtons[6].cget('bg') up['rightindex'] = self.colorButtons[7].cget('bg') up['rightmiddle'] = self.colorButtons[8].cget('bg') up['rightring'] = self.colorButtons[9].cget('bg') up['rightpinky'] = self.colorButtons[10].cget('bg') up['righthand'] = self.colorButtons[12].cget('bg') with open('STKKConfig.ini', 'w') as configfile: config.write(configfile) def ButtonsToRGBColorList(self): """Takes the attribute list of color Buttons and returns a list of 7-bit RGB tuples containing their background colors""" colors = [] for button in self.colorButtons: if isinstance(button, tk.Button): colors.append(RGBStringToTuple(button.cget('bg'))) return colors def ButtonsToPaletteColorList(self): """Takes the attribute list of color Buttons and returns a list of one element tuples containing their background colors mapped to palette indices""" colors = [] # Load the palette map from the .ini file prefs_file = cfg.ConfigParser() files = prefs_file.read('PaletteMap.ini') # If the .ini contains the palette map, map # button background colors to palette if len(files) == 1 and 'PaletteMap' in prefs_file: palette_map = prefs_file['PaletteMap'] for button in self.colorButtons: if isinstance(button, tk.Button): colors.append(mapRGBStringToPalette(button.cget('bg'), palette_map)) else: # Palette map not loaded, map to arbitrary colors colors.append((0x07,)) colors.append((0x2D,)) colors.append((0x2F,)) colors.append((0x2F,)) colors.append((0x2F,)) colors.append((0x2F,)) colors.append((0x1F,)) colors.append((0x1B,)) colors.append((0x1B,)) colors.append((0x1B,)) colors.append((0x1B,)) colors.append((0x2F,)) colors.append((0x1B,)) return colors ### # Map Palette methods ### def mapPalette(self): """Map Palette button click handler""" # If the keyboard is not connected, show an error if not self.connected: showerror(title='Not Connected', message='Connect to keyboard before mapping palette') return # If the buffer scale is 3, assume this is a MK1 keyboard # and show an error if self.buffer_scale == 3: showerror(title="Unmappable", message="MK1 keyboards do not need to be mapped") return # Disable buttons self.enableGUIControls(False) self.disconnectButton.configure(state='disabled') self.mapPaletteButton.configure(state='disabled') # If the palette dialog doesn't exist, create it if not self.map_palette_dialog: # Create window self.map_palette_dialog = tk.Toplevel(self) self.map_palette_dialog.title('Map MK2 Palette') # Create labels valueLabel = tk.Label(self.map_palette_dialog) valueLabel["text"] = "Index:" valueLabel.grid(column=0, row=0, padx=5, pady=10, sticky='E') colorLabel = tk.Label(self.map_palette_dialog) colorLabel["text"] = "Color:" colorLabel.grid(column=2, row=0, padx=5, pady=10, sticky='W') #Create index and color displays self.map_palette_index = tk.Label(self.map_palette_dialog) self.map_palette_index["text"] = "0x01" self.map_palette_index.grid(column=1, row=0, sticky='W') self.map_palette_color = tk.Button(self.map_palette_dialog, width=8, state='disabled', bg='#000000') self.map_palette_color.grid(column=3, row=0, padx=2, sticky='W') # Create buttons previousButton = tk.Button(self.map_palette_dialog, text="< Prev", command=self.mapPalettePrev, bg='#fefefe') previousButton.grid(column=0, row=2, sticky='E') nextButton = tk.Button(self.map_palette_dialog, text="Next >", command=self.mapPaletteNext, bg='#fefefe') nextButton.grid(column=1, row=2, sticky='W') setButton = tk.Button(self.map_palette_dialog, text="Set Color", command=self.mapPaletteSetColor, bg='#fefefe') setButton.grid(column=3, row=2, sticky='W') saveButton = tk.Button(self.map_palette_dialog, text=" Save ", command=self.mapPaletteSave, bg='#fefefe') saveButton.grid(column=0, row=3, padx=10, pady=10, sticky='W') cancelButton = tk.Button(self.map_palette_dialog, text="Cancel", command=self.mapPaletteCancel, bg='#fefefe') cancelButton.grid(column=1, row=3, padx=10, sticky='W') # Capture the Close Window event and # map it to the Cancel button handler self.map_palette_dialog.protocol("WM_DELETE_WINDOW", self.mapPaletteCancel) elif self.map_palette_dialog.state() == 'iconic': # Else show the window self.map_palette_dialog.deiconify() # If there is no palette map dictionary if not self.map_palette_dict: # Try to load the palette map from the .ini file prefs_file = cfg.ConfigParser() files = prefs_file.read('PaletteMap.ini') # If the .ini contains the palette map, set the dictionary if len(files) == 1 and 'PaletteMap' in prefs_file: self.map_palette_dict = prefs_file['PaletteMap'] else: # Else create a new dictionary self.map_palette_dict = {} # Display the current palette map color in the dialog self.showCurrentMapColor() def showCurrentMapColor(self): """Displays the color of the current index in the map palette dialog""" # Get the current palette index from the dialog currentIndex = self.map_palette_index.cget('text') currentColor = '#000000' # Read the currently mapped color if the palette map dictionary exists if self.map_palette_dict: if currentIndex in self.map_palette_dict: currentColor = self.map_palette_dict[currentIndex] # Display the color in the dialog self.map_palette_color.configure(bg=currentColor) # Display the palette index on the keyboard self.displayPaletteIndex(currentIndex) def displayPaletteIndex(self, index): """Displays the palette index on the keyboard""" # Make sure the keyboard is connected if not self.connected: return # If the passed index is not an int, convert it if not isinstance(index, int): index = int(index, 16) # Create the tuple indexTuple = (index,) # Display the palette index in the first 12 keys for i in range(0, 12): self.writeColorToBuffer(indexTuple, i) self.kb_device.write(self.lights_buffer) def mapPalettePrev(self): """Map Palette dialog Prev button handler""" # Read the current index from the dialog currentIndex = self.map_palette_index.cget('text') # Convert the index to an int currentIndex = int(currentIndex, 16) # If the index is > 1 if currentIndex > 1: # Decrement the index currentIndex -= 1 # Update the dialog and keyboard currentIndex = '0x' + ("%02x" % (currentIndex,)) self.map_palette_index.configure(text=currentIndex) self.showCurrentMapColor() def mapPaletteNext(self): """Map Palette dialog Next button handler""" # Read the current index from the dialog currentIndex = self.map_palette_index.cget('text') # Convert the index to an int currentIndex = int(currentIndex, 16) # If the index is < 255 if currentIndex < 255: # Increment the index currentIndex += 1 # Update the dialog and keyboard currentIndex = '0x' + ("%02x" % (currentIndex,)) self.map_palette_index.configure(text=currentIndex) self.showCurrentMapColor() def mapPaletteSetColor(self): """Map Palette dialog Set Color button handler""" # Get the current color from the dialog currentColor = self.map_palette_color.cget('bg') # Show the color picker result = askcolor(currentColor, parent=self.map_palette_dialog) # If a color was selected if result[1]: # Update the dialog with the new color self.map_palette_color.configure(bg=result[1]) # Get the current index from the dialog currentIndex = self.map_palette_index.cget('text') # Store in the palette map dictionary self.map_palette_dict[currentIndex] = result[1] def mapPaletteSave(self): """Map Palette dialog Save button handler""" # Create a ConfigParser config = cfg.ConfigParser() # Set the palette map dictionary config['PaletteMap'] = self.map_palette_dict # Write the palette map to the config file with open('PaletteMap.ini', 'w') as configfile: config.write(configfile) # Turn off keyboard lights self.lightsOut() # Enable buttons self.enableGUIControls() self.disconnectButton.configure(state='normal') self.mapPaletteButton.configure(state='normal') # Destroy the Map Palette dialog self.map_palette_dialog.destroy() self.map_palette_dialog = None def mapPaletteCancel(self): """Map Palette dialog Cancel button handler""" # Turn off keyboard lights self.lightsOut() # Enable buttons self.enableGUIControls() self.disconnectButton.configure(state='normal') self.mapPaletteButton.configure(state='normal') # Destroy the Map Palette dialog self.map_palette_dialog.destroy() self.map_palette_dialog = None
class paper_trade: def __init__(self, window:Tk)->None: self.imp_strikes: List[float] = [] self.imp_my_buy_price: List[float] = [] self.nse_adapter = OC_DATA() self.stop = False self.my_atm: float = 0.0 self.interval = 10. self.first_run = True self.buy_pe_limit: List[float] = [] self.sell_pe_limit: List[float] = [] self.sell_ce_limit: List[float] = [] self.buy_ce_limit: List[float] = [] self.market_price: List[float] = [] self.vix_percentage = 2 self.my_buy_price = [] self.strategies: List[String] = ['IRON CONDOR'] self.sh_cols: List[List[String]] = [['Instrument','Qty','My_price','LTP','P&L']] self.indices: List[str] = ['NIFTY','BANKNIFTY','RELIANCE','ASHOKLEY','TATAMOTORS','SBIN'] self.indices_lot: dict[str,str]={'NIFTY':'75','BANKNIFTY':'25','RELIANCE':'505','ASHOKLEY':'9000','TATAMOTORS':'5700', \ 'SBIN':'3000'} self.symb_lot_dict: dict[str,List[str]] = {} self.symb_lot_dict['SYMBOLS'] = ['NIFTY','BANKNIFTY','RELIANCE'] self.symb_lot_dict['LOT_SIZE'] = ['75','25'] self.setup_main_window(window) def setup_main_window(self,window)->None: self.sh_window: Tk = window self.sh_window.title('Paper trading') window_width: int = self.sh_window.winfo_reqwidth() window_height: int = self.sh_window.winfo_reqheight() position_right: int = int(self.sh_window.winfo_screenwidth() / 2 - window_width / 2) position_down: int = int(self.sh_window.winfo_screenheight() / 2 - window_height / 2) self.sh_window.geometry("1000x800+300+100") self.sh_window.grid_rowconfigure(0, weight=0) self.sh_window.grid_columnconfigure(0, weight=1) rh = self.sh_window.winfo_height() rw = self.sh_window.winfo_width() #self.sh_window.configure(width=1200,height=800) #self.sh_window.grid_propagate(0) pdx = 5 pdy = 5 row_idx = 0 top_frame: Frame = Frame(self.sh_window,width=rw,height=.1*rh) #top_frame.pack(anchor='nw',fill='both', expand=True, side=TOP) top_frame.grid(row=0,column=0,sticky='nsew') #top_frame.grid_rowconfigure(0, weight=0) #top_frame.grid_columnconfigure(0, weight=0) #top_frame.grid_propagate(1) #top_frame.configure(height=500) var_stock: StringVar = StringVar() var_stock.set(" ") lbl_stock: Label = Label(top_frame,text='Symbol',justify=LEFT,font=("TkDefaultFont", 10,"bold"),width=10) #lbl_stock.pack(anchor=N, expand=False, side=LEFT) lbl_stock.grid(row=0,column=0,sticky='nw',padx=pdx,pady=pdy) self.combo_box_stock = Combobox(top_frame,width=10,textvariable=var_stock) #self.combo_box_stock.pack(anchor=N, expand=False, side=LEFT) self.combo_box_stock.grid(row=0,column=1,sticky='nw',padx=pdx,pady=pdy) self.combo_box_stock.configure(state='readonly') self.combo_box_stock['values'] = self.indices self.combo_box_stock.bind('<<ComboboxSelected>>', self.set_expiry_date) date_var_stock: StringVar = StringVar() date_var_stock.set(" ") lbl_exp_date_stock: Label = Label(top_frame,text='Expiry',justify=LEFT,font=("TkDefaultFont", 10,"bold"),width=10) #lbl_exp_date_stock.pack(anchor=N, expand=False, side=LEFT) lbl_exp_date_stock.grid(row=1,column=0,sticky=N+S+W,padx=pdx,pady=pdy) self.date_combo_box_stock = Combobox(top_frame,width=10,textvariable=date_var_stock) #self.date_combo_box_stock.pack(anchor=N, expand=False, side=LEFT) self.date_combo_box_stock.grid(row=1,column=1,sticky=N+S+W,padx=pdx,pady=pdy) self.date_combo_box_stock.configure(state='readonly') self.date_combo_box_stock.bind('<<ComboboxSelected>>', self.set_expiry_date) # var_lot_size: StringVar = StringVar() var_lot_size.set(" ") lbl_lot_size: Label = Label(top_frame,text='Qty',justify=LEFT,font=("TkDefaultFont", 10, "bold")) #lbl_lot_size.pack(anchor=N, expand=False, side=LEFT) lbl_lot_size.grid(row=0,column=2,sticky=N+S+W,padx=pdx,pady=pdy) self.qty_combo_box = Combobox(top_frame,width=10,textvariable=var_lot_size) #self.qty_combo_box.pack(anchor=N, expand=False, side=LEFT) self.qty_combo_box.configure(state='readonly') self.qty_combo_box.grid(row=0,column=3,sticky=N+S+W,padx=pdx,pady=pdy) var_vix: StringVar = StringVar() var_vix.set(" ") lbl_vix: Label = Label(top_frame,text='VIX',justify=LEFT,font=("TkDefaultFont", 10, "bold")) #lbl_vix.pack(anchor=N, expand=False, side=LEFT) lbl_vix.grid(row=1,column=2,sticky=N+S+W,padx=pdx,pady=pdy) self.vix_combo_box = Combobox(top_frame,width=10,textvariable=var_vix) #self.vix_combo_box.pack(anchor=N, expand=False, side=LEFT) self.vix_combo_box.grid(row=1,column=3,sticky=N+S+W,padx=pdx,pady=pdy) self.vix_combo_box.configure(state='readonly') self.vix_combo_box['values'] = list(map(lambda x: x/10.0, range(5, 100, 5))) self.vix_combo_box.bind('<<ComboboxSelected>>', self.set_VIX) self.start_button: Button = tk.Button(top_frame,text='Trade',command=self.main_recursive,width=10,bg='green',fg='white',font=("TkDefaultFont", 10, "bold")) #self.start_button.pack(anchor=N, expand=False, side=LEFT) self.start_button.grid(row=0,column=4,sticky=N+S+W)#,padx=pdx,pady=pdy) self.start_button.configure(state='disabled') self.import_button: Button = tk.Button(top_frame,text='Manual',command=self.import_iron_condor,width=10,bg='red',fg='white',font=("TkDefaultFont", 10, "bold")) #self.import_button.pack(anchor=N, expand=False, side=LEFT) self.import_button.grid(row=0,column=5,sticky=N+S+W)#,padx=pdx,pady=pdy) self.import_button.configure(state='disabled') self.load_button: Button = tk.Button(top_frame,text='Load trade',command=self.load_file,width=10,bg='yellow',fg='black',font=("TkDefaultFont", 10, "bold")) self.load_button.grid(row=1,column=4,sticky=N+S+W+E) self.load_button.configure(state='normal') self.lbl_nse_con_time: Label = Label(top_frame,text=' ',justify=LEFT,font=("TkDefaultFont", 10, "bold")) #self.lbl_nse_con_time.pack(anchor=N, expand=False, side=LEFT) self.lbl_nse_con_time.grid(row=0,column=6,sticky=N+S+W+E) bot_frame: Frame = Frame(self.sh_window,width=1200,height=.3*rh) #bot_frame.pack(anchor='nw', fill='both',expand=True, side=TOP) bot_frame.grid(row=1,column=0,sticky='nsew') #bot_frame.grid_rowconfigure(0, weight=1) #bot_frame.grid_columnconfigure(0, weight=1) #bot_frame.grid_propagate(0) self.plot_frame: Frame = Frame(self.sh_window,width=1200, height=.6*rh) #self.plot_frame.pack(anchor='nw', fill='both',expand=True, side=TOP) self.plot_frame.grid(row=2,column=0,sticky="nsew") #self.plot_frame.grid_rowconfigure(0, weight=1) #self.plot_frame.grid_columnconfigure(0, weight=1) #self.plot_frame.grid_propagate(0) fig = Figure(figsize = (2, 2), dpi = 200) self.plot1 = fig.add_subplot(111) self.plot1.tick_params(axis='both', which='minor', labelsize=8) self.canvas = FigureCanvasTkAgg(fig,master = self.plot_frame) self.canvas.get_tk_widget().pack(anchor=N,fill='both',expand=True) self.NB: Notebook = Notebook(bot_frame) self.NB.pack(anchor=N,fill="both", expand=True) self.NBF: List[Frame] = [] self.NBS: List[tksheet.Sheet] = [] self.NB_DF: List[pd.Dataframe] = [] for strat in enumerate(self.strategies): self.NBF.append(Frame(self.NB)) self.NB.add(self.NBF[-1],text=strat[1]) sh = tksheet.Sheet(self.NBF[-1], column_width=100, align="center", headers = self.sh_cols[strat[0]], header_font=("TkDefaultFont", 10, "bold"), empty_horizontal=0, empty_vertical=20, header_height=35) sh.enable_bindings( ("toggle_select", "drag_select", "column_select", "row_select", "column_width_resize", "arrowkeys", "right_click_popup_menu", "rc_select", "copy", "select_all")) sh.pack(anchor=W,fill="both", expand=True) #sh.change_theme("dark") self.NBS.append(sh) def export_iron_condor(self): self.imp_strikes.clear() self.imp_my_buy_price.clear() for i in enumerate(self.imp_cbox): if(i[1].get()==""): break self.imp_strikes.append(float(i[1].get())) self.imp_my_buy_price.append(float(self.imp_tbox[i[0]].get('1.0',END))) df_export: pd.DataFrame = pd.DataFrame() df_export['Strikes'] = self.imp_strikes df_export['Buy_price'] = self.imp_my_buy_price save_name = self.combo_box_stock.get()+'-'+self.date_combo_box_stock.get()+'-'+datetime.now().strftime("%H:%M:%S") df_export.to_csv(save_name+'.csv') self.imp_wd.destroy() self.import_button.configure(state='disabled') def save_current_data(self): save_name = self.combo_box_stock.get()+'_'+self.date_combo_box_stock.get()+'_'+date.today().strftime("%b-%d-%Y")+'.csv' if(not path.exists(save_name)): df_export: pd.DataFrame = pd.DataFrame() df_export['Strikes'] = self.df['Instrument'] df_export['Buy_price'] = self.df['My_price'] df_export['Qty'] = [(self.df['Qty'].tolist())[0]]*5 df_export.to_csv(save_name) def load_file(self): file = askopenfile(mode ='r', filetypes =[('CSV files', '*.csv')]) self.df_loaded: pd.DataFrame = pd.read_csv(file.name) self.imp_strikes = self.df_loaded['Strikes'].tolist() self.imp_my_buy_price = self.df_loaded['Buy_price'].tolist() qty = (self.df_loaded['Qty'].tolist())[0] name_split = (os.path.basename(file.name)).split('_') print(name_split) self.combo_box_stock.set(name_split[0]) self.date_combo_box_stock.set(name_split[1]) self.qty_combo_box.set(qty) self.nse_adapter.set_stock(self.combo_box_stock.get()) self.main_recursive() def open_file(self): file = askopenfile(mode ='r', filetypes =[('CSV files', '*.csv')]) #if file is not None: # content = file.read() # print(content) self.df_loaded: pd.DataFrame = pd.read_csv(file.name) self.imp_strikes = self.df_loaded['Strikes'].tolist() self.imp_my_buy_price = self.df_loaded['Buy_price'].tolist() self.imp_wd.destroy() self.import_button.configure(state='disabled') def import_iron_condor(self): self.imp_wd: Tk = Tk() self.imp_wd.title('Paper trading') window_width: int = self.imp_wd.winfo_reqwidth() window_height: int = self.imp_wd.winfo_reqheight() position_right: int = int(self.imp_wd.winfo_screenwidth() / 2 - window_width / 2) position_down: int = int(self.imp_wd.winfo_screenheight() / 2 - window_height / 2) self.imp_wd.geometry("600x300+300+200") bot_frame: Frame = Frame(self.imp_wd,width=800, height=300) bot_frame.pack(anchor='nw', fill='both',expand=True, side=TOP) bot_frame.pack_propagate(0) json_data = self.nse_adapter.get_oc_data() match_date = self.date_combo_box_stock.get() strike_prices: List[float] = [data['strikePrice'] for data in json_data['records']['data'] \ if (str(data['expiryDate']).lower() == str(match_date).lower())] self.imp_cbox: List[Combobox] = [] self.imp_tbox: List[tk.Text] = [] imp_vars: List[StringVar] = [] imp_lbls: List[Label] = [] imp_lbls_txt: List[Label] = ['buy PUT','sell PUT','sell CALL','buy CALL'] imp_lbls_color: List[Label] = ['green','red','red','green'] row_idx = 0 for i in enumerate(imp_lbls_txt): str_var = StringVar() str_var.set(' ') lbl: Label = Label(bot_frame,text=i[1],justify=LEFT,font=("TkDefaultFont", 10,"bold"),fg=imp_lbls_color[i[0]],width=20) lbl.grid(row=i[0],column=0,sticky=N+S+W) cb = Combobox(bot_frame,width=10,textvariable=str_var) cb.grid(row=i[0],column=1,sticky=N+S+W) cb.configure(state='readonly') cb['values'] = strike_prices self.imp_cbox.append(cb) txt = tk.Text(bot_frame,width=10,bg='yellow',height=2) txt.grid(row=i[0],column=2,sticky=N+S+W) self.imp_tbox.append(txt) row_idx = i[0]+1 ok_button: Button = tk.Button(bot_frame,text='OK!',command=self.export_iron_condor,width=20,bg='green',fg='white',font=("TkDefaultFont", 10, "bold")) ok_button.grid(row=row_idx,column=4,sticky=N+S+W) load_button: Button = tk.Button(bot_frame,text='Load',command=self.open_file,width=20,bg='green',fg='white',font=("TkDefaultFont", 10, "bold")) load_button.grid(row=row_idx+1,column=4,sticky=N+S+W) def set_VIX(self,event): self.vix_percentage = float(self.vix_combo_box.get()) def set_expiry_date(self,event): self.nse_adapter.set_stock(self.combo_box_stock.get()) self.nse_adapter.get_expiry_dates() self.date_combo_box_stock['values'] = tuple(self.nse_adapter.expiry_dates) self.date_combo_box_stock.set(self.nse_adapter.expiry_dates[0]) qtys = [x*int(self.indices_lot[self.combo_box_stock.get()]) for x in range(1,11)] self.qty_combo_box['values'] = qtys self.qty_combo_box.set(qtys[0]) self.start_button.configure(state='normal') self.import_button.configure(state='normal') def main_recursive(self)->None: if(self.first_run): self.start_button.configure(state='disabled') self.combo_box_stock.configure(state='disabled') self.date_combo_box_stock.configure(state='disabled') self.qty_combo_box.configure(state='disabled') self.refresh_data() self.first_run = False self.curr_time = time.time() time_passed = int(self.curr_time-self.prev_time) if(time_passed>=self.interval): self.refresh_data() else: self.sh_window.after((10 * 1000),self.main_recursive) return if(not self.stop): self.sh_window.after((10 * 1000),self.main_recursive) return def refresh_data(self): for strat in enumerate(self.strategies): curr_sh = self.NBS[strat[0]] if(strat[1]=='IRON CONDOR'): df = self.df_iron_condor() for col in enumerate(df.columns): curr_sh.set_column_data(col[0],values=df[col[1]]) for i in range(curr_sh.get_total_rows()): if(float(curr_sh.get_cell_data(i,len(df.columns)-1))<=0.0): curr_sh.highlight_cells(row=i, column=len(df.columns)-1, bg='white',fg='red') if(float(curr_sh.get_cell_data(i,len(df.columns)-1))>0.0): curr_sh.highlight_cells(row=i, column=len(df.columns)-1, bg='green',fg='white') self.prev_time = time.time() curr_sh.refresh() def df_iron_condor(self): df: pd.DataFrame = pd.DataFrame() df_graph: pd.DataFrame = pd.DataFrame() buy_pe_pl: List[float] = [] sell_pe_pl: List[float] = [] sell_ce_pl: List[float] = [] buy_ce_pl: List[float] = [] start = time.time() json_data = self.nse_adapter.get_oc_data() end = time.time(); strr = "NSE response time (sec) : " + str(round(end-start,2)) + " ( " + str(self.nse_adapter.con_trial) + " hits)" self.lbl_nse_con_time.config(text=strr) match_date = self.date_combo_box_stock.get() print(match_date) strike_prices: List[float] = [data['strikePrice'] for data in json_data['records']['data'] \ if (str(data['expiryDate']).lower() == str(match_date).lower())] ce_values: List[dict] = [data['CE'] for data in json_data['records']['data'] \ if "CE" in data and (str(data['expiryDate'].lower()) == str(match_date.lower()))] pe_values: List[dict] = [data['PE'] for data in json_data['records']['data'] \ if "PE" in data and (str(data['expiryDate'].lower()) == str(match_date.lower()))] ce_data: pd.DataFrame = pd.DataFrame(ce_values) pe_data: pd.DataFrame = pd.DataFrame(pe_values) #print(list(ce_data.columns)) pe_otm_data: pd.DataFrame = pd.DataFrame() ce_otm_data: pd.DataFrame = pd.DataFrame() df_call_buy: pd.DataFrame = pd.DataFrame() strike_diff: List[float] = [] curr_price = ce_data['underlyingValue'][0] self.sh_window.title('Paper trading-->'+self.combo_box_stock.get()+' ('+str(curr_price)+' ) last updated @--'+datetime.now().strftime("%H:%M:%S")) if(self.first_run): diff = [abs(x-curr_price) for x in strike_prices] min_pos = diff.index(min(diff)) self.my_atm = strike_prices[min_pos] strike_diff = list(map(lambda x:x-self.my_atm,strike_prices)) iron_condor_strikes: List[float] = [] if(len(self.imp_strikes)==0): search_strike = (1-(self.vix_percentage/100.))*self.my_atm diff = [abs(x-search_strike) for x in strike_prices] min_pos = diff.index(min(diff)) sell_pe_idx = min_pos buy_pe_idx = sell_pe_idx-1 iron_condor_strikes.append(buy_pe_idx)#buy_pe_strike iron_condor_strikes.append(sell_pe_idx)#sell_pe_strike pe_otm_data = pe_data.iloc[iron_condor_strikes] iron_condor_strikes.clear() search_strike = (1+(self.vix_percentage/100.))*self.my_atm diff = [abs(x-search_strike) for x in strike_prices] min_pos = diff.index(min(diff)) sell_ce_idx = min_pos iron_condor_strikes.append(min_pos)#sell_ce_strike buy_ce_idx = sell_ce_idx + 1 iron_condor_strikes.append(buy_ce_idx)#buy_ce_strike ce_otm_data = ce_data.iloc[iron_condor_strikes] else: iron_condor_strikes.append(strike_prices.index(self.imp_strikes[0])) iron_condor_strikes.append(strike_prices.index(self.imp_strikes[1])) pe_otm_data = pe_data.iloc[iron_condor_strikes] buy_pe_idx = iron_condor_strikes[0] sell_pe_idx = iron_condor_strikes[1] iron_condor_strikes.clear() iron_condor_strikes.append(strike_prices.index(self.imp_strikes[2])) iron_condor_strikes.append(strike_prices.index(self.imp_strikes[3])) ce_otm_data = ce_data.iloc[iron_condor_strikes] sell_ce_idx = iron_condor_strikes[0] buy_ce_idx = iron_condor_strikes[1] self.my_buy_price = self.imp_my_buy_price pd_concat = pd.concat([pe_otm_data,ce_otm_data],axis=0) sell_buy_signs = [1.,-1.,-1.,1.] lot_list = [float(self.qty_combo_box.get())]*4 qty_list = list(map(mul,lot_list,sell_buy_signs)) ltp_list = list(map(float,pd_concat['lastPrice'].tolist())) if(self.first_run and len(self.imp_strikes)==0): self.my_buy_price = pd_concat['lastPrice'].tolist() net_points: List[float] = list(map(mul,sell_buy_signs,self.my_buy_price)) net_points = list(map(lambda x: x*-1,net_points)) tt = list(map(sub,ltp_list,self.my_buy_price)) df['Instrument'] = pd_concat['strikePrice'].tolist() df['Qty'] = qty_list df['My_price'] = list(map(float,self.my_buy_price)) df['LTP'] = ltp_list df['P&L'] = list(map(mul,tt,qty_list)) df['P&L'] = df['P&L'].round(3) total_row = {'Instrument':' ','Qty':' ','My_price':str(round(sum(net_points),2)),'LTP':'Total ','P&L':df['P&L'].sum()} df = df.append(total_row,ignore_index=True) for i in range(len(strike_prices)): if(i>=buy_pe_idx): val = -self.my_buy_price[0] else: val = abs(strike_prices[i]-strike_prices[buy_pe_idx])-self.my_buy_price[0] buy_pe_pl.append(val) if(i>=sell_pe_idx): val = self.my_buy_price[1] else: val = self.my_buy_price[1]-abs(strike_prices[i]-strike_prices[sell_pe_idx]) sell_pe_pl.append(val) if(i<=sell_ce_idx): val = self.my_buy_price[2] else: val = self.my_buy_price[2]-abs(strike_prices[i]-strike_prices[sell_ce_idx]) sell_ce_pl.append(val) if(i<=buy_ce_idx): val = -self.my_buy_price[3] else: val = abs(strike_prices[i]-strike_prices[buy_ce_idx])-self.my_buy_price[3] buy_ce_pl.append(val) self.buy_pe_limit.append((pd_concat['strikePrice'].tolist())[0]) self.sell_pe_limit.append((pd_concat['strikePrice'].tolist())[1]) self.sell_ce_limit.append((pd_concat['strikePrice'].tolist())[2]) self.buy_ce_limit.append((pd_concat['strikePrice'].tolist())[3]) self.market_price.append(curr_price) ttl1 = list(map(add,buy_pe_pl,sell_pe_pl)) ttl2 = list(map(add,buy_ce_pl,sell_ce_pl)) ttl3 = list(map(add,ttl1,ttl2)) ttl3 = list(map(lambda x:x*float(self.qty_combo_box.get()),ttl3)) df_graph['sell_call'] = ttl3 #plt.clf() #plt.plot(strike_prices,ttl3,'-b') #plt.axvline(x=(pd_concat['strikePrice'].tolist())[0],linestyle='--',color='g') #plt.axvline(x=(pd_concat['strikePrice'].tolist())[1],linestyle='--',color='r') #plt.axvline(x=(pd_concat['strikePrice'].tolist())[2],linestyle='--',color='r') #plt.axvline(x=(pd_concat['strikePrice'].tolist())[3],linestyle='--',color='g') #plt.plot(curr_price,df['P&L'].iloc[0:-1].sum(),'D') #plt.text(1.05*min(strike_prices),.9*max(ttl3),'max_profit = '+str(round(max(ttl3),2)),color='green',fontsize='10') #plt.text(1.05*min(strike_prices),.3*max(ttl3),'max_loss = '+str(round(min(ttl3),2)),color='red',fontsize='10') #clr = 'red' #if(df['P&L'].iloc[0:-1].sum()>0): # clr = 'green' #plt.text(1.01*curr_price,1.01*df['P&L'].iloc[0:-1].sum(),str(df['P&L'].iloc[0:-1].sum()),color=clr,fontsize='8') #plt.pause(.0001) #plt.show(block = False) #plt.title('Paper trading-->'+self.combo_box_stock.get()+' ('+str(curr_price)+' ) last updated @--'+datetime.now().strftime("%H:%M:%S")) self.strike_prices = strike_prices self.pd_concat = pd_concat self.curr_price = curr_price self.ttl3 = ttl3 self.df = df self.draw_plot() self.save_current_data() return df def draw_plot(self): self.plot1.clear() self.plot1.plot(self.strike_prices,self.ttl3,'-b',lw=.8) self.plot1.axvline(x=(self.pd_concat['strikePrice'].tolist())[0],linestyle='--',color='g',lw=.8) self.plot1.axvline(x=(self.pd_concat['strikePrice'].tolist())[1],linestyle='--',color='r',lw=.8) self.plot1.axvline(x=(self.pd_concat['strikePrice'].tolist())[2],linestyle='--',color='r',lw=.8) self.plot1.axvline(x=(self.pd_concat['strikePrice'].tolist())[3],linestyle='--',color='g',lw=.8) self.plot1.plot(self.curr_price,self.df['P&L'].iloc[0:-1].sum(),'D',markersize=2) self.plot1.text(1.01*min(self.strike_prices),.5*max(self.ttl3),'max_profit ='+str(round(max(self.ttl3),2)),color='green',fontsize='6') self.plot1.text(1.1*min(self.strike_prices),.5*max(self.ttl3),'max_loss = '+str(round(min(self.ttl3),2)),color='red',fontsize='6') clr = 'red' if(self.df['P&L'].iloc[0:-1].sum()>0): clr = 'green' self.plot1.text(1.01*self.curr_price,1.01*self.df['P&L'].iloc[0:-1].sum(),str(self.df['P&L'].iloc[0:-1].sum()),color=clr,fontsize='4') self.canvas.draw()
class Config(Toplevel): def __init__(self, master): Toplevel.__init__(self, master) self.title(_("Preferences")) self.grab_set() self.resizable(False, False) self.protocol("WM_DELETE_WINDOW", self.quit) self.changes = {}, {} # --- style style = Style(self) style.theme_use("clam") style.configure("TScale", sliderlength=20) style.map("TCombobox", fieldbackground=[('readonly', 'white')], selectbackground=[('readonly', 'white')], selectforeground=[('readonly', 'black')]) style.configure("prev.TLabel", background="white") style.map("prev.TLabel", background=[("active", "white")]) color = CONFIG.get("Categories", CONFIG.get("General", "default_category")) style.configure("titlebar.TFrame", background=color) style.configure("titlebar.TLabel", background=color) style.configure("text.TFrame", background="white") # --- body self.notebook = Notebook(self) okcancel_frame = Frame(self) okcancel_frame.columnconfigure(0, weight=1) okcancel_frame.columnconfigure(1, weight=1) self.notebook.pack(expand=True, fill="both") okcancel_frame.pack(fill="x", expand=True) # --- * General settings general_settings = Frame(self.notebook) general_settings.columnconfigure(0, weight=1) self.notebook.add(general_settings, text=_("General"), sticky="ewsn", padding=4) # --- *-- language lang = {"fr": "Français", "en": "English"} self.lang = StringVar(self, lang[CONFIG.get("General", "language")]) lang_frame = Frame(general_settings) Label(lang_frame, text=_("Language")).grid(row=0, sticky="w", padx=4, pady=4) menu_lang = Menu(lang_frame, tearoff=False) Menubutton(lang_frame, menu=menu_lang, width=9, textvariable=self.lang).grid(row=0, column=1, padx=8, pady=4) menu_lang.add_radiobutton(label="English", value="English", variable=self.lang, command=self.translate) menu_lang.add_radiobutton(label="Français", value="Français", variable=self.lang, command=self.translate) # --- *-- opacity self.opacity_scale = Scale(general_settings, orient="horizontal", length=200, from_=0, to=100, value=CONFIG.get("General", "opacity"), command=self.display_label) self.opacity_label = Label( general_settings, text="{val}%".format(val=self.opacity_scale.get())) # --- *-- position frame_position = Frame(general_settings) self.position = StringVar(self, CONFIG.get("General", "position")) Label(frame_position, text=_("Default position of the notes")).grid(row=0, columnspan=3, sticky="w", padx=4, pady=4) Radiobutton(frame_position, text=_("Always above"), value="above", variable=self.position).grid(row=1, column=0) Radiobutton(frame_position, text=_("Always below"), value="below", variable=self.position).grid(row=1, column=1) Radiobutton(frame_position, text=_("Normal"), value="normal", variable=self.position).grid(row=1, column=2) # --- *-- titlebar self.titlebar_disposition = StringVar( self, CONFIG.get("General", "buttons_position")) font_title = "%s %s" % (CONFIG.get("Font", "title_family").replace( " ", "\ "), CONFIG.get("Font", "title_size")) style = CONFIG.get("Font", "title_style").split(",") if style: font_title += " " font_title += " ".join(style) frame_titlebar = Frame(general_settings) frame_titlebar.columnconfigure(1, weight=1) frame_titlebar.columnconfigure(3, weight=1) Label(frame_titlebar, text=_("Title bar disposition")).grid(row=0, columnspan=4, sticky="w", padx=4, pady=4) Radiobutton(frame_titlebar, value="right", variable=self.titlebar_disposition).grid(row=1, column=0) right = Frame(frame_titlebar, style="titlebar.TFrame") right.grid(row=1, column=1, sticky="ew") def select_right(event): self.titlebar_disposition.set("right") Label(right, text=_("Title"), style="titlebar.TLabel", anchor="center", font=font_title).pack(side="left", fill="x", expand=True) Label(right, image="img_close", style="titlebar.TLabel").pack(side="right") Label(right, image="img_roll", style="titlebar.TLabel").pack(side="right") for ch in right.children.values(): ch.bind("<Button-1>", select_right) Radiobutton(frame_titlebar, value="left", variable=self.titlebar_disposition).grid(row=1, column=2) left = Frame(frame_titlebar, style="titlebar.TFrame") left.grid(row=1, column=3, sticky="ew") def select_left(event): self.titlebar_disposition.set("left") Label(left, image="img_close", style="titlebar.TLabel").pack(side="left") Label(left, image="img_roll", style="titlebar.TLabel").pack(side="left") Label(left, text=_("Title"), style="titlebar.TLabel", anchor="center", font=font_title).pack(side="right", fill="x", expand=True) for ch in left.children.values(): ch.bind("<Button-1>", select_left) # --- *-- placement lang_frame.grid(sticky="w") Separator(general_settings, orient="horizontal").grid(sticky="ew", pady=10) Label(general_settings, text=_("Opacity")).grid(sticky="w", padx=4, pady=4) self.opacity_scale.grid(padx=4, pady=(4, 10)) self.opacity_label.place(in_=self.opacity_scale, relx=1, rely=0.5, anchor="w", bordermode="outside") Separator(general_settings, orient="horizontal").grid(sticky="ew", pady=10) frame_position.grid(sticky="ew") Separator(general_settings, orient="horizontal").grid(sticky="ew", pady=10) frame_titlebar.grid(sticky="ew", pady=4) if LATEX: Separator(general_settings, orient="horizontal").grid(sticky="ew", pady=10) Button(general_settings, text=_('Delete unused LaTex data'), command=self.cleanup).grid(padx=4, pady=4, sticky='w') # --- * Font settings font_settings = Frame(self.notebook) font_settings.columnconfigure(0, weight=1) self.notebook.add(font_settings, text=_("Font"), sticky="ewsn", padding=4) # --- *-- title fonttitle_frame = Frame(font_settings) title_size = CONFIG.get("Font", "title_size") title_family = CONFIG.get("Font", "title_family") self.sampletitle = Label(fonttitle_frame, text=_("Sample text"), anchor="center", style="prev.TLabel", relief="groove") self.sampletitle.grid(row=2, columnspan=2, padx=4, pady=6, ipadx=4, ipady=4, sticky="eswn") self.fonts = list(set(font.families())) self.fonts.append("TkDefaultFont") self.fonts.sort() w = max([len(f) for f in self.fonts]) self.sizes = [ "%i" % i for i in (list(range(6, 17)) + list(range(18, 32, 2))) ] self.fonttitle_family = Combobox(fonttitle_frame, values=self.fonts, width=(w * 2) // 3, exportselection=False, validate="key") self._validate_title_size = self.register( lambda *args: self.validate_font_size(self.fonttitle_size, *args)) self._validate_title_family = self.register( lambda *args: self.validate_font_family(self.fonttitle_family, * args)) self.fonttitle_family.configure( validatecommand=(self._validate_title_family, "%d", "%S", "%i", "%s", "%V")) self.fonttitle_family.current(self.fonts.index(title_family)) self.fonttitle_family.grid(row=0, column=0, padx=4, pady=4) self.fonttitle_size = Combobox( fonttitle_frame, values=self.sizes, width=5, exportselection=False, validate="key", validatecommand=(self._validate_title_size, "%d", "%P", "%V")) self.fonttitle_size.current(self.sizes.index(title_size)) self.fonttitle_size.grid(row=0, column=1, padx=4, pady=4) frame_title_style = Frame(fonttitle_frame) frame_title_style.grid(row=1, columnspan=2, padx=4, pady=6) self.is_bold = Checkbutton(frame_title_style, text=_("Bold"), command=self.update_preview_title) self.is_italic = Checkbutton(frame_title_style, text=_("Italic"), command=self.update_preview_title) self.is_underlined = Checkbutton(frame_title_style, text=_("Underline"), command=self.update_preview_title) style = CONFIG.get("Font", "title_style") if "bold" in style: self.is_bold.state(("selected", )) if "italic" in style: self.is_italic.state(("selected", )) if "underline" in style: self.is_underlined.state(("selected", )) self.is_bold.pack(side="left") self.is_italic.pack(side="left") self.is_underlined.pack(side="left") self.update_preview_title() # --- *-- text size = CONFIG.get("Font", "text_size") family = CONFIG.get("Font", "text_family") font_frame = Frame(font_settings) self.sample = Label(font_frame, text=_("Sample text"), anchor="center", style="prev.TLabel", relief="groove") self.sample.grid(row=1, columnspan=2, padx=4, pady=6, ipadx=4, ipady=4, sticky="eswn") self.font_family = Combobox(font_frame, values=self.fonts, width=(w * 2) // 3, exportselection=False, validate="key") self._validate_family = self.register( lambda *args: self.validate_font_family(self.font_family, *args)) self._validate_size = self.register( lambda *args: self.validate_font_size(self.font_size, *args)) self.font_family.configure(validatecommand=(self._validate_family, "%d", "%S", "%i", "%s", "%V")) self.font_family.current(self.fonts.index(family)) self.font_family.grid(row=0, column=0, padx=4, pady=4) self.font_size = Combobox(font_frame, values=self.sizes, width=5, exportselection=False, validate="key", validatecommand=(self._validate_size, "%d", "%P", "%V")) self.font_size.current(self.sizes.index(size)) self.font_size.grid(row=0, column=1, padx=4, pady=4) self.update_preview() # --- *-- placement Label(font_settings, text=_("Title")).grid(row=0, padx=4, pady=4, sticky="w") fonttitle_frame.grid(row=1) Separator(font_settings, orient="horizontal").grid(row=2, sticky="ew", pady=10) Label(font_settings, text=_("Text")).grid(row=3, padx=4, pady=4, sticky="w") font_frame.grid(row=4) # --- * Categories self.category_settings = CategoryManager(self.notebook, master) self.notebook.add(self.category_settings, text=_("Categories"), sticky="ewsn", padding=4) # --- * Symbols symbols_settings = Frame(self.notebook) self.notebook.add(symbols_settings, text=_("Symbols"), sticky="ewsn", padding=4) txt_frame = Frame(symbols_settings, relief="sunken", borderwidth=1, style="text.TFrame") self.symbols = Text(txt_frame, width=1, height=1, highlightthickness=0, spacing2=5, spacing1=5, relief="flat", padx=4, pady=4, font="%s %s" % (family.replace(" ", "\ "), size)) self.symbols.insert("1.0", CONFIG.get("General", "symbols")) Label(symbols_settings, text=_("Available symbols")).pack(padx=4, pady=4) txt_frame.pack(fill="both", expand=True, padx=4, pady=4) self.symbols.pack(fill="both", expand=True) Button(symbols_settings, text=_('Reset'), command=self.reset_symbols).pack(padx=4, pady=4) # --- Ok/Cancel buttons Button(okcancel_frame, text="Ok", command=self.ok).grid(row=1, column=0, padx=4, pady=10, sticky="e") Button(okcancel_frame, text=_("Cancel"), command=self.destroy).grid(row=1, column=1, padx=4, pady=10, sticky="w") # --- bindings self.font_family.bind('<<ComboboxSelected>>', self.update_preview) self.font_family.bind('<Return>', self.update_preview) self.font_size.bind('<<ComboboxSelected>>', self.update_preview, add=True) self.font_size.bind('<Return>', self.update_preview, add=True) self.fonttitle_family.bind('<<ComboboxSelected>>', self.update_preview_title) self.fonttitle_size.bind('<<ComboboxSelected>>', self.update_preview_title, add=True) self.fonttitle_family.bind('<Return>', self.update_preview_title) self.fonttitle_size.bind('<Return>', self.update_preview_title, add=True) def reset_symbols(self): self.symbols.delete('1.0', 'end') self.symbols.insert('1.0', SYMBOLS) def cleanup(self): ''' Remove unused latex images ''' self.master.cleanup() def validate_font_size(self, combo, d, ch, V): ''' Validation of the size entry content ''' if d == '1': l = [i for i in self.sizes if i[:len(ch)] == ch] if l: i = self.sizes.index(l[0]) combo.current(i) index = combo.index("insert") combo.selection_range(index + 1, "end") combo.icursor(index + 1) return ch.isdigit() else: return True def validate_font_family(self, combo, action, modif, pos, prev_txt, V): """ completion of the text in the path entry with existing folder/file names """ try: sel = combo.selection_get() txt = prev_txt.replace(sel, '') except TclError: txt = prev_txt if action == "0": txt = txt[:int(pos)] + txt[int(pos) + 1:] return True else: txt = txt[:int(pos)] + modif + txt[int(pos):] l = [i for i in self.fonts if i[:len(txt)] == txt] if l: i = self.fonts.index(l[0]) combo.current(i) index = combo.index("insert") combo.delete(0, "end") combo.insert(0, l[0].replace("\ ", " ")) combo.selection_range(index + 1, "end") combo.icursor(index + 1) return True else: return False def ok(self): family = self.font_family.get() if family not in self.fonts: l = [i for i in self.fonts if i[:len(family)] == family] if l: family = l[0] else: family = 'TkDefaultFont' size = self.font_size.get() familytitle = self.fonttitle_family.get() if familytitle not in self.fonts: l = [i for i in self.fonts if i[:len(familytitle)] == familytitle] if l: familytitle = l[0] else: familytitle = 'TkDefaultFont' sizetitle = self.fonttitle_size.get() opacity = "%i" % float(self.opacity_scale.get()) language = self.lang.get().lower()[:2] style = "" if self.is_bold.instate(("selected", )): style += "bold," if self.is_italic.instate(("selected", )): style += "italic," if self.is_underlined.instate(("selected", )): style += "underline," if style: style = style[:-1] symbols = [ l.strip() for l in self.symbols.get("1.0", "end").splitlines() ] CONFIG.set("General", "default_category", self.category_settings.default_category.get().lower()) CONFIG.set("General", "language", language) CONFIG.set("General", "opacity", opacity) CONFIG.set("General", "position", self.position.get()) CONFIG.set("General", "buttons_position", self.titlebar_disposition.get()) CONFIG.set("General", "symbols", "".join(symbols)) CONFIG.set("Font", "text_size", size) CONFIG.set("Font", "text_family", family) CONFIG.set("Font", "title_family", familytitle) CONFIG.set("Font", "title_size", sizetitle) CONFIG.set("Font", "title_style", style) col_changes = {} name_changes = {} for cat in self.category_settings.categories: new_name = self.category_settings.get_name(cat) if cat in CONFIG.options("Categories"): old_color = CONFIG.get("Categories", cat) new_color = COLORS[self.category_settings.get_color(cat)] if new_name != cat: name_changes[cat] = new_name CONFIG.remove_option("Categories", cat) CONFIG.set("Categories", new_name, new_color) if old_color != new_color: col_changes[new_name] = (old_color, new_color) CONFIG.set("Categories", new_name, new_color) else: CONFIG.set("Categories", new_name, COLORS[self.category_settings.get_color(cat)]) save_config() self.changes = col_changes, name_changes self.destroy() def get_changes(self): return self.changes def translate(self): showinfo( "Information", _("The language setting will take effect after restarting the application" ), parent=self) def update_preview(self, event=None): family = self.font_family.get() size = self.font_size.get() self.sample.configure(font="%s %s" % (family.replace(" ", "\ "), size)) def update_preview_title(self, event=None): family = self.fonttitle_family.get() size = self.fonttitle_size.get() config = "%s %s" % (family.replace(" ", "\ "), size) if self.is_bold.instate(("selected", )): config += " bold" if self.is_italic.instate(("selected", )): config += " italic" if self.is_underlined.instate(("selected", )): config += " underline" self.sampletitle.configure(font=config) def display_label(self, value): self.opacity_label.configure(text=" {val} %".format( val=int(float(value)))) def quit(self): self.destroy()
class EnergyMonitor(): def __init__(self, parent): self.parent = parent self.data_container = OrderedDict() self.monthly_data = OrderedDict() self.loaded_ids = [] self.loaded_fuels = [] self.welcome_label = tk.Label(self.parent, text='Welcome to the Energy Monitor!', font=('Calibri', 32)) self.welcome_label.configure(background='#c6e2ff') self.welcome_label.pack() self.message_label = tk.Label( self.parent, text= 'Please use the dialog below to load a CSV file, which will be displayed ' + 'in the box below.', font=('Calibri', 14), wraplength=540) self.message_label.configure(background='#c6e2ff') self.message_label.pack(pady=20) # self.btn_file = Button(parent, text="Load file", command=load_file) self.btn_file = tk.Button(self.parent, text="Load file", command=self.load_file) self.btn_file.pack(pady=20) self.scrolled_text = tk.scrolledtext.ScrolledText(self.parent, width=40, height=10) self.scrolled_text.pack() self.house_combo = Combobox(self.parent) self.house_combo.pack_forget() self.fuel_label = tk.Label(self.parent, text="", font=('Calibri', 11)) self.fuel_label.pack_forget() self.btn_graph_annual = tk.Button( self.parent, text='Annual Usage', command=functools.partial(self.generate_annual_graph_singlehouse, self.house_combo.get())) self.btn_graph_annual.pack_forget() self.btn_graph_monthly = tk.Button( self.parent, text='Monthly Usage', command=functools.partial(self.generate_monthly_graph_singlehouse, self.house_combo.get())) self.btn_graph_monthly.pack_forget() self.btn_graph_multiple_monthly = tk.Button( self.parent, text='All Houses Monthly Usage', command=functools.partial(self.generate_graph_monthly_multiple, self.house_combo.get())) self.btn_graph_multiple_monthly.pack_forget() self.selected_radio = tk.IntVar() self.radio_gas = tk.Radiobutton(self.parent, text="Gas", value=FuelType.gas.value, variable=self.selected_radio) self.radio_electric = tk.Radiobutton(self.parent, text="Electricity", value=FuelType.electricity.value, variable=self.selected_radio) self.radio_gas.pack_forget() self.radio_electric.pack_forget() def load_file(self, file=None): if file is None: file = filedialog.askopenfilename( initialdir=path.dirname(__file__)) elif not path.isfile(file): raise ValueError("This file does not exist or is not readable.") print(file) re_single_house = re.compile('^(.*?)_both_daily$') re_multiple_houses = re.compile('^(gas|electricity)_daily$') filename = basename(file).split('.')[0] single_match = re_single_house.search(filename) multiple_match = re_multiple_houses.search(filename) if single_match is not None: self.process_single_file(file, single_match.group(1)) elif multiple_match is not None: fuel_type = FuelType[multiple_match.group(1)] self.process_multiple_file(file, fuel_type) else: raise ValueError( "File format is not correct, must be one of '{fuel-type}_daily.csv" + " or '{house-id}_both_daily.csv is invalid") self.house_combo.configure(values=self.loaded_ids) self.house_combo.current(0) self.house_combo.pack(pady=5) self.fuel_label.configure( text="Available fuel types: " + ','.join(list(map(lambda f: str(f.name), self.loaded_fuels)))) self.fuel_label.pack(pady=20) self.btn_graph_annual.pack(pady=5) self.btn_graph_monthly.pack() if len(self.loaded_ids) > 1: self.btn_graph_multiple_monthly.pack() if FuelType.gas in self.loaded_fuels: self.radio_gas.pack() if FuelType.electricity in self.loaded_fuels: self.radio_electric.pack() def process_single_file(self, file, house_id): print( "This file is a single house with both fuel types. The house id is '%s'." % house_id) print("Deleting old data") self.data_container.clear() self.loaded_ids.clear() self.loaded_fuels.clear() with open(file, 'r') as file_contents: reader = csv.reader(file_contents) header = next(reader, None) if header[1].lower() != 'electricity' or header[2].lower( ) != 'gas': raise ValueError( 'File is not in correct format. First column must be electricity, second must be gas.' ) for row in reader: print(row) this_date = datetime.datetime.strptime(row[0], '%Y%m%d').date() self.data_container[this_date] = { house_id: { FuelType.electricity: float(row[1]), FuelType.gas: float(row[2]) } } # Since we have only loaded one file, set the id directly self.loaded_ids.append(house_id) self.loaded_fuels.extend([FuelType.electricity, FuelType.gas]) def process_multiple_file(self, file, fuel_type): print("This file is a multiple house file with %s data." % fuel_type) with open(file, 'r') as file_contents: reader = csv.reader(file_contents) header = next(reader, None) # Add the loaded ids to the list self.loaded_ids = header[1:len(header)] if fuel_type not in self.loaded_fuels: self.loaded_fuels.append(fuel_type) if header[0].lower() != 'date': raise ValueError( 'The header line must begin with a date column, then a column for each property' ) for row in reader: this_date = datetime.datetime.strptime(row[0], '%Y%m%d').date() if this_date not in self.data_container: self.data_container[this_date] = {} # Validate number of rows with data in is correct with the header if len(row) != len(header): raise ValueError( 'The number of elements in this row is not correct.') for index in range(1, len(row)): this_house_id = header[index] if this_house_id not in self.data_container[this_date]: self.data_container[this_date][this_house_id] = {} self.data_container[this_date][this_house_id][ fuel_type] = row[index] def generate_monthly_data(self): print('Generating monthly data') this_monthly_data = OrderedDict() for date in self.data_container: this_date = datetime.date(date.year, date.month, 1) if this_date not in this_monthly_data: this_monthly_data[this_date] = {} for house in self.data_container[this_date].keys(): if house not in this_monthly_data[this_date]: this_monthly_data[this_date][house] = { FuelType.gas: 0.0, FuelType.electricity: 0.0 } if FuelType.gas in self.data_container[date][house]: this_monthly_data[this_date][house][FuelType.gas] += float( self.data_container[date][house][FuelType.gas]) if FuelType.electricity in self.data_container[date][house]: this_monthly_data[this_date][house][ FuelType.electricity] += float( self.data_container[date][house][ FuelType.electricity]) return this_monthly_data def generate_metrics(self): print("Metrics") # When the combobox changes we should fill the scroll bar with metrics for that house def generate_monthly_graph_singlehouse(self, house_id=None): if house_id is None: raise ValueError("No house ID passed in, cannot generate graph.") elif house_id == '': house_id = self.house_combo.get() print("Generating monthly data for house with id %s" % house_id) self.monthly_data = self.generate_monthly_data() date_range = list(self.monthly_data.keys()) (gas_values, electricity_values) = ([], []) for date in date_range: if FuelType.gas not in self.monthly_data[date][house_id] \ or FuelType.electricity not in self.monthly_data[date][house_id]: raise KeyError( "Both fuel values must be present to display this graph correctly." ) gas_values.append(self.monthly_data[date][house_id][FuelType.gas]) electricity_values.append( self.monthly_data[date][house_id][FuelType.electricity]) gas_trace = go.Scatter(x=date_range, y=gas_values, name='Gas') electricity_trace = go.Scatter(x=date_range, y=electricity_values, name='Electricity', yaxis='y2') layout = go.Layout(title='Monthly Both Fuels', yaxis=dict(title='Gas Usage (kWh)'), yaxis2=dict( title='Electricity Usage (kWh)', titlefont=dict(color='rgb(148, 103, 189)'), tickfont=dict(color='rgb(148, 103, 189)'), overlaying='y', side='right')) fig = go.Figure(data=[gas_trace, electricity_trace], layout=layout) plotly.offline.plot(fig, auto_open=True) def generate_graph(self): print("Stub method for generating graphs") # Use this one in the submitted code, keep the agnosting one separate def generate_annual_graph_singlehouse(self, house_id=None): if house_id is None: raise ValueError("No house ID passed in, cannot generate graph.") elif house_id == '': house_id = self.house_combo.get() date_range = list(self.data_container.keys()) (gas_values, electricity_values) = ([], []) for date in date_range: if FuelType.gas not in self.data_container[date][house_id] \ or FuelType.electricity not in self.data_container[date][house_id]: raise KeyError( "Both fuel values must be present to display this graph correctly." ) gas_values.append( self.data_container[date][house_id][FuelType.gas]) electricity_values.append( self.data_container[date][house_id][FuelType.electricity]) gas_trace = go.Scatter(x=date_range, y=gas_values, name='gas trace') electricity_trace = go.Scatter(x=date_range, y=electricity_values, name='electricity trace', yaxis='y2') graph_data = [gas_trace, electricity_trace] layout = go.Layout(title='Single House Both Fuels', yaxis=dict(title='Usage (kWh)'), yaxis2=dict( title='yaxis2 title', titlefont=dict(color='rgb(148, 103, 189)'), tickfont=dict(color='rgb(148, 103, 189)'), overlaying='y', side='right')) fig = go.Figure(data=graph_data, layout=layout) plotly.offline.plot(fig, auto_open=True) def generate_graph_singlehouse(self, data, house_id=None): if house_id is None: raise ValueError("No house ID passed in, cannot generate graph.") elif house_id == '': house_id = self.house_combo.get() date_range = list(data.keys()) (gas_values, electricity_values) = ([], []) for date in date_range: if FuelType.gas not in data[date][house_id] \ or FuelType.electricity not in data[date][house_id]: raise KeyError( "Both fuel values must be present to display this graph correctly." ) gas_values.append(data[date][house_id][FuelType.gas]) electricity_values.append( data[date][house_id][FuelType.electricity]) gas_trace = go.Scatter(x=date_range, y=gas_values, name='gas trace') electricity_trace = go.Scatter(x=date_range, y=electricity_values, name='electricity trace', yaxis='y2') graph_data = [gas_trace, electricity_trace] layout = go.Layout(title='Single House Both Fuels', yaxis=dict(title='Usage (kWh)'), yaxis2=dict( title='yaxis2 title', titlefont=dict(color='rgb(148, 103, 189)'), tickfont=dict(color='rgb(148, 103, 189)'), overlaying='y', side='right')) fig = go.Figure(data=graph_data, layout=layout) plotly.offline.plot(fig, auto_open=True) def generate_graph_monthly_multiple(self, fuel_type=None): if fuel_type is None or fuel_type == '': fuel_type = FuelType(self.selected_radio.get()) self.monthly_data = self.generate_monthly_data() if fuel_type is None: # TODO fetch the value somehow fuel_type = FuelType.gas date_range = list(self.monthly_data.keys()) usages = OrderedDict() data = [] for date in date_range: for house in list(self.monthly_data[date].keys()): if house not in usages: usages[house] = [] usages[house].append(self.monthly_data[date][house][fuel_type]) for house in list(usages.keys()): data.append(go.Bar(x=date_range, y=usages[house], name=house)) layout = go.Layout(barmode='group') fig = go.Figure(data=data, layout=layout) plotly.offline.plot(fig, auto_open=True)
class Ui(object): def __init__(self, switcher: Switcher): self._switcher = switcher self._tk_root = Tk() self._tk_root.title(TITLE) self._tk_root.columnconfigure(1, weight=1) self._tk_root.rowconfigure(2, weight=1) self._tk_root.geometry('560x120') self._tk_root.protocol('WM_DELETE_WINDOW', self._on_destroy) # UI elements # |---------|-----------------| # | Name: | dropdown | # | Set DLL | dll path text | # | Apply | Create shortcut | self._text_dll_name = Label(self._tk_root, text='Name:', anchor=W) self._text_dll_name.grid(row=0, column=0, padx=8, sticky=W) self._combobox = Combobox(self._tk_root, values=tuple(self._switcher.dll_names), validate='key', validatecommand=(self._tk_root.register( self._dll_name_typed), '%P')) self._combobox.grid(row=0, column=1, padx=8, pady=8, sticky=W) self._combobox.bind('<<ComboboxSelected>>', lambda _: self._dll_name_selected()) if self._switcher.dll_names: self._combobox.current(0) self._button_set_dll = Button(self._tk_root, text='Set DLL', command=self._set_dll) self._button_set_dll.grid(row=1, column=0, padx=8, sticky=W) self._text_dll_path = Label(self._tk_root, anchor=W) self._text_dll_path.grid(row=1, column=1, columnspan=2, padx=8, sticky=W) self._button_apply = Button(self._tk_root, text='Apply', command=self._apply) self._button_apply.grid(row=2, column=0, columnspan=2, padx=8, pady=8, sticky=W + S) self._button_create_shortcut = Button(self._tk_root, text='Create shortcut', command=self._create_shortcut) self._button_create_shortcut.grid(row=2, column=1, padx=8, pady=8, sticky=W + S) self._validate_ori_root() self._dll_name_selected() def _validate_ori_root(self): if self._switcher.assembly_csharp: return messagebox.showinfo(message='Please locate your Ori DE directory', parent=self._tk_root, title=TITLE) while True: ori_root = filedialog.askdirectory( parent=self._tk_root, title='Select the Ori DE directory', mustexist=True) if not ori_root: messagebox.showerror(message='Ori DE directory not found', parent=self._tk_root, title=TITLE) sys.exit(1) ori_root = os.path.abspath(ori_root) if self._switcher.get_assemblycsharp_path(ori_root): break messagebox.showerror( message= 'Invalid Ori DE directory. Should be the directory that contains oriDE.exe', parent=self._tk_root, title=TITLE) self._switcher.ori_root = ori_root # new dll path was set def _update_dll_path(self, dll_path): self._text_dll_path.configure(text=dll_path or '') self._button_apply.configure(state=NORMAL if dll_path else DISABLED) self._button_create_shortcut.configure( state=NORMAL if dll_path else DISABLED) # dll name changed def _update_dll_name(self, dll_name): self._button_set_dll.configure(state=NORMAL if dll_name else DISABLED) dll_path = self._switcher.get_dll_path(dll_name) self._update_dll_path(dll_path) # user chose a name from the list def _dll_name_selected(self): self._update_dll_name(self._combobox.get()) # user is typing a name (combobox validatecommand callback) def _dll_name_typed(self, text): self._update_dll_name(text) return True # user clicked on button_set_dll def _set_dll(self): dll_name = self._combobox.get() dll_path = filedialog.askopenfilename( filetypes=[('DLL', '*.dll')], initialdir=self._switcher.ori_root, parent=self._tk_root, title=f'Choose your "{dll_name}" DLL file') if not dll_path: return dll_path = os.path.abspath(dll_path) if dll_path == self._switcher.assembly_csharp: messagebox.showerror( message= "You cannot choose the game's original DLL path.\nIf this is your mod DLL, please rename it or copy it elsewhere.", title=TITLE) return self._switcher.set_dll_path(dll_name, dll_path) self._update_dll_path(dll_path) self._combobox.configure(values=tuple(self._switcher.dll_names)) # user clicked on button_apply def _apply(self): try: dll_name = self._combobox.get() self._switcher.switch(dll_name) messagebox.showinfo(message=f'Switched to {dll_name} DLL', parent=self._tk_root, title=TITLE) self._on_destroy() except SwitcherException as e: # Should never happen messagebox.showerror(message=e, title=TITLE) # user clicked on button_create_shortcut def _create_shortcut(self): dll_name = self._combobox.get() shortcut_name = f'SwitchTo{dll_name.capitalize()}.lnk' win_cmd_path = r'C:\Windows\System32\cmd.exe' program_dir, program_filename = os.path.split( os.path.abspath(sys.argv[0])) if program_filename.endswith('.py'): program_filename = 'py ' + program_filename elif not program_filename.endswith('.exe'): messagebox.showerror(message='Cannot create shortcut', parent=self._tk_root, title=TITLE) return args = f'/c {program_filename} {dll_name}' shortcut_dir = filedialog.askdirectory(parent=self._tk_root, title='Choose location', mustexist=True) if not shortcut_dir: return shortcut_dir = os.path.abspath(shortcut_dir) shortcut = Dispatch('WScript.Shell').CreateShortCut( os.path.join(shortcut_dir, shortcut_name)) shortcut.Targetpath = win_cmd_path shortcut.Arguments = args shortcut.WorkingDirectory = program_dir shortcut.save() messagebox.showinfo(message=f'Shortcut {shortcut_name[:-4]} created', parent=self._tk_root, title=TITLE) def _on_destroy(self): self._switcher.save_data_json() self._tk_root.destroy() def mainloop(self): self._tk_root.mainloop()
class WidgetTable(Frame): """ A frame which contains rows which can be populate with multiple widgets in each column. We can have a button to remove rows, and a few different ways to add new rows. Parameters ---------- headings : list(str) A list of strings for the headings. If the value is specified as `None` then no header row will be drawn. pattern : list(instance of Variable) A list of Variables to be associated with the widget. These variables need to be the appropriate type for the entry_type associated with the data, as well as the data passed in (if the table is to be initially or automatically populated). The Variable information can be passed in as a dicitonary to allow very specific modification of how the data works. The dictionary has the following keys: - var: An instantiated Variable object - text: A string (used as the text on buttons, or default text for an entry/label) - configs: A dictionary of the configuration to be applied to the widget. - func: The function used as a callback for buttons, checkbuttons etc. - func_has_row_ctx: (bool) whether or not the function specified by func is given the current line as an argument. widgets_pattern : list of Widget instances A list of Widgets that will be drawn in each column. These widgets *must* be un-instantiated to allow cloning when creating new rows. add_options : list, optional A fixed length list of options that can be added. If None then the rows can just be added arbitrarily using button. data_array : list, optional A list of the intial data to populate the table with. This can either be raw data or an array of the variables adder_script : function, optional A function that will be called when the Add button is pressed or a value is picked from the add_options option box. If this function returns an values they are assumed to be the values to be passed into the newly created widgets if possible. To remove the functionality to add new rows set this to tkinter.DISABLED. remove_script : function, optional A callback for when a row is deleted. This function can be used to block deletion. This is acheived by having this function return anything. If nothing is returned then the deletion occurs as expected. To remove the functionality to remove rows set this to tkinter.DISABLED. sort_column : int, optional The column number that the data will automatically be sorted by. max_rows : int, optional The maximum number of rows to display before forcing the ScrollableFrame to have a scroller. style : dict, optional A dictionary containing a number of style parameters. Possible parameters are: nodivders : bool Whether or not to draw the dividers. """ def __init__(self, master, headings=[], pattern=[], widgets_pattern=[], add_options=None, data_array=[], adder_script=None, remove_script=None, sort_column=None, max_rows=None, style=dict(), *args, **kwargs): self.master = master # s = Style(self.master) # s.configure('proper.TEntry', background='green') super(WidgetTable, self).__init__(self.master, *args, **kwargs) self.rows = [] self.headings = headings self.pattern = pattern self.widgets_pattern = widgets_pattern self.num_columns = len(self.widgets_pattern) self.add_options = add_options self.adder_script = adder_script self.remove_script = remove_script self.sort_column = sort_column self.max_rows = max_rows self.style = style self.entry_config = { 'readonlybackground': OSCONST.TEXT_RONLY_BG, 'highlightbackground': OSCONST.CANVAS_BG } # the index we need to redraw the rows after self.first_redraw_row = 0 self.row_offset = 0 self.separator_offset = 0 self.widgets = [] self.add_button = None self._create_widgets() self.separators = [] if not self.style.get('nodividers', False): for _ in range(self.num_columns - 1): sep = Separator(self.sf.frame, orient='vertical') self.separators.append(sep) self.delete_icon = Image.open(OSCONST.ICON_REMOVE) self.delete_icon = self.delete_icon.resize((20, 20), Image.LANCZOS) self.delete_icon = ImageTk.PhotoImage(self.delete_icon) # storage variables if data_array != []: # ensure a 2D array if not isinstance(data_array[0], list): data_array = [data_array] self.data = [] self.set(data_array) else: # empty table self.data = [] self._draw_separators() self.bind(OSCONST.ADDROW, self._add_row_from_key) self.sf.configure_view(needs_update=True) #region public methods def add_row_data(self, idx, data=None): """ Add the provided row data at the required index Paramaters ---------- idx : int Index the data is the be added at. data : list This is a list of either the values the variables will take or the data itself. Any entry can be None which indicates the default un-initiated data should be used. """ # TODO: fix the optimisation so that this is not 0 any more... self.first_redraw_row = 0 # len(self.data) - 1 self._assign_row_data(idx, data) def add_row_widgets(self, count=1): """ Add one or more sets of row widgets to the end of the table The widgets are added from the WidgetTable's widget_pattern property. Parameters ---------- count : int The number of rows of widgets to add. Defaults to 1 """ # remove the add button if it exists if count != 0: if self.add_button is not None: self.add_button.grid_forget() initial_rows = len(self.widgets) for r in range(count): row_widgets = [] rows = self.sf.frame.grid_size()[1] # draw each of the new widgets in the last row for i, w in enumerate(self.widgets_pattern): w_actual = w(self.sf.frame) w_actual.bind(OSCONST.ADDROW, self._add_row_from_key) w_actual.grid(row=rows, column=2 * i, sticky='nsew', padx=2, pady=2) row_widgets.append(w_actual) # add the delete button at the end of the row if self.remove_script != DISABLED: curr_row = initial_rows + r delete_button = tkButton( self.sf.frame, command=lambda x=curr_row: self.delete_rows_and_update(x), relief='flat', borderwidth=0, highlightthickness=0, takefocus=0) delete_button.config(image=self.delete_icon) delete_button.grid(row=rows, column=2 * self.num_columns - 1) row_widgets.append(delete_button) self.widgets.append(row_widgets) # set the focus on the first of the widgets in the bottom row # TODO: this will probably need a bit more complexity added to it?? self.widgets[-1][0].focus_set() if count != 0: # finally, fix up separators and add button if needed self._draw_separators() if self.add_button is not None: self.add_button.grid(row=rows + 1, column=2 * self.num_columns - 1) def add_rows(self, data=None, count=1, from_start=False): """ Add a new row to the end of the current data and redraw all the current data from the new data onward. We can add multiple rows at a time to save drawing, undrawing then drawing the add button again and again. Parameters data : list | None Data to be automatically added to the new row(s) count : int Number of new rows to add. Defaults to 1. from_start : bool Whether to assign row data from the start of not. This should always be False unless count == 0. """ refresh = False # if from_start == True then the data will be placed from row 0 curr_rows = (1 - from_start) * len(self.data) # if there is no size difference we simply want to refresh the data if count == 0: refresh = True count = len(data) if data is not None and data != []: data = self.ensure_2D_array(data) for i in range(count): self.add_row_data(curr_rows + i, data[i]) else: for i in range(count): self.add_row_data(curr_rows + i) if not refresh: self.add_row_widgets(count) # now sort the data if needed. # we only want to sort if data is provided, otherwise we can have weird # effects like the new data being inserted at the start. if data is not None: self.sort_data() self._correct_idx_refs() # apply the data appropriately self._apply_data() def add_row_from_button(self): """ Add a row from the 'Add Row' button """ # before anything happens call the adder script if there is one to # determine whether there is any data that can populate the new row. if self.adder_script is not None: try: ret = self.adder_script() if ret is None: self.add_rows() else: self.add_rows(ret) except TypeError: # in this case the wrong number of arguments have been passed # (potentially. Print a message and pass) print(("The adder function used wasn't called because " "it had the wrong number of arguments")) except ValueError: # In this case the function may have broken. # This indicates we do not want to add the row pass else: self.add_rows() self._resize_to_max(resize_canvas='xy', move_to_bottom=True) def add_row_from_selection(self, event): """ Add a new row from the list of possible rows to add """ # this only needs to be different to implement the functionality to # allow the entry in the list to be removed if it needs to be # unless we leave that functionality up to the user... if self.adder_script is not None: ret = self.adder_script() if ret is None: self.add_rows() else: self.add_rows(ret) self._resize_to_max(resize_canvas='x') def delete_row(self, idx, ignore_script=False): """ Remove the row widgets and data Parameters ---------- idx : int Row index to delete. ignore_script : bool Whether or not to ignore the call to the removal script. Defaults to False (runs removal script by default if there is one) """ remove_rtn = None if self.remove_script is not None and not ignore_script: remove_rtn = self.remove_script(idx) if remove_rtn is None: for w in self.widgets[-1]: w.grid_forget() del self.widgets[-1] del self.data[idx] def delete_rows_and_update(self, idx, count=1, ignore_script=False): """ Remove one or more row widgets and update the table Parameters ---------- idx : int Row index to delete. count : int Number of rows to delete. Defaults to 1. ignore_script : bool Whether or not to ignore the call to the removal script. Defaults to False (runs removal script by default if there is one). """ # remove up to the maximum number of rows for _ in range(min(len(self.widgets), count)): self.delete_row(idx, ignore_script) if self.remove_script != DISABLED: # remap the delete command for the buttons for i in range(len(self.widgets)): del_btn = self.widgets[i][-1] del_btn.config( command=lambda x=i: self.delete_rows_and_update(x)) # now, reapply all the variables self.first_redraw_row = 0 self._correct_idx_refs() self._apply_data() self._resize_to_max(resize_canvas='xy') def get(self, values=True): """ Return a 2D array of all the data contained. Parameters ---------- values : bool If values == True, the value of the Variables will be returned. If False the Variables themselves will be returned """ out_data = [] for row in self.data: row_data = [] if values: for var in row: if not isinstance(var, dict): row_data.append(var.get()) else: if 'var' in var: row_data.append(var['var'].get()) elif 'text' in var: row_data.append(var['text']) else: # simply return the actual row data row_data.append(row) out_data.append(row_data) return out_data def set(self, data=[]): """ Force the table to be updated with new data """ diff = len(data) - len(self.data) if diff < 0: # assign the row data for i in range(len(data)): self.add_row_data(i, data[i]) # remove all unneccesary rows self.delete_rows_and_update(-1, abs(diff), ignore_script=True) elif diff > 0: # assign the data up to the number of existing widgets for i in range(len(data) - diff): self.add_row_data(i, data[i]) self.add_rows(data[-diff:], diff) elif diff == 0: self.add_rows(data, diff, from_start=True) self._resize_to_max() def set_row(self, idx, data): """ Set the data for a specific row Parameters ---------- idx : int Index of the row the data will be set in. data : list Row data to be assigned. This should be a list of raw values, not a list of instances of Variables. """ for i, val in enumerate(data): if val is not None: self.data[idx][i].set(val) def sort_data(self): """ If a sort column is specified on intialisation of the WidgetTable then sort by this column.""" if isinstance(self.sort_column, int): if self.sort_column < self.num_columns: self.data.sort(key=lambda x: x[self.sort_column].get()) #region private methods def _add_row_from_key(self, *args): """ Add a new row when the new row keyboard shortcut is pressed This will only be possible when we don't have a fixed list of possibilites to add. """ if not isinstance(self.add_options, list): self.add_row_from_button() def _apply_data(self): """ Apply all the data in self.data to the widget array. The widgets are traversed column by column so that we can create an apply function specifically for that widget type. """ # do columns then rows to save having to check data types repeatedly for column in range(self.num_columns): # first, create a lambda which can be re-used for each row w = self.widgets_pattern[column] try: if callable(w): # in this case the widget is actually one wrapped in a # lambda statement. # extract it by checking the type w = type(w(self)) if issubclass(w, Label): if isinstance(self.pattern[column], dict): # apply any provided configs: if self.pattern[column].get('var') is not None: apply = lambda wgt, var: wgt.configure( textvariable=var['var'], **var.get('configs', dict())) # noqa: E731 elif self.pattern[column].get('text') is not None: apply = lambda wgt, var: wgt.configure( text=var['text'], **var.get('configs', dict() )) # noqa: E731 else: apply = lambda wgt, var: wgt.configure( # noqa: E731 textvariable=var) elif issubclass(w, tkEntry): # combobox is a subclass of the ttk.Entry object if issubclass(w, Combobox): # we will be assuming that the underlying data type is # an OptionsVar to provide simplest functionality if isinstance(self.pattern[column], dict): def apply(wgt, var): configs = var.get('configs', dict()) var = var['var'] wgt.configure(values=var.options, **configs) wgt.set(var.get()) # set the selection binding select_value = lambda e, w=wgt: var.set( wgt.get()) # noqa: E731 wgt.bind("<<ComboboxSelected>>", select_value) else: def apply(wgt, var): wgt.configure(values=var.options) wgt.set(var.get()) # set the selection binding select_value = lambda e, w=wgt: var.set( wgt.get()) # noqa: E731 wgt.bind("<<ComboboxSelected>>", select_value) elif issubclass(w, Entry): if isinstance(self.pattern[column], dict): # apply any provided configs: apply = lambda wgt, var: wgt.configure( textvariable=var['var'], **var.get('configs', dict())) # noqa: E731 else: apply = lambda wgt, var: wgt.configure( textvariable=var) # noqa: E731 else: if isinstance(self.pattern[column], dict): # apply any provided configs: apply = lambda wgt, var: wgt.configure( textvariable=var['var'], **self.entry_config, **var.get('configs', dict())) # noqa: E731 else: apply = lambda wgt, var: wgt.configure( textvariable=var, **self.entry_config ) # noqa: E731 elif issubclass(w, Checkbutton): # check underlying data type to provide correct function if isinstance(self.pattern[column], dict): apply = lambda wgt, var: wgt.configure( # noqa: E731 variable=var['var'], command=var.get('func', None), **var.get('configs', dict())) else: apply = lambda wgt, var: wgt.configure( variable=var) # noqa: E731,E501 elif issubclass(w, Button): apply = lambda wgt, var: wgt.configure( text=var['text'], # noqa: E731,E501 command=var['func']) else: raise TypeError except TypeError: print('unsupported Widget Type??') print(w, w.__name__) raise # now, on each row apply the data for row in range(self.first_redraw_row, len(self.widgets)): apply(self.widgets[row][column], self.data[row][column]) def _assign_row_data(self, idx, data=None): """ Assign the data provided to the WidgetTable's data array's Variables. Parameters ---------- idx : int Index to place the new data in the data array data : list | None Data to assign. This data is processed to ensure that it is in the right format for being assigned to the underlying Variables. This can consist of either the raw values for each widget, an instance of a Variable, or a dictionary with parameters as described by the docstring of the widget table. (see help(WidgetTable) for more info) """ row_vars = [] # iterate over the columns for i in range(len(self.pattern)): if data is not None: val = data[i] else: val = None if val is not None: if isinstance(self.pattern[i], dict): # create a copy of the pattern for the current column data new_dict = copy_dict(self.pattern[i]) # then populate the new dict with any provided data if isinstance(val, Variable): # in this case we are just receiving the Variable # and don't want to modify the rest of the dictionary if hasattr(val, 'copy'): new_dict['var'] = val.copy() else: new_dict['var'] = val p = self.pattern[i] if p.get('func_has_row_ctx', False): f = copy(p['func']) new_dict['func'] = lambda x=idx: f(x) else: # otherwise we have been passed a (at least partial) # dictionary of data if 'var' in val: var = val['var'] if isinstance(var, Variable): if hasattr(var, 'copy'): new_dict['var'] = var.copy() else: new_dict['var'] = var else: new_dict['var'].set(var) if 'text' in val: new_dict['text'] = val['text'] if 'func' in val: if val.get('func_has_row_ctx', False): # if the function requires knowledge of the row # it is then we give it to it. new_dict['func'] = lambda x=idx: val['func'](x) else: new_dict['func'] = val['func'] if 'configs' in val: new_dict['configs'] = val['configs'] var = new_dict else: if isinstance(val, Variable): if hasattr(val, 'copy'): var = val.copy() else: var = val else: var = self.pattern[i]() var.set(val) else: if not isinstance(self.pattern[i], dict): try: issubclass(self.pattern[i], Variable) var = self.pattern[i]() except TypeError: if hasattr(self.pattern[i], 'copy'): var = self.pattern[i].copy() else: var = self.pattern[i] else: # we still need to check if the function requires row # context var = dict() for key in self.pattern[i].keys(): if key != 'func': if key == 'var': if hasattr(self.pattern[i][key], 'copy'): var[key] = self.pattern[i][key].copy() else: var[key] = self.pattern[i][key] else: var[key] = self.pattern[i][key] if var.get('func_has_row_ctx', False): var['func'] = lambda x=idx: self.pattern[i]['func'](x) row_vars.append(var) if idx < len(self.data): self.data[idx] = row_vars else: self.data.append(row_vars) def _assign_data(self, data): """ This is used to assign raw data to the underlying variables """ # clear self.data self.data = [] for i, row in enumerate(data): self._assign_row_data(i, row) def _correct_idx_refs(self): """ Correct any reference to index in any function in the data array""" for i, row in enumerate(self.data): for val in row: if isinstance(val, dict): if val.get('func_has_row_ctx', False): f = copy(val['func']) del val['func'] val['func'] = lambda x=i: f(x) def _create_widgets(self): """ Create all the base widgets required """ if isinstance(self.add_options, list): add_option_frame = Frame(self) Label(add_option_frame, text="Add an option: ").grid(column=0, row=0, sticky='w') self.nameselection = Combobox(add_option_frame, values=self.add_options, state='readonly', exportselection=0) self.nameselection.grid(column=2, row=0, sticky='w') self.nameselection.bind("<<ComboboxSelected>>", self.add_row_from_selection) self.separator_offset = 1 add_option_frame.grid(column=0, row=0, sticky='w', padx=2, pady=2) self.sf = ScrollableFrame(self) self.sf.grid(column=0, row=1, sticky='nsew') self.grid_rowconfigure(0, weight=0) self.grid_rowconfigure(1, weight=1) self.grid_columnconfigure(0, weight=1) else: self.sf = ScrollableFrame(self) self.sf.grid(column=0, row=0, sticky='nsew') if self.adder_script != DISABLED: self.add_button = Button(self.sf.frame, text="Add Row", command=self.add_row_from_button) self.add_button.grid(row=2, column=2 * self.num_columns - 1) self.add_button.bind(OSCONST.ADDROW, self._add_row_from_key) self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) if self.headings is not None: for i, heading in enumerate(self.headings): Label(self.sf.frame, text=heading).grid(column=2 * i, row=self.separator_offset, sticky='nsew', padx=2, pady=2) Separator(self.sf.frame, orient='horizontal').grid( column=0, row=self.separator_offset + 1, columnspan=2 * self.num_columns - 1, sticky='ew') self.row_offset = self.sf.frame.grid_size()[1] def _draw_separators(self): """ Redraw all the separators when the table is being redrawn """ if self.style.get('nodividers', False): return rows = self.sf.frame.grid_size()[1] for i, sep in enumerate(self.separators): sep.grid_forget() sep.grid(column=2 * i + 1, row=self.separator_offset, rowspan=rows - self.separator_offset, sticky='ns') def _resize_to_max(self, **config): """ Resize the ScrollCanvas up to the maximum allowed size if a max number of rows is specified. """ max_x, max_y = (None, None) self.sf.update_idletasks() if self.max_rows is not None: if len(self.data) > self.max_rows: max_x, max_y = self.sf.frame.grid_bbox( column=0, row=self.sf.frame.grid_size()[1] - 2 - self.max_rows, col2=self.sf.frame.grid_size()[0] - 1, row2=self.sf.frame.grid_size()[1] - 1)[2:] self.sf.block_resize = False self.sf.configure_view(max_size=(max_x, max_y), needs_update=True, **config) #region properties @property def options(self): return self.add_options @options.setter def options(self, value): if len(value) > 0: self.nameselection.configure(values=value) self.nameselection.set(value[0]) #region class methods #TODO: move to utils? @staticmethod def ensure_2D_array(arr): """ If the provided array is not 2D convert it to one """ if isinstance(arr, list): if not isinstance(arr[0], list): return [arr] else: return arr else: raise ValueError("Provided data is not an array")
class TeamWindow: def __init__(self, parent, teams): self.window = Toplevel(parent.window) self.window.withdraw() self.parent = parent self.teams = deepcopy(teams) self.teamFrame = Frame(self.window) self.streamFrame = Frame(self.window) self.buttonFrame = Frame(self.window) self.isRename = False self.tempName = None self.currentTeam = None self.teamsExist = False self.pageLoaded = False self.comboboxTeam = None self.freeAgentListbox = None self.teamMemberListbox = None self.selectedFreeAgents = None self.selectedTeamMembers = None self.buttonLeftArrow = None self.buttonUpArrow = None self.buttonDownArrow = None self.buttonRightArrow = None self.buttonRename = None WindowHelper.initializeWindow(self.window, self.parent, 380, 282, 30, 50, LabelConstants.TEAM_WINDOW) self.gridFrames() self.addDropdown() self.addFreeAgentListbox() self.addListboxButtons() self.addTeamMemberListbox() self.addButtons() if self.teamsExist: self.switchActiveTeam() self.pageLoaded = True WindowHelper.finalizeWindow(self.window, self.parent) def gridFrames(self): self.buttonFrame.grid_columnconfigure(0, weight=1) self.buttonFrame.grid_columnconfigure(1, weight=1) self.buttonFrame.grid_columnconfigure(2, weight=1) self.buttonFrame.grid_columnconfigure(3, weight=1) self.teamFrame.grid(row=0, sticky=NSEW, padx=4, pady=4) self.streamFrame.grid(row=1, sticky=NSEW, padx=4, pady=4) self.buttonFrame.grid(row=2, sticky=NSEW, padx=4, pady=4) def addDropdown(self): teams = self.getListOfTeams() labelTeam = Label(self.teamFrame, text=LabelConstants.TEAMS_DROPDOWN) labelTeam.grid(row=0, column=0, sticky=NSEW, padx=4, pady=4) self.comboboxTeam = Combobox(self.teamFrame, values=teams, state="readonly") self.comboboxTeam.bind("<<ComboboxSelected>>", self.switchActiveTeam) if teams: self.teamsExist = True self.comboboxTeam.current(0) self.currentTeam = self.comboboxTeam.get() self.comboboxTeam.grid(row=0, column=1, padx=4, pady=4) buttonNewTeam = Button(self.teamFrame, text=LabelConstants.CREATE_NEW_TEAM, width=16, command=self.createNewTeam) buttonNewTeam.grid(row=0, column=2, sticky=NSEW, padx=(40, 4), pady=4) def addFreeAgentListbox(self): frameFreeAgentListBox = Frame(self.streamFrame) frameFreeAgentListBox.grid(row=0, column=0, sticky=NSEW, padx=4, pady=(0, 4)) labelFreeAgentListBox = Label(frameFreeAgentListBox, text=LabelConstants.FREE_AGENTS) labelFreeAgentListBox.grid(row=0, column=0, padx=4, sticky=W) scrollbar = Scrollbar(frameFreeAgentListBox) scrollbar.grid(row=1, column=1, sticky="NWS") self.freeAgentListbox = Listbox(frameFreeAgentListBox, selectmode=MULTIPLE, yscrollcommand=scrollbar.set, activestyle=NONE) scrollbar.config(command=self.freeAgentListbox.yview) self.freeAgentListbox.bind('<<ListboxSelect>>', self.onSelectFreeAgentListbox) self.freeAgentListbox.grid(row=1, column=0, sticky=NSEW, padx=(4, 0)) def addListboxButtons(self): frameListBoxButtons = Frame(self.streamFrame) frameListBoxButtons.grid(row=0, column=1, sticky=NSEW, pady=(0, 4)) self.buttonLeftArrow = Button(frameListBoxButtons, text=LabelConstants.LEFT, width=7, command=lambda: self.moveLeft(), state=DISABLED) self.buttonLeftArrow.grid(row=0, sticky=NSEW, padx=4, pady=(38, 4)) self.buttonUpArrow = Button(frameListBoxButtons, text=LabelConstants.UP, width=7, command=lambda: self.moveUp(), state=DISABLED) self.buttonUpArrow.grid(row=1, sticky=NSEW, padx=4, pady=4) self.buttonDownArrow = Button(frameListBoxButtons, text=LabelConstants.DOWN, width=7, command=lambda: self.moveDown(), state=DISABLED) self.buttonDownArrow.grid(row=2, sticky=NSEW, padx=4, pady=4) self.buttonRightArrow = Button(frameListBoxButtons, text=LabelConstants.RIGHT, width=7, command=lambda: self.moveRight(), state=DISABLED) self.buttonRightArrow.grid(row=3, sticky=NSEW, padx=4, pady=4) def addTeamMemberListbox(self): frameTeamMemberListbox = Frame(self.streamFrame) frameTeamMemberListbox.grid(row=0, column=2, sticky=NSEW, pady=(0, 4)) labelLiveListBox = Label(frameTeamMemberListbox, text=LabelConstants.TEAM_MEMBERS) labelLiveListBox.grid(row=0, column=0, padx=4, sticky=W) scrollbar = Scrollbar(frameTeamMemberListbox) scrollbar.grid(row=1, column=1, sticky="NWS") self.teamMemberListbox = Listbox(frameTeamMemberListbox, selectmode=SINGLE, yscrollcommand=scrollbar.set, activestyle=NONE) scrollbar.config(command=self.teamMemberListbox.yview) self.teamMemberListbox.bind('<<ListboxSelect>>', self.onSelectTeamMemberListbox) self.teamMemberListbox.grid(row=1, column=0, sticky=NSEW, padx=(4, 0)) def addButtons(self): # TODO: These don't need to be defined as self. self.buttonRename = Button(self.buttonFrame, text=LabelConstants.RENAME, width=8, command=lambda: self.rename()) self.buttonRename.grid(row=0, column=0, sticky=NSEW, padx=(8, 4), pady=4) buttonDelete = Button(self.buttonFrame, text=LabelConstants.DELETE, width=8, command=lambda: self.delete()) buttonDelete.grid(row=0, column=1, sticky=NSEW, padx=4, pady=4) buttonSave = Button(self.buttonFrame, text=LabelConstants.OK, width=8, command=lambda: self.ok()) buttonSave.grid(row=0, column=2, sticky=NSEW, padx=4, pady=4) buttonCancel = Button(self.buttonFrame, text=LabelConstants.CANCEL, width=8, command=lambda: self.window.destroy()) buttonCancel.grid(row=0, column=3, sticky=NSEW, padx=4, pady=4) def moveLeft(self): if self.selectedTeamMembers: for stream in self.selectedTeamMembers: self.freeAgentListbox.insert(END, self.teamMemberListbox.get(stream)) for stream in reversed(self.selectedTeamMembers): self.teamMemberListbox.delete(stream) self.teamMemberListbox.selection_clear(0, END) self.selectedTeamMembers = None self.buttonLeftArrow.configure(state=DISABLED) def moveUp(self): index = self.teamMemberListbox.curselection() if self.selectedTeamMembers and len(self.selectedTeamMembers) == 1 and index is not None and index[0] != 0: stream = self.teamMemberListbox.get(index[0]) self.teamMemberListbox.delete(index[0]) self.teamMemberListbox.insert(index[0] - 1, stream) self.teamMemberListbox.selection_set(index[0] - 1) def moveDown(self): index = self.teamMemberListbox.curselection() if self.selectedTeamMembers and len(self.selectedTeamMembers) == 1 and index is not None and index[0] != self.teamMemberListbox.size() - 1: stream = self.teamMemberListbox.get(index[0]) self.teamMemberListbox.delete(index[0]) self.teamMemberListbox.insert(index[0] + 1, stream) self.teamMemberListbox.selection_set(index[0] + 1) def moveRight(self): if self.selectedFreeAgents: for stream in self.selectedFreeAgents: self.teamMemberListbox.insert(END, self.freeAgentListbox.get(stream)) for stream in reversed(self.selectedFreeAgents): self.freeAgentListbox.delete(stream) self.freeAgentListbox.selection_clear(0, END) self.selectedFreeAgents = None self.buttonRightArrow.configure(state=DISABLED) def switchActiveTeam(self, event=None): if self.pageLoaded and self.currentTeam is not None and len(self.currentTeam) > 0: self.storeCurrentTeamChanges(self.currentTeam) teamMembers = self.teams[self.comboboxTeam.get()] freeAgents = sorted([x for x in self.teams[LabelConstants.ALL_TEAM] if x not in teamMembers], key=str.casefold) self.clearListboxes() for streamer in freeAgents: self.freeAgentListbox.insert(END, streamer) for streamer in teamMembers: self.teamMemberListbox.insert(END, streamer) self.currentTeam = self.comboboxTeam.get() def clearListboxes(self): self.freeAgentListbox.selection_clear(0, END) self.teamMemberListbox.selection_clear(0, END) self.freeAgentListbox.delete(0, END) self.teamMemberListbox.delete(0, END) def onSelectFreeAgentListbox(self, event): w = event.widget self.selectedFreeAgents = w.curselection() self.buttonRightArrow.configure(state=NORMAL) self.buttonLeftArrow.configure(state=DISABLED) self.buttonUpArrow.configure(state=DISABLED) self.buttonDownArrow.configure(state=DISABLED) def onSelectTeamMemberListbox(self, event): w = event.widget self.selectedTeamMembers = w.curselection() self.buttonRightArrow.configure(state=DISABLED) self.buttonLeftArrow.configure(state=NORMAL) if len(self.selectedTeamMembers) > 1: self.buttonUpArrow.configure(state=DISABLED) self.buttonDownArrow.configure(state=DISABLED) else: self.buttonUpArrow.configure(state=NORMAL) self.buttonDownArrow.configure(state=NORMAL) def getListOfTeams(self) -> List[str]: return list(key for key in self.teams.keys() if key != LabelConstants.ALL_TEAM and key != LabelConstants.TOP_TWITCH_TEAM) def rename(self): if self.comboboxTeam.current() >= 0: self.isRename = True TeamNameWindow(self) def storeCurrentTeamChanges(self, key): self.teams[key] = list(self.teamMemberListbox.get(0, END)) def ok(self): if self.comboboxTeam.get() != "": self.storeCurrentTeamChanges(self.comboboxTeam.get()) self.parent.setTeams(self.teams) self.window.destroy() def delete(self): self.teams.pop(self.comboboxTeam.get()) self.comboboxTeam.set("") self.comboboxTeam.selection_clear() self.clearListboxes() self.comboboxTeam.configure(values=self.getListOfTeams()) self.currentTeam = None def createNewTeam(self): self.isRename = False TeamNameWindow(self)
class _get_value_w_units(_Dialog): def body(self, master): dialogframe = Frame(master, width=466, height=221) self.dialogframe = dialogframe dialogframe.pack() self.make_Button_1( self.dialogframe ) # Button: Set XXX to None (not used) : at Main(3,1) self.make_Combobox_1( self.dialogframe) # Combobox: Mine Yours Ours : at Main(5,3) self.make_Entry_1(self.dialogframe) # Entry: at Main(5,2) self.make_Label_1( self.dialogframe) # Label: Input XXX Value : at Main(1,1) self.make_Label_2( self.dialogframe) # Label: definition : at Main(2,1) self.make_Label_3( self.dialogframe) # Label: Value : at Main(4,2) self.make_Label_4( self.dialogframe) # Label: Units : at Main(4,3) self.make_Label_5(self.dialogframe) # Label: XXX= : at Main(5,1) self.make_Label_6(self.dialogframe) # Label: at Main(5,0) self.make_Label_7(self.dialogframe) # Label: at Main(5,4) self.dialogframe.columnconfigure(4, weight=1) self.dialogframe.columnconfigure(0, weight=1) # >>>>>>insert any user code below this comment for section "top_of_init" self.set_value_to_none = False if not self.dialogOptions.get('show_none_btn', False): self.Button_1.grid_remove() self.Entry_1.focus_set() self.Entry_1.select_range(0, END) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Button_1" def make_Button_1(self, frame): """ Button: Set XXX to None (not used) : at Main(3,1)""" self.Button_1 = Button(frame, text="Set XXX to None (i.e. not used)", width="45") self.Button_1.grid(row=3, column=1, columnspan="3") # >>>>>>insert any user code below this comment for section "make_Button_1" self.Button_1.bind("<ButtonRelease-1>", self.Button_1_Click) name = self.dialogOptions.get('label', '') if not name: name = self.dialogOptions.get('name', '') self.Button_1.configure(text='Set %s to None (i.e. not used)' % name) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_1" def make_Combobox_1(self, frame): """ Combobox: Mine Yours Ours : at Main(5,3)""" self.Combobox_1 = Combobox(frame, values="Mine Yours Ours", text="Combobox_1") self.Combobox_1.grid(row=5, column=3, sticky="w") self.Combobox_1_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Combobox_1" units = self.dialogOptions.get('units', '') category = get_category(units) catL = categoryD.get(category, [units]) self.Combobox_1.configure(values=' '.join(catL)) self.Combobox_1.configure(textvariable=self.Combobox_1_StringVar) self.Combobox_1_StringVar.set(units) self.Combobox_1_StringVar_traceName = self.Combobox_1_StringVar.trace_variable( "w", self.Combobox_1_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Entry_1" def make_Entry_1(self, frame): """ Entry: at Main(5,2)""" self.Entry_1 = Entry(frame, width="15") self.Entry_1.grid(row=5, column=2, sticky="ew", columnspan="1") self.Entry_1_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Entry_1" value = self.dialogOptions.get('value', '') self.Entry_1_StringVar.set(value) self.Entry_1.configure(textvariable=self.Entry_1_StringVar) self.Entry_1_StringVar_traceName = self.Entry_1_StringVar.trace_variable( "w", self.Entry_1_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_1" def make_Label_1(self, frame): """ Label: Input XXX Value : at Main(1,1)""" self.Label_1 = Label(frame, text="Input XXX Value", width="60") self.Label_1.grid(row=1, column=1, columnspan="3") # >>>>>>insert any user code below this comment for section "make_Label_1" name = self.dialogOptions.get('label', '') if not name: name = self.dialogOptions.get('name', '') self.Label_1.configure(text='Input: ' + name) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_2" def make_Label_2(self, frame): """ Label: definition : at Main(2,1)""" self.Label_2 = Label(frame, text="definition", width="60", height="6") self.Label_2.grid(row=2, column=1, columnspan="3") # >>>>>>insert any user code below this comment for section "make_Label_2" desc = self.dialogOptions.get('desc', '') self.Label_2.configure(text=desc, wraplength=400) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_3" def make_Label_3(self, frame): """ Label: Value : at Main(4,2)""" self.Label_3 = Label(frame, text="Value", width="15") self.Label_3.grid(row=4, column=2) # >>>>>>insert any user code below this comment for section "make_Label_3" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_4" def make_Label_4(self, frame): """ Label: Units : at Main(4,3)""" self.Label_4 = Label(frame, text="Units", width="15", anchor="w") self.Label_4.grid(row=4, column=3) # >>>>>>insert any user code below this comment for section "make_Label_4" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_5" def make_Label_5(self, frame): """ Label: XXX= : at Main(5,1)""" self.Label_5 = Label(frame, text="XXX=", width="15", anchor="e") self.Label_5.grid(row=5, column=1, sticky="e") # >>>>>>insert any user code below this comment for section "make_Label_5" name = self.dialogOptions.get('name', '') self.Label_5.configure(text=name + '=') # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_6" def make_Label_6(self, frame): """ Label: at Main(5,0)""" self.Label_6 = Label(frame, text="", width="2") self.Label_6.grid(row=5, column=0) # >>>>>>insert any user code below this comment for section "make_Label_6" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_7" def make_Label_7(self, frame): """ Label: at Main(5,4)""" self.Label_7 = Label(frame, text="", width="2") self.Label_7.grid(row=5, column=4) # >>>>>>insert any user code below this comment for section "make_Label_7" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Button_1_Click" def Button_1_Click(self, event): #bind method for component ID=Button_1 """ Button: Set XXX to None (not used) : at Main(3,1)""" pass # >>>>>>insert any user code below this comment for section "Button_1_Click" # replace, delete, or comment-out the following #print( "executed method Button_1_Click" ) self.set_value_to_none = True self.ok() # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_1_StringVar_traceName" def Combobox_1_StringVar_Callback(self, varName, index, mode): """ Combobox: Mine Yours Ours : at Main(5,3)""" pass # >>>>>>insert any user code below this comment for section "Combobox_1_StringVar_traceName" # replace, delete, or comment-out the following #print( "Combobox_1_StringVar_Callback varName, index, mode",varName, index, mode ) #print( " new StringVar value =",self.Combobox_1_StringVar.get() ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Entry_1_StringVar_traceName" def Entry_1_StringVar_Callback(self, varName, index, mode): """ Entry: at Main(5,2)""" pass # >>>>>>insert any user code below this comment for section "Entry_1_StringVar_traceName" # replace, delete, or comment-out the following #print( "Entry_1_StringVar_Callback varName, index, mode",varName, index, mode ) #print( " new StringVar value =",self.Entry_1_StringVar.get() ) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "standard_message_dialogs" # standard message dialogs... showinfo, showwarning, showerror def ShowInfo(self, title='Title', message='your message here.'): tkinter.messagebox.showinfo(title, message) return def ShowWarning(self, title='Title', message='your message here.'): tkinter.messagebox.showwarning(title, message) return def ShowError(self, title='Title', message='your message here.'): tkinter.messagebox.showerror(title, message) return # standard question dialogs... askquestion, askokcancel, askyesno, or askretrycancel # return True for OK, Yes, Retry, False for Cancel or No def AskYesNo(self, title='Title', message='your question here.'): return tkinter.messagebox.askyesno(title, message) def AskOK_Cancel(self, title='Title', message='your question here.'): return tkinter.messagebox.askokcancel(title, message) def AskRetryCancel(self, title='Title', message='your question here.'): return tkinter.messagebox.askretrycancel(title, message) # return "yes" for Yes, "no" for No def AskQuestion(self, title='Title', message='your question here.'): return tkinter.messagebox.askquestion(title, message) # END of standard message dialogs # >>>>>>insert any user code below this comment for section "standard_message_dialogs" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "dialog_validate" def validate(self): self.result = {} # return a dictionary of results #self.result["Combobox_1"] = self.Combobox_1_StringVar.get() #self.result["Entry_1"] = self.Entry_1_StringVar.get() # >>>>>>insert any user code below this comment for section "dialog_validate" # set values in "self.result" dictionary for return # for example... # self.result["age"] = self.Entry_2_StringVar.get() self.result["return_units"] = self.Combobox_1_StringVar.get() s = self.Entry_1_StringVar.get().strip() if self.set_value_to_none or s.lower() == 'none': self.result["return_value"] = None else: try: s = eval(s) except: self.ShowError( title='Invalid Number', message='"%s" NOT recognized as number\nPlease Try Again.' % s) return 0 try: value = float(s) except: self.ShowError( title='Invalid Number', message='"%s" is NOT a number\nPlease Try Again.' % s) return 0 self.result["return_value"] = s #print('Value w Units Dialog result =', self.result) #self.result["test"] = "test message" return 1 """ replace test code desc = 'radius of curvature just downstream of throat (Rdownstream / Rthrt) this could be a very long description and we would just need to wrap it.' dialog = _get_value_w_units(self.master, "Test Dialog", dialogOptions={'name':'Rthrt', 'units':'in', 'value':'22', 'desc':desc, 'show_none_btn':True}) """ # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "end" def apply(self): pass
Checkbutton3.configure(text='''Header photo''') Checkbutton3.configure(variable=check2) Label1 = Label(Frame1) Label1.place(relx=0.04, rely=-0.04) Label1.configure(text='''Upload''') Button1 = Button(Frame1) Button1.place(relx=0.74, rely=0.7, height=25, width=60) Button1.configure(padding=(2, 0, 0, 0)) Button1.configure(text='''Upload''') Button1.configure(command=up) TCombobox1 = Combobox(Frame1) TCombobox1.place(relx=0.09, rely=0.22, relheight=0.18, relwidth=0.61) TCombobox1.configure(textvariable=combobox1) TCombobox1.configure(width=173) TCombobox1.configure(takefocus="") TCombobox1.configure(state="readonly") TCombobox1['values'] = photos Frame3 = Frame(root) Frame3.place(relx=0.02, rely=0.33, relheight=0.63, relwidth=0.46) Frame3.configure(relief=GROOVE) Frame3.configure(borderwidth="2") Frame3.configure(relief=GROOVE) Frame3.configure(width=285) Label4 = Label(Frame3) Label4.place(relx=0.04, rely=-0.04, height=21, width=44) Label4.configure(text='''Follow''')
def OnDoubleClick(self, event): """ редактирование элемента по двойному клику """ common_width = 17 add_width = 3 add_item_window = Toplevel() add_item_window.minsize(width=250, height=340) item = self.selection()[0] set_to_edit = self.item(item, "values") labels = [item for item in self.data] lbl = [] values = {} for i in range(0, len(labels)): values[labels[i]] = StringVar() lbl.append(Label(add_item_window, text=labels[i])) lbl[i].grid(column=0, row=i, padx=10, pady=10, sticky='w') if labels[i] == 'Кинотеатр': v = Combobox( add_item_window, values=[row[0] for index, row in self.cinemas.iterrows()], textvariable=values[labels[i]], width=common_width) elif labels[i] == 'Время': v = Entry(add_item_window, textvariable=values[labels[i]]) values[labels[i]].trace( 'w', lambda name, index, mode, sv=values[labels[ i]], item=v: entryUpdateEndHour(sv, item)) values[labels[i]].set(set_to_edit[i]) elif labels[i] == 'Фильм': """ живое подтверждение того, что DataFrame для строк идея плохая """ lst = list(self.films['Фильм']) lst = [item.replace('[', '') for item in lst] lst = [item.strip("'") for item in lst] v = Combobox(add_item_window, values=lst, textvariable=values[labels[i]], width=common_width) # это можно переписать с помощью lambda в одну строку elif labels[i] == 'Класс': v = Combobox(add_item_window, values=self.dictionaries['class'], textvariable=values[labels[i]], width=common_width) elif labels[i] == '3D': v = Combobox(add_item_window, values=self.dictionaries['3D'], textvariable=values[labels[i]], width=common_width) elif labels[i] == 'Статус': v = Combobox(add_item_window, values=self.dictionaries['status'], textvariable=values[labels[i]], width=common_width) else: v = Entry(add_item_window, textvariable=values[labels[i]], width=common_width + add_width) if labels[i] == 'Билет': v.configure(state=DISABLED) values[labels[i]].trace('w', lambda name, index, mode, sv=values[labels[ i]], item=v: updateBoxes(sv, item)) values[labels[i]].set(set_to_edit[i]) v.grid(column=1, row=i, padx=10, pady=10, sticky='w') ok_button = Button(add_item_window, text='Изменить', width=12, command=lambda data=values, frame=add_item_window: self.save_item(data, frame)) ok_button.grid(column=0, row=i + 1, pady=10, padx=10) cancel_button = Button(add_item_window, text='Отменить', command=add_item_window.destroy, width=12) cancel_button.grid(column=1, row=i + 1, pady=10, padx=15)
class _tk_rocket_units: def __init__(self, master): grid_frame = Frame(master) self.grid_frame = grid_frame grid_frame.pack(expand=1, fill=BOTH) self.master = master self.x, self.y, self.w, self.h = 10, 10, 403, 513 self.master.title("tk_rocket_units") self.make_Frame_1(self.grid_frame) # Frame: at Main(1,1) self.make_Label_10(self.grid_frame) # Label: at Main(0,0) self.make_Label_11(self.grid_frame) # Label: at Main(4,1) self.make_Label_7(self.grid_frame) # Label: at Main(2,1) self.make_Label_8(self.grid_frame) # Label: at Main(1,0) self.make_Label_9(self.grid_frame) # Label: at Main(1,2) self.make_Text_1(self.grid_frame) # Text: at Main(3,1) self.make_Combobox_1( self.Frame_1) # Combobox: Mine Yours Ours : at Frame_1(1,1) self.make_Combobox_2( self.Frame_1) # Combobox: Mine Yours Ours : at Frame_1(3,1) self.make_Combobox_3( self.Frame_1) # Combobox: Mine Yours Ours : at Frame_1(6,3) self.make_Entry_1(self.Frame_1) # Entry: at Frame_1(5,1) self.make_Label_1( self.Frame_1) # Label: Category : at Frame_1(1,2) self.make_Label_2(self.Frame_1) # Label: Units : at Frame_1(3,2) self.make_Label_3(self.Frame_1) # Label: Value : at Frame_1(5,2) self.make_Label_4( self.Frame_1) # Label: Number Format : at Frame_1(5,3) self.make_Label_5(self.Frame_1) # Label: at Frame_1(2,1) self.make_Label_6(self.Frame_1) # Label: at Frame_1(4,1) self.grid_frame.rowconfigure(3, weight=1) self.grid_frame.columnconfigure(1, weight=1) # >>>>>>insert any user code below this comment for section "top_of_init" self.master.title("RocketUnits v%s" % get_version()) self.show_all_units() # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Frame_1" def make_Frame_1(self, frame): """ Frame: at Main(1,1)""" self.Frame_1 = Frame(frame, width="60", height="50", borderwidth="0", relief="flat") self.Frame_1.grid(row=1, column=1, sticky="w") # >>>>>>insert any user code below this comment for section "make_Frame_1" def show_all_units(self): self.Text_1.delete(1.0, END) cat = self.Combobox_1_StringVar.get() inp_units = self.Combobox_2_StringVar.get() fmt = float_formatD[self.Combobox_3_StringVar.get()] try: inp_val = float(self.Entry_1_StringVar.get()) except: inp_val = 0.0 def_unit_val = (inp_val - offsetD[inp_units]) / conv_factD[inp_units] for units in display_unitsD[cat]: val = def_unit_val * conv_factD[units] + offsetD[units] if fmt == 'd': dval = eng_context.create_decimal_from_float(val) sOut = dval.to_eng_string() elif fmt == 's': dval = sci_context.create_decimal_from_float(val) sOut = str(dval.normalize()) else: sOut = fmt % val self.Text_1.insert(END, UNIT_FMT_STR % units + " = " + sOut + '\n') # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_10" def make_Label_10(self, frame): """ Label: at Main(0,0)""" self.Label_10 = Label(frame, text="", width="4") self.Label_10.grid(row=0, column=0) # >>>>>>insert any user code below this comment for section "make_Label_10" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_11" def make_Label_11(self, frame): """ Label: at Main(4,1)""" self.Label_11 = Label(frame, text="", width="4") self.Label_11.grid(row=4, column=1) # >>>>>>insert any user code below this comment for section "make_Label_11" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_7" def make_Label_7(self, frame): """ Label: at Main(2,1)""" self.Label_7 = Label(frame, text="", width="15") self.Label_7.grid(row=2, column=1) # >>>>>>insert any user code below this comment for section "make_Label_7" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_8" def make_Label_8(self, frame): """ Label: at Main(1,0)""" self.Label_8 = Label(frame, text="", width="4") self.Label_8.grid(row=1, column=0) # >>>>>>insert any user code below this comment for section "make_Label_8" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_9" def make_Label_9(self, frame): """ Label: at Main(1,2)""" self.Label_9 = Label(frame, text="", width="4") self.Label_9.grid(row=1, column=2) # >>>>>>insert any user code below this comment for section "make_Label_9" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Text_1" def make_Text_1(self, frame): """ Text: at Main(3,1)""" self.Text_1 = Text(frame, width="40", height="20") self.Text_1.grid(row=3, column=1, sticky="nsew") # >>>>>>insert any user code below this comment for section "make_Text_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_1" def make_Combobox_1(self, frame): """ Combobox: Mine Yours Ours : at Frame_1(1,1)""" self.Combobox_1 = Combobox(frame, values="Mine Yours Ours", text="Combobox_1") self.Combobox_1.grid(row=1, column=1, sticky="e") self.Combobox_1_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Combobox_1" self.Combobox_1.configure(textvariable=self.Combobox_1_StringVar) self.Combobox_1_StringVar.set("Length") self.Combobox_1['height'] = len(categoryL) self.Combobox_1['values'] = categoryL self.Combobox_1_StringVar_traceName = self.Combobox_1_StringVar.trace_variable( "w", self.Combobox_1_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_2" def make_Combobox_2(self, frame): """ Combobox: Mine Yours Ours : at Frame_1(3,1)""" self.Combobox_2 = Combobox(frame, values="Mine Yours Ours", text="Combobox_2") self.Combobox_2.grid(row=3, column=1, sticky="e") self.Combobox_2_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Combobox_2" self.Combobox_2.configure(textvariable=self.Combobox_2_StringVar) self.Combobox_2_StringVar.set("ft") self.Combobox_2['height'] = 20 self.Combobox_2['values'] = display_unitsD[ self.Combobox_1_StringVar.get()] self.Combobox_2_StringVar_traceName = self.Combobox_2_StringVar.trace_variable( "w", self.Combobox_2_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Combobox_3" def make_Combobox_3(self, frame): """ Combobox: Mine Yours Ours : at Frame_1(6,3)""" self.Combobox_3 = Combobox(frame, values="Mine Yours Ours", text="Combobox_3") self.Combobox_3.grid(row=6, column=3, sticky="e") self.Combobox_3_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Combobox_3" self.Combobox_3.configure(textvariable=self.Combobox_3_StringVar) self.Combobox_3_StringVar.set("general") self.Combobox_3['height'] = len(float_formatD) self.Combobox_3['values'] = list(float_formatL) self.Combobox_3_StringVar_traceName = self.Combobox_3_StringVar.trace_variable( "w", self.Combobox_3_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Entry_1" def make_Entry_1(self, frame): """ Entry: at Frame_1(5,1)""" self.Entry_1 = Entry(frame, width="13") self.Entry_1.grid(row=5, column=1, sticky="e") self.Entry_1_StringVar = StringVar() # >>>>>>insert any user code below this comment for section "make_Entry_1" self.Entry_1_StringVar.set("1.0") self.Entry_1.configure(textvariable=self.Entry_1_StringVar) self.Entry_1_StringVar_traceName = self.Entry_1_StringVar.trace_variable( "w", self.Entry_1_StringVar_Callback) # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_1" def make_Label_1(self, frame): """ Label: Category : at Frame_1(1,2)""" self.Label_1 = Label(frame, text="Category", width="15", anchor="w") self.Label_1.grid(row=1, column=2, sticky="w") # >>>>>>insert any user code below this comment for section "make_Label_1" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_2" def make_Label_2(self, frame): """ Label: Units : at Frame_1(3,2)""" self.Label_2 = Label(frame, text="Units", width="15", anchor="w") self.Label_2.grid(row=3, column=2, sticky="w") # >>>>>>insert any user code below this comment for section "make_Label_2" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_3" def make_Label_3(self, frame): """ Label: Value : at Frame_1(5,2)""" self.Label_3 = Label(frame, text="Value", width="15", anchor="w") self.Label_3.grid(row=5, column=2, sticky="w") # >>>>>>insert any user code below this comment for section "make_Label_3" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_4" def make_Label_4(self, frame): """ Label: Number Format : at Frame_1(5,3)""" self.Label_4 = Label(frame, text="Number Format", width="15") self.Label_4.grid(row=5, column=3) # >>>>>>insert any user code below this comment for section "make_Label_4" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_5" def make_Label_5(self, frame): """ Label: at Frame_1(2,1)""" self.Label_5 = Label(frame, text="", width="15") self.Label_5.grid(row=2, column=1) # >>>>>>insert any user code below this comment for section "make_Label_5" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "make_Label_6" def make_Label_6(self, frame): """ Label: at Frame_1(4,1)""" self.Label_6 = Label(frame, text="", width="15") self.Label_6.grid(row=4, column=1) # >>>>>>insert any user code below this comment for section "make_Label_6" # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_1_StringVar_traceName" def Combobox_1_StringVar_Callback(self, varName, index, mode): """ Combobox: Mine Yours Ours : at Frame_1(1,1)""" pass # >>>>>>insert any user code below this comment for section "Combobox_1_StringVar_traceName" # replace, delete, or comment-out the following self.Combobox_2['values'] = display_unitsD[ self.Combobox_1_StringVar.get()] self.Combobox_2_StringVar.set( display_def_unitsD[self.Combobox_1_StringVar.get()]) #self.Combobox_2.current(0) self.show_all_units() # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_2_StringVar_traceName" def Combobox_2_StringVar_Callback(self, varName, index, mode): """ Combobox: Mine Yours Ours : at Frame_1(3,1)""" pass # >>>>>>insert any user code below this comment for section "Combobox_2_StringVar_traceName" # replace, delete, or comment-out the following self.show_all_units() # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Combobox_3_StringVar_traceName" def Combobox_3_StringVar_Callback(self, varName, index, mode): """ Combobox: Mine Yours Ours : at Frame_1(6,3)""" pass # >>>>>>insert any user code below this comment for section "Combobox_3_StringVar_traceName" # replace, delete, or comment-out the following self.show_all_units() # TkGridGUI generated code. DO NOT EDIT THE FOLLOWING. section "Entry_1_StringVar_traceName" def Entry_1_StringVar_Callback(self, varName, index, mode): """ Entry: at Frame_1(5,1)""" pass # >>>>>>insert any user code below this comment for section "Entry_1_StringVar_traceName" # replace, delete, or comment-out the following self.Combobox_2['values'] = display_unitsD[ self.Combobox_1_StringVar.get()] #self.Combobox_2.current(0) self.show_all_units()
class MainWindow(mp.Process): """Defines the main control window and all its control logic. As Tkinter only allows to create root windwo (Tk()) in the main process, this is implemented as its own subprocess that will open the window with a call to self.run() Args: connector_dict: Dictionary create by calling multiprocessing.Manger().dict() message_q: Queue that will be polled every few seconds. Elements in queue will be plotted to the internal text field. start_analysis_e: Event signaling if analysis can be started connected_e: Event signaling that LSL streams are connected ready_for_connection_e: Event signaling that LSL streams have been selected in GUI save_e: Event signaling that data should be saved. """ def __init__(self, connector_dict: Dict, message_q: mp.Queue, start_recording_e: mp.Event, start_analysis_e: mp.Event, connected_e: mp.Event, ready_for_connection_e: mp.Event, save_e: mp.Event): super().__init__() self.connector_dict = connector_dict self.message_q = message_q self.start_recording_e = start_recording_e self.start_analysis_e = start_analysis_e self.ready_for_connection_e = ready_for_connection_e self.connected_e = connected_e self.save_e = save_e self.master = None # Parameters self.eeg_stream = None self.eeg_streams_dict = None self.marker_stream = None self.marker_streams_dict = None self.channel_select = None self.update_interval = None self.record_time = None self.y_min = None self.y_max = None self.save_filename = None self.filter_check = None self.squared_check = None self.connected = None # Widgets self.eeg_stream_label = None self.eeg_stream_combobox = None self.eeg_stream_button = None self.marker_stream_label = None self.marker_stream_combobox = None self.marker_stream_button = None self.filter_checkbutton_label = None self.filter_checkbutton = None self.connect_button = None self.seperator = None self.start_recording_btn = None self.record_time_label = None self.Separator_2 = None self.update_interval_label = None self.update_interval_combobox = None self.start_analysis_btn = None self.channel_select_label = None self.channel_select_combobox = None self.squared_label = None self.squared_checkbtn = None self.update_ylim_btn = None self.y_min_label = None self.y_min_entry = None self.y_max_label = None self.y_max_entry = None self.seperator = None self.save_label = None self.save_entry = None self.save_btn = None self.text_console = None def build_main_window(self): # Hack to make tkinter work in other process than main from tkinter import Tk, StringVar, Text, HORIZONTAL, EW, IntVar from tkinter.ttk import Separator, Combobox, Button, Label, Entry, Checkbutton self.master = Tk() # Parameters self.eeg_stream = StringVar() self.eeg_streams_dict = {} self.marker_stream = StringVar() self.marker_streams_dict = {} self.channel_select = IntVar() self.channel_select.set(0) self.update_interval = IntVar() self.update_interval.set(0) self.record_time = StringVar() self.record_time.set("00:00 minutes recorded") self.y_min = IntVar() self.y_min.set(-10) self.y_max = IntVar() self.y_max.set(10) self.save_filename = StringVar() self.save_filename.set("1") self.filter_check = IntVar() self.filter_check.set(1) self.squared_check = IntVar() self.squared_check.set(0) self.connected = False self.print_from_queue() # Widgets self.eeg_stream_label = Label(self.master, text='EEG LSL-stream:') self.eeg_stream_label.grid(row=0, column=0) self.eeg_stream_combobox = Combobox(self.master, textvariable=self.eeg_stream) self.eeg_stream_combobox.configure(state='disabled') self.eeg_stream_combobox.grid(row=0, column=1) self.eeg_stream_button = Button( self.master, text='Refresh', command=lambda: self.find_streams('EEG', self.eeg_stream_combobox, self.eeg_streams_dict, self. eeg_stream)) self.eeg_stream_button.grid(row=0, column=2) self.marker_stream_label = Label(self.master, text='Marker LSL-stream:') self.marker_stream_label.grid(row=1, column=0) self.marker_stream_combobox = Combobox(self.master, textvariable=self.marker_stream) self.marker_stream_combobox.configure(state='disabled') self.marker_stream_combobox.grid(row=1, column=1) self.marker_stream_button = Button( self.master, text='Refresh', command=lambda: self.find_streams( 'P300_Marker', self.marker_stream_combobox, self. marker_streams_dict, self.marker_stream)) self.marker_stream_button.grid(row=1, column=2) self.filter_checkbutton_label = Label( self.master, text='Filter (Butter, Order 4, Cutoff: 1, 30):') self.filter_checkbutton_label.grid(row=2, column=0) self.filter_checkbutton = Checkbutton(self.master, variable=self.filter_check, text='') self.filter_checkbutton.grid(row=2, column=1) self.connect_button = Button(self.master, text='Connect', command=self.connect_streams) self.connect_button.grid(row=2, column=2) self.connect_button.configure(state='disabled') self.seperator = Separator(self.master, orient=HORIZONTAL) self.seperator.grid(row=3, column=0, columnspan=3, sticky=EW) self.start_recording_btn = Button(self.master, text='Start recoding', command=self.start_recording) self.start_recording_btn.grid(row=4, column=2) self.start_recording_btn.configure(state='disabled') self.record_time_label = Label(self.master, textvariable=self.record_time) self.record_time_label.grid(row=4, column=1) self.Separator_2 = Separator(self.master) self.Separator_2.grid(row=5, column=0, columnspan=3, sticky=EW) self.update_interval_label = Label(self.master, text='Update interval (seconds):') self.update_interval_label.grid(row=6, column=0) self.update_interval_combobox = Combobox( self.master, textvariable=self.update_interval) self.update_interval_combobox.bind('<<ComboboxSelected>>', self.update_connector_dict) self.update_interval_combobox.grid(row=6, column=1) self.update_interval_combobox['values'] = list(range(10)) self.update_interval_combobox.configure(state='disabled') self.start_analysis_btn = Button(self.master, text='Start analysis', command=self.start_analysis) self.start_analysis_btn.grid(row=6, column=2) self.start_analysis_btn.configure(state='disabled') self.channel_select_label = Label(self.master, text='Channel to display:') self.channel_select_label.grid(row=7, column=0) self.channel_select_combobox = Combobox( self.master, textvariable=self.channel_select) self.channel_select_combobox.bind('<<ComboboxSelected>>', self.update_connector_dict) self.channel_select_combobox.grid(row=7, column=1) self.channel_select_combobox.configure(state='disabled') self.squared_label = Label(self.master, text='squared') self.squared_label.grid(row=8, column=0) self.squared_checkbtn = Checkbutton(self.master, variable=self.squared_check) self.squared_checkbtn.grid(row=8, column=1) self.squared_checkbtn.configure(state='disabled') self.update_ylim_btn = Button(self.master, text='Update', command=self.update_connector_dict) self.update_ylim_btn.grid(row=8, column=2) self.update_ylim_btn.configure(state='disabled') self.y_min_label = Label(self.master, text='Y min:') self.y_min_label.grid(row=9, column=0) self.y_min_entry = Entry(self.master, textvariable=self.y_min) self.y_min_entry.grid(row=9, column=1) self.y_min_entry.configure(state='disabled') self.y_max_label = Label(self.master, text='Y max:') self.y_max_label.grid(row=10, column=0) self.y_max_entry = Entry(self.master, textvariable=self.y_max) self.y_max_entry.grid(row=10, column=1) self.y_max_entry.configure(state='disabled') self.seperator = Separator(self.master, orient=HORIZONTAL) self.seperator.grid(row=11, column=0, columnspan=3, sticky=EW) self.save_label = Label(self.master, text='Filename:') self.save_label.grid(row=12, column=0) self.save_entry = Entry(self.master, textvariable=self.save_filename) self.save_entry.grid(row=12, column=1) self.save_entry.configure(state='disabled') self.save_btn = Button(self.master, text='Save', command=self.save) self.save_btn.grid(row=12, column=2) self.save_btn.configure(state='disabled') self.text_console = Text(self.master) self.text_console.grid(row=15, column=0, rowspan=3, columnspan=3) self.text_console.configure(state='disabled') def save(self): self.update_connector_dict() self.save_e.set() def update_channel_select(self): num_channels = self.connector_dict['number of channels'] self.channel_select_combobox['values'] = list(range(num_channels)) def start_recording(self): self.connect_button.configure(state='disabled') self.start_recording_btn.configure(state='disabled') self.channel_select_combobox.configure(state='normal') self.update_interval_combobox.configure(state='normal') self.y_min_entry.configure(state='normal') self.y_max_entry.configure(state='normal') self.update_ylim_btn.configure(state='normal') self.squared_checkbtn.configure(state='normal') self.update_channel_select() self.update_recording_time() self.start_recording_e.set() self.start_analysis_btn.configure(state='normal') def update_recording_time(self): num_samples = self.connector_dict['sample count'] samplerate = self.connector_dict['samplerate'] number_of_seconds = int(num_samples / samplerate) minutes = number_of_seconds // 60 remaining_seconds = number_of_seconds % 60 result_string = '{:02}:{:02} minutes recorded'.format( minutes, remaining_seconds) self.record_time.set(result_string) self.master.after(1000, self.update_recording_time) def start_analysis(self): self.start_analysis_btn.configure(state='disabled') self.save_btn.configure(state='normal') self.save_entry.configure(state='normal') self.update_connector_dict() self.start_analysis_e.set() def find_streams(self, stream_type, widget, stream_dict, var): stream_dict.clear() timeout = 3 self.print_to_console('Searching for ' + stream_type + ' streams... (timeout = ' + str(timeout) + ' seconds)') streams = resolve_byprop('type', stream_type, timeout=timeout) if not streams: self.print_to_console('No stream found.') return widget.configure(state='normal') stream_list = [] for stream in streams: stream_dict[stream.name()] = stream stream_list.append(stream.name()) widget['values'] = stream_list if len(streams) >= 1: var.set(streams[0].name()) self.print_to_console(str(len(streams)) + ' Stream(s) found!') self.test_if_two_streams() def test_if_two_streams(self): if self.eeg_stream.get() is not '' and self.marker_stream.get( ) is not '': self.connect_button.configure(state='normal') else: self.connect_button.configure(state='disabled') def print_to_console(self, text_to_print): text_to_print = str(text_to_print) self.text_console.configure(state='normal') self.text_console.insert('end', text_to_print + '\n') self.text_console.configure(state='disabled') def print_from_queue(self): if not self.message_q.empty(): self.print_to_console(self.message_q.get()) self.master.after(500, self.print_from_queue) # noinspection PyUnusedLocal def update_connector_dict(self, event=None): self.connector_dict['update interval'] = self.update_interval.get() self.connector_dict['channel select'] = self.channel_select.get() self.connector_dict['eeg streamname'] = self.eeg_stream.get() self.connector_dict['marker streamname'] = self.marker_stream.get() self.connector_dict['y lim'] = [self.y_min.get(), self.y_max.get()] self.connector_dict['savefile'] = self.save_filename.get() self.connector_dict['filter'] = self.filter_check.get() self.connector_dict['squared'] = self.squared_check.get() def connect_streams(self): self.eeg_stream_combobox.configure(state='disabled') self.eeg_stream_button.configure(state='disabled') self.marker_stream_combobox.configure(state='disabled') self.marker_stream_button.configure(state='disabled') self.filter_checkbutton.configure(state='disabled') self.connect_button.configure(state='disabled') self.update_connector_dict() self.ready_for_connection_e.set() self.connected_e.wait() self.start_recording_btn.configure(state='normal') def run(self): self.build_main_window() self.master.mainloop()
class ChooseSeats: """ChooseSeats class: ChooseSeats window. - Choose how many tickets you want - Choose which seats you want - See how much it cost for tickets old_window: reference to the tk() object (Login window) username: User's username -_- location: Location where the employee works. Use to get the database of that location scheduleId: Use to access and modify seating and update database """ def __init__(self, username, scheduleID, old_window, location): global cinemaDB_path cinemaDB_path = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", f"{location}.db")) self.old_window = old_window self.username = username self.scheduleID = scheduleID self.location = location self.cinema_info = get_cinema_info(scheduleID=scheduleID) self.movie_name = self.cinema_info["movie_name"] self.movie_time = self.cinema_info["movie_time"] self.movie_date = self.cinema_info["movie_date"] self.cinema_hall = self.cinema_info["cinema_hall"] self._seat_layout = seating_layout_list( self.cinema_info["cinema_layout"]) self.available_seats = self.cinema_info["available_seats"] self.num_seats_chosen = 0 self._btn_list = [] self._temp_choice = [] # Ticket Price self.adult_price = Decimal(9.20) self.child_price = Decimal(7.80) self.window = Toplevel() self.window.title("Choose your seats.") self.window.geometry("900x600+300+10") self.window.resizable(False, False) self.window.protocol( "WM_DELETE_WINDOW", self.go_back) # Closing the window is same as signing out # Background Label(self.window).grid(row=0, column=0, padx=(60, 0)) # Just for aligning the GUI self.window.bg = PhotoImage(file="image/Seating.gif") self.background = Label(self.window, image=self.window.bg, width=900, height=600) self.background.place(x=0, y=0) self.heading = Label(self.window, text="Choose your seats", font=("Arial", 30), bg="#D7BDE2") self.heading.grid(row=0, column=0, columnspan=1200, padx=(80, 0), pady=(10, 0)) self.go_back_btn = Button(self.window, text="Go Back", command=self.go_back, font=15, bd=1, bg="#D0D3D4") self.go_back_btn.place(x=30, y=15) # Cinema Screen self.screen = Label(self.window, text="Screen", width=50, height=2, bg="#EBC9C2", font=20) self.screen.grid(row=3, column=0, columnspan=1200, pady=15, padx=(80, 0)) # If there are available seats, enable them to book seats. if self.available_seats != 0: # Choose the number of tickets self.num_tickets_display = Label( self.window, text="How many movie tickets do you want:", bg="#D7BDE2", font=("Arial", 15)) self.num_tickets_display.grid(row=1, column=0, pady=(20, 4), columnspan=50, padx=(70, 0)) self.ticket_frame = LabelFrame( self.window, text= " Type\t Price\t Quantity Sub Total Total", fg="white", bg="#414141", font=("Arial", 12)) self.ticket_frame.grid(row=2, column=0, columnspan=50, padx=(60, 0)) # Adult tickets self.adult_ticket_lbl = Label(self.ticket_frame, text="Adult", font=("Arial", 10), fg="white", bg="#A6A6A6", width=9) self.adult_ticket_lbl.grid(row=0, column=0) self.adult_price_lbl = Label( self.ticket_frame, text=f"£{self.adult_price.quantize(Decimal('0.00'))}", fg="#EEEEEE", bg="#A6A6A6", font=("Arial", 10), width=10) self.adult_price_lbl.grid(row=0, column=1) self.adult_option = Combobox(self.ticket_frame, state="readonly", width=10) self.adult_option.grid(row=0, column=2) self.adult_option["values"] = list( range(0, self.available_seats + 1)) self.adult_option.current(0) self.adult_total = Label(self.ticket_frame, text="£0.00", fg="#EEEEEE", bg="#A6A6A6", font=("Arial", 10), width=10) self.adult_total.grid(row=0, column=3) self.adult_option.bind("<<ComboboxSelected>>", lambda e: self.adult_ticket_update()) # Children tickets self.child_ticket_lbl = Label(self.ticket_frame, text="Child", fg="white", bg="#A6A6A6", font=("Arial", 10), width=9) self.child_ticket_lbl.grid(row=1, column=0) self.child_price_lbl = Label( self.ticket_frame, text=f"£{self.child_price.quantize(Decimal('0.00'))}", fg="#EEEEEE", bg="#A6A6A6", font=("Arial", 10), width=10) self.child_price_lbl.grid(row=1, column=1) self.child_option = Combobox(self.ticket_frame, state="readonly", width=10) self.child_option.grid(row=1, column=2) self.child_option["values"] = list( range(0, self.available_seats + 1)) self.child_option.current(0) self.child_total = Label(self.ticket_frame, text="£0.00", fg="#EEEEEE", bg="#A6A6A6", font=("Arial", 10), width=10) self.child_total.grid(row=1, column=3) self.child_option.bind("<<ComboboxSelected>>", lambda e: self.child_ticket_update()) # Total Cost self.total_cost = Label(self.ticket_frame, text="£0.00", fg="#EEEEEE", bg="#A6A6A6", font=("Arial", 13), width=9, height=2) self.total_cost.grid(row=0, rowspan=2, column=4) self.enter_btn = Button(self.window, text="Enter", command=self.enter, bd=2, bg="#FAE5D3", font=("Arial", 10)) self.enter_btn.grid(row=2, column=16) self.change_btn = Button(self.window, text="Change", command=self.choose_again, bd=1, bg="#FAE5D3") self.pay_btn = Button(self.window, text="Pay", font=15, bg="#D6EAF8", command=self.pay_function, bd=1) self.pay_btn.grid(row=20, column=10, pady=10, columnspan=2) else: self.no_booking = Label(self.window, text="There are no seats available.", font=("Arial", 20), bg="#F54949") self.no_booking.grid(row=1, column=0, pady=(20, 4), columnspan=50, padx=(70, 0)) x, y = 1, 1 for i in self._seat_layout: level = [] for j in i: if j == 0: btn = Button(self.window, width=5, height=2, bd=1, bg="white", command=partial(self.press_seat, (x - 1, y - 1))) if x == 1: btn.grid(column=x + 1, row=y + 3) else: btn.grid(column=x + 1, row=y + 3) level.append(btn) elif j == 1: btn = Button(self.window, width=5, height=2, bd=1, bg="grey", state="disabled", command=partial(self.press_seat, (x - 1, y - 1))) btn.grid(column=x + 1, row=y + 3) level.append(btn) else: level.append(NONE) x += 1 self._btn_list.append(level) x = 1 y += 1 def go_back(self): self.window.destroy() self.old_window.deiconify() def enter(self): if self.child_option.get() != "0" and self.adult_option.get() == "0": messagebox.showinfo("Invalid", "There must be at least one adult.") elif self.adult_option.get() != "0" or self.child_option.get() != "0": self.num_seats_chosen = int(self.adult_option.get()) + int( self.child_option.get()) self.adult_option.configure(state="disabled") self.child_option.configure(state="disabled") self.enter_btn.configure(state="disabled") self.change_btn.grid(row=2, column=17, columnspan=2) else: messagebox.showinfo( "Invalid", "Choose how many tickets you want, then you can choose your seats." ) def adult_ticket_update(self): sub_total = Decimal(self.adult_price * int(self.adult_option.get())).quantize( Decimal('0.00')) self.adult_total.configure(text=f"£{sub_total}") self.child_option["values"] = list( range(0, (self.available_seats + 1) - int(self.adult_option.get()))) total = Decimal(sub_total) + Decimal( self.child_price * int(self.child_option.get())).quantize( Decimal('0.00')) self.total_cost.configure(text=total.quantize(Decimal('0.00'))) def child_ticket_update(self): sub_total = Decimal(self.child_price * int(self.child_option.get())).quantize( Decimal('0.00')) self.child_total.configure(text=f"£{sub_total}") self.adult_option["values"] = list( range(0, (self.available_seats + 1) - int(self.child_option.get()))) total = Decimal(sub_total) + Decimal( self.adult_price * int(self.adult_option.get())).quantize( Decimal('0.00')) self.total_cost.configure(text=total.quantize(Decimal('0.00'))) def pay_function(self): if len( self._temp_choice ) == self.num_seats_chosen and self.enter_btn["state"] == "disabled": num_to_alph = { 0: "A", 1: "B", 2: "C", 3: "D", 4: "E", 5: "F", 6: "G", 7: "H" } seat = ",".join([ str(i[0] + 1) + str(num_to_alph[i[1]]) for i in self._temp_choice ]) message = f""" Movie: {self.movie_name} Location: {self.location} Date: {self.movie_date} Time: {self.movie_time} Cinema Hall: {self.cinema_hall} Number Of Seats: {len(self._temp_choice)} Adult Ticket{"s" if int(self.adult_option.get()) > 1 else ""}: {self.adult_option.get()} Child Ticket{"s" if int(self.child_option.get()) > 1 else ""}: {self.child_option.get()} Seat Location{"s" if len(self._temp_choice) > 1 else ""}: {seat} Total Cost: £{self.total_cost.cget("text")} Are you ready to pay?""" if messagebox.askyesno("Confirm", message): global userDB_path db = sqlite3.connect(userDB_path) cursor = db.cursor() cursor.execute( f"""SELECT userID FROM people WHERE username = ?""", (self.username, )) userID = cursor.fetchone()[0] db.close() new_available_seats = self.available_seats - len( self._temp_choice) updated_layout = seating_layout_string(self._seat_layout) global cinemaDB_path db = sqlite3.connect(cinemaDB_path) cursor = db.cursor() cursor.execute( """INSERT INTO customer_tickets(userID, scheduleID, user_tickets, num_tickets, adult_tickets, child_tickets, cost) VALUES(?,?,?,?,?,?,?)""", (userID, self.scheduleID, seat, len( self._temp_choice), self.adult_option.get(), self.child_option.get(), self.total_cost.cget("text"))) cursor.execute( """UPDATE seating_plan SET available_seats=?, cinema_layout=? WHERE scheduleID=?""", (new_available_seats, updated_layout, self.scheduleID)) db.commit() db.close() self.go_back() messagebox.showinfo("Enjoy", "Enjoy Your movie.") else: messagebox.showinfo("Invalid", "Please choose your seat first.") def choose_again(self): self.adult_option.configure(state="readonly") self.child_option.configure(state="readonly") self.enter_btn.configure(state="normal") self.change_btn.grid_forget() for pos in self._temp_choice: self._seat_layout[pos[1]][pos[0]] = 0 self._btn_list[pos[1]][pos[0]].configure(bg="white") self._temp_choice = [] self.num_seats_chosen = 0 def press_seat(self, pos): if self._seat_layout[pos[1]][pos[0]] != 3: if self.num_seats_chosen != 0: if len(self._temp_choice) < self.num_seats_chosen: self._btn_list[pos[1]][pos[0]].configure(bg="green") self._seat_layout[pos[1]][pos[0]] = 3 self._temp_choice.append((pos[0], pos[1])) else: messagebox.showwarning( "Invalid", "You have already chosen your seats." "\nIf you want to change it, you can do it by tapping the green square." ) else: messagebox.showinfo( "Invalid", "Choose how many tickets you want, then you can choose your seats." ) else: self._btn_list[pos[1]][pos[0]].configure(bg="white") self._seat_layout[pos[1]][pos[0]] = 0 self._temp_choice.remove((pos[0], pos[1]))
class MainWindow(Frame): """This class defines UI and functionality of the application main window Derives from class Frame""" # class variables left_panel_width = 300 left_upper_height = 270 # width required to display the calendar (date picker) notes_ctrl_height = 50 base_color = 'bisque' cover_color = 'indianred' lbl_font = '"Century Gothic" 16' lbl_fontcolor = 'floralwhite' input_font = '"Segoe UI" 16' input_fontcolor = 'brown' btn_font = '"Century Gothic" 12 bold' btn_fontcolor = 'brown' str_by_category = 'filter by category:' str_by_text = 'filter by text:' str_newnote = 'newnote' noteview_side = 250 note_padding = 5 def __init__(self, container): """ctor""" super().__init__(container) container.update_idletasks() self.total_height = container.winfo_height() self.total_width = container.winfo_width() self.left_middle_height = self.left_lower_height = ( self.total_height - __class__.left_upper_height) // 2 self.right_area_width = self.total_width - __class__.left_panel_width self.notes_display_height = self.total_height - self.__class__.notes_ctrl_height self.msgboard_img = PhotoImage( file=msgboard_img_path ) # object that represents the background as cork-board texture self.justdoit_img = PhotoImage( file=justdoit_img_path) # placeholder #1 self.colornotes_img = PhotoImage( file=colornotes_img_path) # placeholder #2 self.create_widgets(container) # initial calculation of the grid dimensions according to the available space and the note frame size self.cnvs_notes_display.gridcols_cnt = self.right_area_width // ( __class__.noteview_side + __class__.note_padding) self.cnvs_notes_display.gridrows_cnt = self.notes_display_height // ( __class__.noteview_side + __class__.note_padding) self.cnvs_notes_display.grid_propagate(False) def create_widgets(self, container): """This method defines UI of the main window""" self.frm_main = Frame(container) self.frm_main.pack(fill=BOTH, expand=True) self.frm_left_main = Frame(self.frm_main, width=__class__.left_panel_width, height=self.total_height, bg=__class__.base_color) self.frm_left_main.pack(side=LEFT) self.frm_left_top = Frame(self.frm_left_main, width=__class__.left_panel_width, height=__class__.left_upper_height, bg=__class__.cover_color) self.frm_left_top.grid(row=0) self.frm_left_top.grid_propagate(False) self.calendar = Calendar(self.frm_left_top, padx_param=__class__.left_panel_width / 5, pady_param=__class__.left_upper_height / 8) self.frm_left_middle = Frame(self.frm_left_main, width=__class__.left_panel_width, height=self.left_middle_height, bg=__class__.base_color) self.frm_left_middle.grid(row=1) self.cnvs_left_middle = Canvas( self.frm_left_middle, width=self.left_panel_width, height=self.left_middle_height) #, bg='white' self.cnvs_left_middle.grid(row=0, column=0) self.cnvs_left_middle.create_image(self.left_panel_width // 2, self.left_middle_height // 2, image=self.justdoit_img) self.frm_left_btm = Frame(self.frm_left_main, width=__class__.left_panel_width, height=self.left_lower_height, bg=__class__.base_color) self.frm_left_btm.grid(row=2) self.cnvs_left_bottom = Canvas( self.frm_left_btm, width=self.left_panel_width, height=self.left_lower_height) #, bg='white' self.cnvs_left_bottom.grid(row=0, column=0) self.cnvs_left_bottom.create_image(self.left_panel_width // 2, self.left_lower_height // 2, image=self.colornotes_img) self.frm_right_main = Frame(self.frm_main, width=self.right_area_width, height=self.total_height, bg=__class__.base_color) self.frm_right_main.pack() self.frm_notes_control = Frame(self.frm_right_main, width=self.right_area_width, height=__class__.notes_ctrl_height, bg=__class__.cover_color) self.frm_notes_control.pack(fill=X) self.frm_notes_control.pack_propagate(False) self.lbl_filter_by_category = Label(self.frm_notes_control, font=__class__.lbl_font, fg=__class__.lbl_fontcolor, bg=__class__.cover_color, text=__class__.str_by_category) self.lbl_filter_by_category.pack(side=LEFT) self.cmbx_filter_by_category = Combobox( self.frm_notes_control, font=__class__.input_font, foreground=__class__.input_fontcolor, textvariable=category_filter_ctrlvar) # ttk.Combobox self.cmbx_filter_by_category.configure(values=['All'] + category_names_lst) self.cmbx_filter_by_category.current(0) # i.e. default value is 'All' self.cmbx_filter_by_category.bind("<<ComboboxSelected>>", self.action_filter_notes) self.cmbx_filter_by_category.pack(side=LEFT) self.lbl_filter_by_text = Label(self.frm_notes_control, font=__class__.lbl_font, fg=__class__.lbl_fontcolor, bg=__class__.cover_color, text=__class__.str_by_text) self.lbl_filter_by_text.pack(side=LEFT) self.entry_filter_by_text = Entry(self.frm_notes_control, font=__class__.input_font, fg=__class__.input_fontcolor, textvariable=descr_filter_ctrlvar) self.entry_filter_by_text.bind('<KeyRelease>', self.action_filter_notes) self.entry_filter_by_text.pack(side=LEFT) self.btn_new_note = Button(self.frm_notes_control, font=__class__.btn_font, fg=__class__.btn_fontcolor, text=__class__.str_newnote) self.btn_new_note.bind("<Button-1>", action_new_note_dialog) self.btn_new_note.pack(side=RIGHT, padx=5) self.frm_notes_display = Frame(self.frm_right_main, width=self.right_area_width, height=self.notes_display_height, bg='bisque') self.frm_notes_display.pack() self.cnvs_notes_display = Canvas(self.frm_notes_display, width=self.right_area_width, height=self.notes_display_height) self.cnvs_notes_display.bind('<Configure>', self.action_config_display) self.cnvs_notes_display.pack(fill=BOTH) self.cnvs_notes_display.create_image(self.right_area_width // 2, self.notes_display_height // 2, image=self.msgboard_img) self.sizegrip = Sizegrip(self) #ttk.Sizegrip self.sizegrip.pack(side=RIGHT) def action_config_display(self, event): """This method deploys according to the new screen dimensions""" #self.after(250, clean_display()) root.update_idletasks() self.total_height = root.winfo_height() self.total_width = root.winfo_width() self.left_middle_height = self.left_lower_height = ( self.total_height - __class__.left_upper_height) // 2 self.right_area_width = self.total_width - __class__.left_panel_width self.notes_display_height = self.total_height - self.__class__.notes_ctrl_height # recalculation of the grid dimensions according to available space and note frame size self.cnvs_notes_display.gridcols_cnt = self.right_area_width // ( __class__.noteview_side + __class__.note_padding) self.cnvs_notes_display.gridrows_cnt = self.notes_display_height // ( __class__.noteview_side + __class__.note_padding) self.action_filter_notes(event) def action_filter_notes(self, event=None): """This method displays notes that meet currentl filtering criteria""" aux_filter_notes(category_filter_ctrlvar.get(), descr_filter_ctrlvar.get()) display_notes(event)
class NSE: def stop_all(self) -> None: self.stop = True def main_recursive(self) -> None: if (self.first_run): #print("FIRST time") self.refresh_data() self.first_run = False self.curr_time = time.time() time_passed = int(self.curr_time - self.prev_time) if (time_passed > self.interval): self.refresh_data() else: self.sh_window.after((10 * 1000), self.main_recursive) return if (not self.stop): self.sh_window.after((10 * 1000), self.main_recursive) return def __init__(self, window: Tk) -> None: self.first_run_live_price: List[float] = [] self.plot_only: bool = True self.graph_index, = plt.plot([], [], 'o-', label='BANKNIFTY') self.first_run: bool = True self.dict_dfs_INDEX: dict[pd.DataFrame] = {} self.dict_dfs_STOCK: dict[pd.DataFrame] = {} self.nb_names: List[String] = [ 'PCR OTM', 'DIFF OTM', 'PCR FAR OTM', 'CE-OTM', 'PE-OTM', 'CE-FAR_OTM', 'PE-FAR_OTM', 'LTP', 'PCR' ] for i in self.nb_names: self.dict_dfs_INDEX[i] = pd.DataFrame() self.dict_dfs_STOCK[i] = pd.DataFrame() self.stop: bool = False self.curr_time = "" self.interval = 5 #seconds self.red: str = "#e53935" self.green: str = "#00e676" self.df_INDEX: pd.DataFrame = pd.DataFrame() self.df_STOCK: pd.DataFrame = pd.DataFrame() self.popular_stocks: List[str] = ['AUROPHARMA','TATASTEEL','ASHOKLEY','AXISBANK', 'BAJAJ-AUTO', 'BAJAJFINSV',\ 'BRITANNIA','DRREDDY','GLENMARK','HDFC', 'HDFCBANK',\ 'ICICIBANK','INDUSINDBK','INFY','MANAPPURAM','MARUTI',\ 'MUTHOOTFIN','RELIANCE','SBILIFE', 'SBIN','TATAMOTORS',\ 'TCS','WIPRO','ZEEL'] self.hdr: Dict[str, str] = { 'user-agent': 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 \ (KHTML, like Gecko) Chrome/88.0.4324.96 Safari/537.36', 'accept-language': 'en-US,en;q=0.9' } self.stock_symbs: List[str] = [ 'AARTIIND', 'ACC', 'ADANIENT', 'ADANIPORTS', 'AMARAJABAT', 'AMBUJACEM', 'APOLLOHOSP', 'APOLLOTYRE', 'ASHOKLEY', 'ASIANPAINT', 'AUROPHARMA', 'AXISBANK', 'BAJAJ-AUTO', 'BAJAJFINSV', 'BAJFINANCE', 'BALKRISIND', 'BANDHANBNK', 'BANKBARODA', 'BATAINDIA', 'BEL', 'BERGEPAINT', 'BHARATFORG', 'BHARTIARTL', 'BHEL', 'BIOCON', 'BOSCHLTD', 'BPCL', 'BRITANNIA', 'CADILAHC', 'CANBK', 'CHOLAFIN', 'CIPLA', 'COALINDIA', 'COFORGE', 'COLPAL', 'CONCOR', 'CUMMINSIND', 'DABUR', 'DIVISLAB', 'DLF', 'DRREDDY', 'EICHERMOT', 'ESCORTS', 'EXIDEIND', 'FEDERALBNK', 'GAIL', 'GLENMARK', 'GMRINFRA', 'GODREJCP', 'GODREJPROP', 'GRASIM', 'HAVELLS', 'HCLTECH', 'HDFC', 'HDFCAMC', 'HDFCBANK', 'HDFCLIFE', 'HEROMOTOCO', 'HINDALCO', 'HINDPETRO', 'HINDUNILVR', 'IBULHSGFIN', 'ICICIBANK', 'ICICIGI', 'ICICIPRULI', 'IDEA', 'IDFCFIRSTB', 'IGL', 'INDIGO', 'INDUSINDBK', 'INDUSTOWER', 'INFY', 'IOC', 'ITC', 'JINDALSTEL', 'JSWSTEEL', 'JUBLFOOD', 'KOTAKBANK', 'LALPATHLAB', 'LICHSGFIN', 'LT', 'LUPIN', 'MANAPPURAM', 'MARICO', 'MARUTI', 'MCDOWELL-N', 'MFSL', 'MGL', 'MINDTREE', 'MOTHERSUMI', 'MRF', 'MUTHOOTFIN', 'NATIONALUM', 'NAUKRI', 'NESTLEIND', 'NMDC', 'NTPC', 'ONGC', 'PAGEIND', 'PEL', 'PETRONET', 'PFC', 'PIDILITIND', 'PNB', 'POWERGRID', 'PVR', 'RAMCOCEM', 'RBLBANK', 'RECLTD', 'RELIANCE', 'SAIL', 'SBILIFE', 'SBIN', 'SHREECEM', 'SIEMENS', 'SRF', 'SRTRANSFIN', 'SUNPHARMA', 'SUNTV', 'TATACHEM', 'TATACONSUM', 'TATAMOTORS', 'TATAPOWER', 'TATASTEEL', 'TCS', 'TECHM', 'TITAN', 'TORNTPHARM', 'TORNTPOWER', 'TVSMOTOR', 'UBL', 'ULTRACEMCO', 'UPL', 'VEDL', 'VOLTAS', 'WIPRO' ] #self.stock_symbs: List[str] = ['INFY','UPL', 'VEDL', 'VOLTAS', 'WIPRO', 'ZEEL'] #self.stock_symbs: List[str] = ['INFY','UPL'] self.stock_symbs = self.popular_stocks self.indices: List[str] = ['NIFTY', 'BANKNIFTY'] #self.indices: List[str] = ['BANKNIFTY'] self.SYMBS: List[String] = self.indices self.stock_symb: String = "" self.session: requests.Session = requests.Session() self.make_intial_nse_connection() self.expiry_date: String = "" self.setup_main_window(window) self.resposne: requests.Response = requests.Response() def make_intial_nse_connection(self) -> None: self.session.close() self.session = requests.Session() url_oc = 'https://www.nseindia.com/option-chain' try: self.response = self.session.get(url_oc, headers=self.hdr, timeout=5) except: self.sh_window.after((10 * 1000), self.make_intial_nse_connection) return self.cookies = self.response.cookies if (self.stock_symb != ""): try: self.response = self.session.get(url, headers=self.hdr, timeout=5, cookies=self.cookies) except: #self.make_intial_nse_connection() self.sh_window.after((10 * 1000), self.make_intial_nse_connection) return def refresh_data(self) -> None: self.col_time = datetime.now().strftime("%H:%M:%S") self.prev_time = time.time() if (self.sh_frame): self.sh_frame.destroy() self.sh_frame: Frame = Frame(self.sh_window, height=2) self.sh_frame.rowconfigure(0, weight=1) self.sh_frame.columnconfigure(0, weight=1) self.sh_frame.pack(anchor=N, fill="x", expand=False) if (self.stock_frame): self.stock_frame.destroy() self.stock_frame: Frame = Frame(self.sh_window) self.stock_frame.rowconfigure(3, weight=1) self.stock_frame.columnconfigure(0, weight=1) self.stock_frame.pack(anchor=N, fill="both", expand=True) if (self.check_index_var.get()): self.SYMBS = self.indices self.index_call = True if (self.plot_only): self.get_data_plot_only() else: self.set_sheet(self.sh_frame) self.sheet_formatting() self.draw_plots() if (self.check_stocks_var.get()): self.SYMBS = self.stock_symbs #selected_symbs = [] #for i in range(len(self.stock_check_var)): # if(self.stock_check_var[i].get()): # selected_symbs.append(self.stock_check[i].text) ##self.SYMBS.extend(selected_symbs) self.index_call = False self.set_sheet(self.stock_frame) self.sheet_formatting() def get_data_plot_only(self): self.NB_DF: List[pd.Dataframe] = [] df, dict_dfs = self.append_df_with_OC() for key in dict_dfs.keys(): self.NB_DF.append(pd.concat([df, dict_dfs[key]], axis=1)) def set_sheet(self, my_frame: Frame) -> None: self.NB: Notebook = Notebook(my_frame) self.NB.pack(anchor=N, fill="both", expand=True) self.NBF: List[Frame] = [] self.NBS: List[tksheet.Sheet] = [] self.NB_DF: List[pd.Dataframe] = [] df, dict_dfs = self.append_df_with_OC() for key in dict_dfs.keys(): self.NBF.append(Frame(self.NB)) self.NB_DF.append(pd.concat([df, dict_dfs[key]], axis=1)) self.NB.add(self.NBF[-1], text=key) sh = tksheet.Sheet(self.NBF[-1], column_width=80, align="center", headers=list(self.NB_DF[-1].columns), header_font=("TkDefaultFont", 10, "bold"), empty_horizontal=0, empty_vertical=20, header_height=35) sh.enable_bindings( ("toggle_select", "drag_select", "column_select", "row_select", "column_width_resize", "arrowkeys", "right_click_popup_menu", "rc_select", "copy", "select_all")) sh.pack(anchor=W, fill="both", expand=True) self.NBS.append(sh) def set_expiry_date(self, event) -> None: self.expiry_date = self.date_combo_box.get() def set_ref_intvl(self, event) -> None: self.interval = float(self.ref_intvl_cbox.get()) def sheet_formatting(self) -> None: num_std_cols = 3 #Symb & ATM for i in range(len(self.NBS)): curr_sh = self.NBS[i] num_cols = len(self.NB_DF[i].columns) for col in enumerate(self.NB_DF[i].columns): curr_sh.set_column_data(col[0], values=self.NB_DF[i][col[1]]) if (not self.first_run): for i in range(curr_sh.get_total_rows()): for j in range(num_std_cols, num_cols - 2, 1): diff = float(curr_sh.get_cell_data(i, j)) - float( curr_sh.get_cell_data(i, j + 1)) perc_change = 1. if (float(curr_sh.get_cell_data(i, j - 1)) > 0.0): perc_change = diff * 100 / float( curr_sh.get_cell_data(i, j - 1)) if (diff < 0.): curr_sh.highlight_cells(row=i, column=j, bg=self.red, fg='white') elif diff == 0.0: curr_sh.highlight_cells(row=i, column=j, bg='white', fg='black') else: curr_sh.highlight_cells(row=i, column=j, bg='blue', fg='white') if perc_change > 40.: curr_sh.highlight_cells(row=i, column=j, bg='green', fg='white') curr_sh.set_currently_selected(0, num_cols - 1) curr_sh.refresh() def setup_main_window(self, window) -> None: self.sh_window: Tk = window self.sh_window.title('Option chain analyzer') window_width: int = self.sh_window.winfo_reqwidth() window_height: int = self.sh_window.winfo_reqheight() position_right: int = int(self.sh_window.winfo_screenwidth() / 2 - window_width / 2) position_down: int = int(self.sh_window.winfo_screenheight() / 2 - window_height / 2) #self.sh_window.geometry("1200x600+{}+{}".format(position_right, position_down)) self.sh_window.geometry("1200x600+300+200") #self.sh_window.geometry("+{}+{}".format(position_right, position_down)) self.sh_frame: Frame = Frame(self.sh_window) self.stock_frame: Frame = Frame(self.sh_window) top_frame: Frame = Frame(self.sh_window) top_frame.rowconfigure(0, weight=1) top_frame.columnconfigure(0, weight=1) top_frame.pack(anchor=S, expand=False, side=TOP) row_idx: int = 0 self.index_call = True self.get_expiry_dates() date_var: StringVar = StringVar() date_var.set(" ") lbl_exp_date: Label = Label(top_frame, text='Index Expiry', justify=LEFT, font=("TkDefaultFont", 10, "bold")) #lbl_exp_date.grid(row=row_idx,column=0,sticky=N+S+W) lbl_exp_date.pack(anchor=N, expand=False, side=LEFT) self.date_combo_box = Combobox(top_frame, width=10, textvariable=date_var) self.date_combo_box.pack(anchor=N, expand=False, side=LEFT) #self.date_combo_box.grid(row=row_idx, column=1, sticky=N + S + E + W) self.date_combo_box.bind('<<ComboboxSelected>>', self.set_expiry_date) self.date_combo_box['values'] = tuple(self.expiry_dates) self.date_combo_box.set(self.expiry_dates[0]) self.date_combo_box.configure(state='readonly') row_idx += 1 self.index_call = False self.get_expiry_dates() date_var_stock: StringVar = StringVar() date_var_stock.set(" ") lbl_exp_date_stock: Label = Label(top_frame, text='Stock Expiry', justify=LEFT, font=("TkDefaultFont", 10, "bold")) #lbl_exp_date_stock.grid(row=row_idx,column=0,sticky=N+S+W) lbl_exp_date_stock.pack(anchor=N, expand=False, side=LEFT) self.date_combo_box_stock = Combobox(top_frame, width=10, textvariable=date_var_stock) self.date_combo_box_stock.pack(anchor=N, expand=False, side=LEFT) #self.date_combo_box_stock.grid(row=row_idx, column=1, sticky=N + S + E + W) self.date_combo_box_stock.bind('<<ComboboxSelected>>', self.set_expiry_date) self.date_combo_box_stock['values'] = tuple(self.expiry_dates) self.date_combo_box_stock.set(self.expiry_dates[0]) self.date_combo_box_stock.configure(state='readonly') row_idx += 1 self.check_stocks_var = IntVar() self.check_stocks = Checkbutton(top_frame, text = "Stocks", variable = self.check_stocks_var, \ onvalue = 1, offvalue = 0, width = 10) #self.check_stocks.grid(row=row_idx, column=1, sticky=N + S + E + W) self.check_stocks.pack(anchor=N, expand=False, side=LEFT) self.check_stocks_var.set(0) row_idx += 1 self.check_index_var = IntVar() self.check_index = Checkbutton(top_frame, text = "Index", variable = self.check_index_var, \ onvalue = 1, offvalue = 0, width = 10) #self.check_index.grid(row=row_idx, column=1, sticky=N + S + E + W) self.check_index.pack(anchor=N, expand=False, side=LEFT) self.check_index_var.set(1) row_idx += 1 ref_intvl: Stringvar = StringVar() ref_intvl.set(" ") lbl_refresh_interval: Label = Label(top_frame, text='Interval (min)', justify=LEFT, font=("TkDefaultFont", 10, "bold")) #lbl_refresh_interval.grid(row=row_idx,column=0,sticky=N+S+W) lbl_refresh_interval.pack(anchor=N, expand=False, side=LEFT) self.ref_intvl_cbox: Combobox = Combobox(top_frame, width=10, textvariable=ref_intvl) #self.ref_intvl_cbox.grid(row=row_idx, column=1, sticky=N + S + E + W) self.ref_intvl_cbox.pack(anchor=N, expand=False, side=LEFT) self.ref_intvl_cbox.bind('<<ComboboxSelected>>', self.set_ref_intvl) self.ref_intvl_cbox['values'] = tuple(range(10, 600, 20)) self.ref_intvl_cbox.configure(state='readonly') row_idx += 1 self.start_button: Button = Button(top_frame, text='START', command=self.main_recursive, width=10) #self.start_button.grid(row=row_idx, column=1, sticky=N + S + E + W) self.start_button.pack(anchor=N, expand=True, side=TOP) row_idx += 1 canvas = tk.Canvas(self.sh_window) scroll_y = tk.Scrollbar(self.sh_window, orient="vertical", command=canvas.yview) bot_frame: Frame = Frame(canvas) #bot_frame = ScrollFrame(bot_frame) #bot_frame.rowconfigure(0, weight=1) #bot_frame.columnconfigure(0, weight=1) #bot_frame.grid(row=row_idx,column=0,sticky=N+S+W) #bot_frame = ScrollableFrame(self.sh_window) #bot_frame = ScrollFrame(self.sh_window) #bot_frame.rowconfigure(1, weight=1) #bot_frame.columnconfigure(0, weight=1) #bot_frame.pack(anchor=N, expand=False, side=LEFT) #bot_frame: Listbox = Listbox(self.sh_window) #bot_frame.pack(side=LEFT,fill='both') #vscrollbar = Scrollbar(self.sh_window) #vscrollbar.pack(side = LEFT, fill = 'both') #for i in range(10000): # bot_frame.insert(END,i) self.stock_check_var: List[IntVar] = [] self.stock_check: List[Checkbutton] = [] int_col = 0 tmp_row_idx = row_idx for stk in enumerate(self.stock_symbs): #if(int(stk[0])>30 and int_col==0): # int_col = 1 # row_idx = tmp_row_idx self.stock_check_var.append(IntVar()) cb = Checkbutton(bot_frame, text = stk[1], variable = self.stock_check_var[-1], \ onvalue = 1, offvalue = 0, width =12) cb.pack() if (stk[1] in self.popular_stocks): self.stock_check_var[-1].set(1) else: self.stock_check_var[-1].set(0) self.stock_check.append(cb) row_idx += 1 canvas.create_window(0, 0, anchor='nw', window=bot_frame) canvas.update_idletasks() canvas.configure(scrollregion=canvas.bbox('all'), yscrollcommand=scroll_y.set) canvas.pack(fill='y', expand=False, side=LEFT) scroll_y.pack(fill='y', side=LEFT, expand=False) self.sh_window.mainloop() def get_stock_symbols(self) -> None: url = 'https://www.nseindia.com/api/master-quote' url_oc = 'https://www.nseindia.com/' response = self.session.get(url_oc, headers=self.hdr, timeout=5) ck = response.cookies response = self.session.get(url, headers=self.hdr, timeout=5, cookies=ck) json_data = response.json() self.stock_symbs = list(json_data) def get_option_chain_data(self) -> None: if self.index_call: self.url = 'https://www.nseindia.com/api/option-chain-indices?symbol=' + self.stock_symb else: self.url = 'https://www.nseindia.com/api/option-chain-equities?symbol=' + self.stock_symb try: self.response = self.session.get(self.url, headers=self.hdr, timeout=5, cookies=self.cookies) if self.response.status_code == 401: self.session.close() self.session = requests.Session() request = self.session.get(self.url_oc, headers=self.hdr, timeout=5) self.cookies = dict(request.cookies) self.response = self.session.get(self.url, headers=self.hdr, timeout=5, cookies=self.cookies) print("reset cookies") except Exception as err: print(self.response) print(err, "5") #self.make_intial_nse_connection() self.sh_window.after((10 * 1000), self.main_recursive) return #try: # self.session.close() # self.session = requests.Session() # request = self.session.get(self.url_oc, headers=self.hdr, timeout=5) # self.cookies = dict(request.cookies) # self.response = self.session.get(self.url,headers=self.hdr,timeout=5,cookies=self.cookies) # print("reset cookies") #except Exception as err: # print(request) # print(response) # print(err, "5") # return def get_expiry_dates(self) -> Tuple: if self.index_call: self.stock_symb = 'NIFTY' else: self.stock_symb = 'INFY' self.get_option_chain_data() json_data = self.response.json() self.expiry_dates: List = [] self.expiry_dates = json_data['records']['expiryDates'] def draw_plots(self): symbb = "BANKNIFTY" self.plot_keys = ['PCR OTM', 'LTP'] mrk_type = ['-ro', '--gs'] #self.plot_keys = ['PCR OTM'] idx: Int = -1 plt.clf() maxx = 0.0 minn = 10000.0 for key in enumerate(self.plot_keys): idx = -1 try: idx = self.nb_names.index(key[1]) except: pass if (idx != -1): xx = self.NB_DF[idx].loc[self.NB_DF[idx]['SYMB'] == symbb] y_data = (xx[xx.columns[3:]].values) y_dat = (y_data[0].tolist()) y_dat.reverse() x_data = range(len(y_dat)) if (minn > min(y_dat)): minn = min(y_dat) if (maxx < max(y_dat)): maxx = max(y_dat) if self.index_call: #self.graph_index.set_ydata(y_dat) #self.graph_index.set_xdata(x_data) plt.plot(x_data, y_dat, mrk_type[key[0]], label=key[1], markersize=1) plt.legend() plt.xlim([0, 1.1 * len(y_dat)]) plt.ylim([.9 * minn, 1.1 * maxx]) plt.pause(.0001) plt.show(block=False) strr = datetime.today().strftime('%Y-%m-%d') plt.title(symbb + "--->" + strr) plt.savefig(strr + '.pdf', dpi=300) def append_df_with_OC(self): self.diff_otm: List = [] self.atms: List = [] self.pcr: List = [] self.pcr_otm: List = [] self.pcr_far_otm: List = [] self.live_prices: List[float] = [] self.DIFF_otm: List[float] = [] self.call_sum_otm: List[float] = [] self.put_sum_otm: List[float] = [] self.call_sum_far_otm: List[float] = [] self.put_sum_far_otm: List[float] = [] for stk in enumerate(self.SYMBS): self.stock_symb = stk[1] self.get_option_chain_data() if self.response is not None: try: json_data = self.response.json() except: json_data = {} return #print(stk) #quote = nse.get_quote(stk) #print(quote['data'][0]['lastPrice']) #print(json_data['records']['data']) #try: # self.live_prices.append(float(quote['data'][0]['lastPrice'].replace(',',''))) #except: # self.live_prices.append('null') if self.index_call: match_date = self.date_combo_box.get() else: match_date = self.date_combo_box_stock.get() my_atm: float = 0.0 strike_prices: List[float] = [data['strikePrice'] for data in json_data['records']['data'] \ if (str(data['expiryDate']).lower() == str(match_date).lower())] ce_values: List[dict] = [data['CE'] for data in json_data['records']['data'] \ if "CE" in data and (str(data['expiryDate'].lower()) == str(match_date.lower()))] pe_values: List[dict] = [data['PE'] for data in json_data['records']['data'] \ if "PE" in data and (str(data['expiryDate'].lower()) == str(match_date.lower()))] ce_data: pd.DataFrame = pd.DataFrame(ce_values) pe_data: pd.DataFrame = pd.DataFrame(pe_values) #print(list(ce_data.columns)) curr_price = ce_data['underlyingValue'][0] if (self.first_run): self.first_run_live_price.append(curr_price) try: diff = [abs(x - curr_price) for x in strike_prices] min_pos = diff.index(min(diff)) my_atm = strike_prices[min_pos] self.atms.append(my_atm) except: self.atms.append('null') self.live_prices.append(curr_price / self.first_run_live_price[stk[0]]) ce_data_otm: pd.DataFrame = ce_data[min_pos:min_pos + 4] pe_data_otm: pd.DataFrame = pe_data[min_pos - 2:min_pos + 2] ce_data_far_otm: pd.DataFrame = ce_data[min_pos + 4:min_pos + 8] pe_data_far_otm: pd.DataFrame = pe_data[min_pos - 7:min_pos - 3] call_sum_otm = ce_data_otm['openInterest'].sum() put_sum_otm = pe_data_otm['openInterest'].sum() diff_otm = (ce_data_otm['changeinOpenInterest'].sum() - pe_data_otm['changeinOpenInterest'].sum() ) / ce_data_otm['changeinOpenInterest'].sum() if (call_sum_otm == 0.): call_sum_otm = 0.001 if (put_sum_otm == 0.): put_sum_otm = 0.001 call_sum_far_otm = ce_data_far_otm['openInterest'].sum() put_sum_far_otm = pe_data_far_otm['openInterest'].sum() if (call_sum_far_otm == 0.): call_sum_far_otm = 0.001 if (put_sum_far_otm == 0.): put_sum_far_otm = 0.001 diff_far_otm = call_sum_far_otm - put_sum_far_otm if (ce_data['openInterest'].sum() != 0): pcr_ratio = float(pe_data['openInterest'].sum()) / float( ce_data['openInterest'].sum()) else: pcr_ratio = float(pe_data['openInterest'].sum()) / .001 self.pcr.append(pcr_ratio) self.call_sum_otm.append(call_sum_otm) self.put_sum_otm.append(put_sum_otm) self.call_sum_far_otm.append(call_sum_far_otm) self.put_sum_far_otm.append(put_sum_far_otm) self.pcr_otm.append(put_sum_otm / call_sum_otm) self.pcr_far_otm.append(put_sum_far_otm / call_sum_far_otm) self.diff_otm.append(diff_otm) self.live_price_normalized = list( map(mul, self.pcr_otm, self.live_prices)) #self.live_price_normalized = self.live_prices if (self.index_call): self.df_INDEX['SYMB'] = self.SYMBS self.df_INDEX['ATM'] = self.atms self.df_INDEX['CONST PRICE'] = self.first_run_live_price self.dict_dfs_INDEX['PCR'].insert(0, self.col_time, self.pcr) self.dict_dfs_INDEX['PCR'][self.col_time] = self.dict_dfs_INDEX[ 'PCR'][self.col_time].round(3) self.dict_dfs_INDEX['CE-OTM'].insert(0, self.col_time, self.call_sum_otm) self.dict_dfs_INDEX['PE-OTM'].insert(0, self.col_time, self.put_sum_otm) self.dict_dfs_INDEX['CE-FAR_OTM'].insert(0, self.col_time, self.call_sum_far_otm) self.dict_dfs_INDEX['PE-FAR_OTM'].insert(0, self.col_time, self.put_sum_far_otm) self.dict_dfs_INDEX['LTP'].insert(0, self.col_time, self.live_price_normalized) self.dict_dfs_INDEX['LTP'][self.col_time] = self.dict_dfs_INDEX[ 'LTP'][self.col_time].round(3) self.dict_dfs_INDEX['PCR OTM'].insert(0, self.col_time, self.pcr_otm) self.dict_dfs_INDEX['PCR OTM'][ self.col_time] = self.dict_dfs_INDEX['PCR OTM'][ self.col_time].round(3) self.dict_dfs_INDEX['PCR FAR OTM'].insert(0, self.col_time, self.pcr_far_otm) self.dict_dfs_INDEX['PCR FAR OTM'][ self.col_time] = self.dict_dfs_INDEX['PCR FAR OTM'][ self.col_time].round(3) self.dict_dfs_INDEX['DIFF OTM'].insert(0, self.col_time, self.diff_otm) self.dict_dfs_INDEX['DIFF OTM'][ self.col_time] = self.dict_dfs_INDEX['DIFF OTM'][ self.col_time].round(3) self.dict_dfs_INDEX['DIFF OTM'][ self.col_time] = self.dict_dfs_INDEX['DIFF OTM'][ self.col_time].round(3) return self.df_INDEX, self.dict_dfs_INDEX else: self.df_STOCK['SYMB'] = self.SYMBS self.df_STOCK['ATM'] = self.atms self.df_STOCK['CONST PRICE'] = self.first_run_live_price self.dict_dfs_STOCK['PCR'].insert(0, self.col_time, self.pcr) self.dict_dfs_STOCK['PCR'][self.col_time] = self.dict_dfs_STOCK[ 'PCR'][self.col_time].round(3) self.dict_dfs_STOCK['CE-OTM'].insert(0, self.col_time, self.call_sum_otm) self.dict_dfs_STOCK['PE-OTM'].insert(0, self.col_time, self.put_sum_otm) self.dict_dfs_STOCK['CE-FAR_OTM'].insert(0, self.col_time, self.call_sum_far_otm) self.dict_dfs_STOCK['PE-FAR_OTM'].insert(0, self.col_time, self.put_sum_far_otm) self.dict_dfs_STOCK['LTP'].insert(0, self.col_time, self.live_price_normalized) self.dict_dfs_STOCK['LTP'][self.col_time] = self.dict_dfs_INDEX[ 'LTP'][self.col_time].round(3) self.dict_dfs_STOCK['PCR OTM'].insert(0, self.col_time, self.pcr_otm) self.dict_dfs_STOCK['PCR OTM'][ self.col_time] = self.dict_dfs_STOCK['PCR OTM'][ self.col_time].round(3) self.dict_dfs_STOCK['PCR FAR OTM'].insert(0, self.col_time, self.pcr_far_otm) self.dict_dfs_STOCK['PCR FAR OTM'][ self.col_time] = self.dict_dfs_STOCK['PCR FAR OTM'][ self.col_time].round(3) self.dict_dfs_STOCK['DIFF OTM'].insert(0, self.col_time, self.diff_otm) self.dict_dfs_STOCK['DIFF OTM'][ self.col_time] = self.dict_dfs_STOCK['DIFF OTM'][ self.col_time].round(3) return self.df_STOCK, self.dict_dfs_STOCK
class Login: def __init__(self, master): self.master = master master.title("Login") master.geometry("600x240") master.configure(background='green') # v = [] connection = psycopg2.connect(user="******",password="******", host="127.0.0.1", port="5432",database="RandR") curs = connection.cursor() curs.execute("select * from Listar_Restaurantes") resta = curs.fetchall() i=0 for item in resta : v.append(item[0]) i+1 curs.close() connection.close() # self.labelR = Label(master, text="Restaurante" , height = 2, width = 600) self.labelR.pack() self.labelR.configure( background='green') self.combo = Combobox(master,values=v , width = 600) self.combo.pack() self.combo.bind('<<ComboboxSelected>>', self.combo.get()) self.other_button = Button(master, text="refresh funcionarios", command=lambda: self.refresh(self.combo.get()), height = 1, width = 100) self.other_button.pack() self.comboid = Combobox(master, width = 600) self.comboid.pack() self.comboid.bind('<<ComboboxSelected>>', self.combo.get()) self.labelR = Label(master, text="Password" , height = 2, width = 600) self.labelR.pack() self.labelR.configure( background='green') self.passw = Entry(master, show='*' , width = 600) self.passw.pack() self.btnlogin = Button(master, text="Login", command=lambda: self.Login(self.comboid.get(),self.passw.get()), height = 1, width = 100) self.btnlogin.pack() def refresh(self ,k): connection = psycopg2.connect(user="******",password="******", host="127.0.0.1", port="5432",database="RandR") curs = connection.cursor() a = [] curs.execute("select * from MostrarFuncionarios('"+k+"')") resta = curs.fetchall() i=0 for item in resta : a.append(item[0]) i+1 curs.close() connection.close() self.comboid.configure(value=a) def Login(self ,k, passs): connection = psycopg2.connect(user="******",password="******", host="127.0.0.1", port="5432",database="RandR") curs = connection.cursor() resta = 0 curs.execute("select testa_login ('"+k+"', '"+str(passs)+"')") resta = curs.fetchone() print(str(resta)) if str(resta) == "(1,)" : self.master.destroy() self.master = tk.Tk() self.app = Index_Ger_V.IndexGer(self.master) self.master.mainloop() else : self.labels = Label( text= "Erro no login" , height = 2, width = 600) self.labels.pack() self.labels.configure( background='green') curs.close() connection.close()
class Booking: """Booking class: Booking window. - Choose where you want to watch the movie ["London", "Canary Wharf", "The O2 Arena", "Waterloo"] - You choose which movie to watch - Book seats - See the image of the movie - See movie info "window": it is a Tk() object (tkinter object) that is passed around so we do not need to create it every single time old_window: reference to the tk() object (Login window) username: User's username -_- """ def __init__(self, window, old_window, username): self.username = username self.old_window = old_window self.window = window self.window.title("Booking") self.window.theatre = PhotoImage(file="image/theatre.gif") # Customers Options self.home = Button(self.window, text="Home", font=("Arial", 30), bd=0, bg="#CBFBB5", command=self.goto_home) self.home.grid(row=0, column=0, padx=(15, 10)) self.booking = Button(self.window, text=" Booking ", font=("Arial", 30), bd=0, bg="#CA65F5") self.booking.grid(row=0, column=1, padx=(0, 10)) self.booked = Button(self.window, text=" Booked ", font=("Arial", 30), bd=0, bg="#1F8BF3", command=self.goto_booked) self.booked.grid(row=0, column=2, padx=(0, 10)) self.user = Button(self.window, text=" User ", font=("Comic Sans", 30), bd=0, bg="#BDC3C7", command=self.goto_user) self.user.grid(row=0, column=3, padx=(0, 10)) self.sign_out = Button(self.window, text=" Sign Out ", font=("Comic Sans", 30), bd=0, bg="#FF916E", command=self.goto_sign_out) self.sign_out.grid(row=0, column=4, padx=(0, 10)) # Choose the location global cinema_location self.choose_location_display = LabelFrame( self.window, text="Where will you watch it?", bg="#414141", fg="white", width=100) self.choose_location_display.grid(row=1, column=0, pady=(20, 4)) self.location_option = Combobox(self.choose_location_display, state="readonly") self.location_option["values"] = cinema_location self.location_option.current(0) self.location_option.grid() self.enter_location_btn = Button(self.window, text="Enter Location", command=self.enter_location, bd=2, bg="#CAE4F8") self.enter_location_btn.grid(row=3, column=0, pady=7) # Choose Movie self.choose_movie_display = LabelFrame(self.window, text="Choose movie:", bg="#414141", fg="white", width=100) self.movie_option = Combobox(self.choose_movie_display, state="readonly") self.enter_movie_btn = Button(self.window, text="Enter Movie", command=self.enter_name, bd=2, bg="#CAE4F8") # Choose Date self.choose_date_display = LabelFrame(self.window, text="Choose date:", bg="#414141", fg="white") self.date_option = Combobox(self.choose_date_display, state="readonly") self.enter_date_btn = Button(self.window, text="Enter Date", command=self.enter_date, bg="#CAE4F8") # Choose Time self.choose_time_display = LabelFrame(self.window, text="Choose time:", bg="#414141", fg="white") self.time_option = Combobox(self.choose_time_display, state="readonly") self.enter_time_btn = Button(self.window, text="Enter Time", command=self.enter_time, bg="#CAE4F8") # Book Seats self.book_seats_btn = Button(self.window, text="Book Seats", font=("Arial", 15), command=self.book_seats, width=10, height=3, bg="#C9A594", fg="#3F3F3F") # No Movie available display self.no_movie = Label( self.window, text="Sorry, there are no movies playing.\nPlease come back later.", font=("Arial", 30)) self.movie_pic = Label(self.window, bg="silver", bd=10, image=self.window.theatre) self.movie_pic.place(x=105, y=220) self.movie_info_btn = Button(self.window, text="Movie Info", font=("Arial", 15), command=self.movie_info) # All the widget I created, I store it here. So i can easily destroy them later. self.widgets = [ self.home, self.booked, self.booking, self.user, self.sign_out, self.choose_movie_display, self.movie_option, self.enter_movie_btn, self.movie_pic, self.choose_date_display, self.date_option, self.enter_date_btn, self.choose_time_display, self.time_option, self.enter_time_btn, self.book_seats_btn, self.movie_info_btn, self.no_movie, self.location_option, self.choose_location_display, self.enter_location_btn ] def movie_info(self): self.window.withdraw() MovieInfo(movie_name=self.movie_option.get(), old_window=self.window, location=self.location_option.get()) def destroy_all(self): """ destroy_all() Destroys all the widget (Clears the window, so I can use the same window for adding new widgets) """ [widget.destroy() for widget in self.widgets] def goto_home(self): """Takes you to the Home window""" self.destroy_all() self.window.Home(window=self.window, old_window=self.old_window, username=self.username) def goto_booked(self): """Takes you to the Booked window""" self.destroy_all() self.window.Booked(window=self.window, old_window=self.old_window, username=self.username) def goto_user(self): """Takes you to the user window""" self.destroy_all() self.window.User(window=self.window, old_window=self.old_window, username=self.username, customer=True) def goto_sign_out(self): """Signs out the user and takes the user back to the Login menu. It also logs the date and the time when the user signs out""" logging.basicConfig(level=logging.INFO, filename="logging.log") logging.info( f"Username: {self.username} Sign-out {datetime.datetime.now()}") self.window.destroy() self.old_window.deiconify() def enter_location(self): """enter_location() obtains the location where the user want to watch the movie at. Get the path to the database for the cinema branch. Then gives the user the list of movie available in that cinema at that location Change the enter location button to change location Disable the location option""" self.location_option.configure(state="disabled") self.enter_location_btn.configure(text="Change Location", command=self.change_location) global cinemaDB_path location = self.location_option.get() cinemaDB_path = os.path.abspath( os.path.join(os.path.dirname(__file__), "..", f"{location}.db")) self.movie_name_dict = get_movie_names() # Obtain the movie name # If no names if len(self.movie_name_dict) == 0: messagebox.showwarning( "Sorry", "Sorry, there are not any movie playing in this cinema hall.") # Checks if there is any movie playing if self.movie_name_dict: self.choose_movie_display.grid(row=1, column=1, pady=(20, 4)) self.movie_option["values"] = [ name for name in self.movie_name_dict.keys() ] self.movie_option.current(0) self.movie_option.grid() self.movie_option.bind( "<<ComboboxSelected>>", lambda e: self.movie_pic.configure( image=self.window.booking_img[self.movie_option.get()])) self.enter_movie_btn.grid(row=3, column=1, pady=7) # Getting the images of the movie self.window.booking_img = {} for name in self.movie_name_dict.keys(): if os.path.exists(f"./image/Booking/{name}.gif"): img = PhotoImage(file=f"./image/Booking/{name}.gif") else: img = PhotoImage(file="./image/Error_Booking.gif") self.window.booking_img[name] = img self.movie_pic.configure( image=self.window.booking_img[self.movie_option.get()]) self.movie_info_btn.place(x=713, y=230) else: # If there is no movie in the database self.no_movie.place(x=200, y=250) def enter_name(self): """enter_name() select the movie and give a list of available time. Change the enter movie button to change movie Disable the movie option list """ self.movie_option.configure(state="disabled") self.enter_movie_btn.configure(text="Change Movie", command=self.change_movie) date = get_dates( movie_id=self.movie_name_dict[self.movie_option.get()]) if date: date.sort() self.choose_date_display.grid(row=1, column=2, pady=(20, 4)) self.date_option["values"] = date self.date_option.current(0) self.date_option.grid() self.enter_date_btn.grid(row=3, column=2, pady=7) def enter_date(self): """enter_data() select the date and give a list of available time. Change the enter date button to change date Disable the date option list""" self.date_option.configure(state="disabled") self.enter_date_btn.configure(text="Change Date", command=self.change_date) self.choose_time_display.grid(row=1, column=2, pady=(20, 4), columnspan=3) time = get_times( movie_id=self.movie_name_dict[self.movie_option.get()], date=self.date_option.get()) time.sort() self.time_option["values"] = time self.time_option.current(0) self.time_option.grid() self.enter_time_btn.grid(row=3, column=3, pady=7) def enter_time(self): """enter_date() selects the time, then book seats button appear Change the enter time to change time Disable the time option list""" self.time_option.configure(state="disable") self.enter_time_btn.configure(text="Change Time", command=self.change_time) self.book_seats_btn.grid(row=1, column=4, rowspan=3) def change_location(self): """change_location() will enable the the location option Change the change location to enter location Hide the choose movie, date and time option and book seats button""" self.location_option.configure(state="readonly") self.enter_location_btn.configure(text="Enter Location", command=self.enter_location) self.choose_movie_display.grid_remove() self.movie_option.grid_remove() self.enter_movie_btn.grid_remove() self.movie_info_btn.place_forget() self.movie_pic.configure(image=self.window.theatre) self.change_movie() def change_movie(self): """change_movie() will enable the the movie option Change the change movie to enter movie Hide the choose date and time option and book seats button""" self.movie_option.configure(state="readonly") self.enter_movie_btn.configure(text="Enter Movie", command=self.enter_name) self.choose_date_display.grid_remove() self.date_option.grid_remove() self.enter_date_btn.grid_remove() self.change_date() def change_date(self): """change_date() will enable the the date option Change the change date to enter date Hide the choose time option and book seats button""" self.enter_date_btn.configure(text="Enter Date", command=self.enter_date) self.choose_time_display.grid_remove() self.time_option.grid_remove() self.enter_time_btn.grid_remove() self.date_option.configure(state="readonly") self.enter_date_btn.configure(state="normal") self.change_time() def change_time(self): """change_time() will enable the the time option Change the change time to enter time Hide the seats button""" self.enter_time_btn.configure(text="Enter Time", command=self.enter_time) self.time_option.configure(state="readonly") self.book_seats_btn.grid_remove() def book_seats(self): """Takes the user to booking seats window""" global cinemaDB_path db = sqlite3.connect(cinemaDB_path) cursor = db.cursor() cursor.execute( f"""SELECT s.scheduleID FROM seating_plan sp, schedule s WHERE s.scheduleID = sp.scheduleID AND date= ? AND time= ?""", (self.date_option.get(), self.time_option.get())) scheduleID = cursor.fetchone()[0] db.close() self.window.withdraw() location = self.location_option.get() ChooseSeats(old_window=self.window, username=self.username, scheduleID=scheduleID, location=location)