def __init__(self, parent, **optional_arguments): tkinter.LabelFrame.__init__(self, parent, text=optional_arguments['text']) self.colors = None # setup default parameters and then process optional arguments self.field_count = default_field_count self.process_optional_arguments(optional_arguments) # setup the table showing initial balance, current balance, and expenditure totals self.totals_table: TableWidget = None self.load_total_amounts() # sets up a separator between the two tables separator = Separator(self) separator.grid(row=0, column=1, sticky="NS") # setup the table showing spending by category self.category_table: TableWidget = None self.load_spending_by_category() # setup the pie chart self.pie_chart = PieChart(self) self.pie_chart.grid(row=1, columnspan=3) self.load_table_data(None, None, None)
def create_widgets(self): ''' Creates widgets of this object. ''' yScrollbar = Scrollbar(self, orient=VERTICAL) yScrollbar.grid(row=2, column=3, sticky=N+S) canvas = StyledCanvas(self, height=HEIGHT_WITHOUT_CHECKBOXES, yscrollcommand=yScrollbar.set) self.canvas = canvas canvas.grid(row=2, column=0, columnspan=3, sticky=N+E+W) self._config_columns(self) canvas.columnconfigure(0, weight=1) if self.add_headers: non_discr_lbl = Label(self, text='Non-\ndiscretionary') non_discr_lbl.grid(row=0, column=1, padx=3, pady=1) weakly_disp_lbl = Label(self, text='Weakly\ndisposable') weakly_disp_lbl.grid(row=0, column=2, padx=3, pady=1) sep = Separator(self) sep.grid(row=1, column=0, columnspan=3, sticky=E+W, pady=10, padx=3) self.frame_with_boxes = Frame(canvas) self._config_columns(self.frame_with_boxes) self.frame_with_boxes.grid(sticky=N+S+W+E, pady=15, padx=3) canvas.create_window(0, 0, window=self.frame_with_boxes, anchor=N+W) canvas.update_idletasks() canvas['scrollregion'] = (0, 0, 0, HEIGHT_WITHOUT_CHECKBOXES) yScrollbar['command'] = canvas.yview MouseWheel(self).add_scrolling(canvas, yscrollbar=yScrollbar)
def __init__(self, parent, theme_name: str): # initializes this frame and its sub frames tkinter.Frame.__init__(self, parent) self.model: FinanceManagerModel = None self.color_manager: ColorManager = None self.fd: FileDisplay = FileDisplay(self) self.fd.set_listener(self) self.fd.grid(row=0, column=0, sticky=tkinter.NS) separator1 = Separator(self, orient="vertical") separator1.grid(row=0, column=1, sticky='ns') self.tv: TableVisualizer = TableVisualizer(self) self.tv.add_listener(self) self.tv.grid(row=0, column=2, sticky=tkinter.NS) separator2 = Separator(self, orient="vertical") separator2.grid(row=0, column=3, sticky='ns') self.dv: DataVisualizer = DataVisualizer(self, text="Data Visualizer") self.dv.grid(row=0, column=4, sticky=tkinter.NS) if theme_name == "dark": self.set_color_manager( ColorManager(ColorTheme.get_dark_theme_dict())) else: self.set_color_manager( ColorManager(ColorTheme.get_default_theme_dict()))
class TkFrameInfo(Frame): def __init__(self, w, text: str, lbl_width: int, info_width: int, info_bg: str, *args, **kwargs): super().__init__(w, *args, **kwargs) self.lbl = Label(self, width=lbl_width, text=text) self.lbl.grid(row=0, column=0) self.info = Entry(self, width=info_width, readonlybackground=info_bg, borderwidth=0, justify="left", state="readonly") self.info.grid(row=0, column=1) self.sep = Separator(self, orient="horizontal") self.sep.grid(row=1, column=0, columnspan=2, sticky="new") def insert(self, text): self.info["state"] = "normal" self.info.delete(0, "end") self.info.insert(0, text) self.info["state"] = "readonly" def get(self) -> str: return self.info.get()
def __init__(self, parent: Tk, main): super(CommandSettingsWindow, self).__init__(parent) self._root = parent self._main = main w = 300 h = 250 # get screen width and height ws = self._root.winfo_screenwidth() # width of the screen hs = self._root.winfo_screenheight() # height of the screen # calculate x and y coordinates for the Tk window x = (ws / 2) - (w / 2) y = (hs / 2) - (h / 2) self._root.title('Command settings') # root.geometry('{}x{}'.format(300, 250)) self._root.geometry('%dx%d+%d+%d' % (2.5 * w, 2.5 * h, x, y)) self._root.resizable(height=False, width=False) frame1 = Frame(self._root) frame1.pack(fill="both", expand=True) label_buttons = Label(frame1, text='Button names', font=fontStyle_medium) label_commands = Label(frame1, text='Transmitted data', font=fontStyle_medium) label_buttons.grid(row=0, column=0, padx=10) label_commands.grid(row=0, column=2, padx=10) button_list = [] for i in range(len(button_text)): button_list.append( Label(frame1, text=button_text[i], borderwidth=borderwidth, relief='sunken', width=15).grid(row=i + 2, column=0, pady=5, padx=15)) command_list = [] for i in range(len(dict_commands)): text = ''.join( format(x, '02X') for x in list(dict_commands.values())[i]) command_list.append( Label(frame1, text='0x' + text).grid(row=i + 2, column=2, padx=10)) sep1 = Separator(frame1, orient='vertical') sep1.grid(row=0, column=1, rowspan=9, sticky='ns', pady=(5, 0)) sep2 = Separator(frame1, orient='horizontal') sep2.grid(row=1, column=0, columnspan=3, sticky='we', padx=5)
def create_message(root): root.cryptLabel = Label(root, text="AES Cryptography", bg=bgcolor) root.messageLabel = Label(root, text="Input Message ", bg=bgcolor) root.encryptLabel = Label(root, text="Encrypted message ", bg=bgcolor) root.decryptLabel = Label(root, text="Decrypted message ", bg=bgcolor) root.messageEntry = Entry(root) root.messageEntry.insert(END, 'Enter your message here') root.encryptEntry = Entry(root) root.encryptEntry.insert(END, '') root.decryptEntry = Entry(root) root.decryptEntry.insert(END, '') encryptButton = Button(root, text="Encrypt", bg=bgcolor, command=handle_encrypt) decryptButton = Button(root, text="Decrypt", bg=bgcolor, command=handle_decrypt) emptyLabel1 = Label(root, text="", bg=bgcolor) root.finalLabel = Label(root, text="", bg=bgcolor) horSeparator = Separator(root, orient="horizontal") root.cryptLabel.grid(row=20, columnspan=5) root.messageLabel.grid(row=21, column=0, sticky="W") root.encryptLabel.grid(row=22, column=0, sticky="W") root.decryptLabel.grid(row=23, column=0, sticky="W") root.messageEntry.config(highlightbackground=bgcolor) root.encryptEntry.config(highlightbackground=bgcolor, state='readonly') root.decryptEntry.config(highlightbackground=bgcolor, state='readonly') root.messageEntry.grid(row=21, column=1, columnspan=3, sticky="NEWS") root.encryptEntry.grid(row=22, column=1, columnspan=3, sticky="NEWS") root.decryptEntry.grid(row=23, column=1, columnspan=3, sticky="NEWS") encryptButton.config(highlightbackground=bgcolor) decryptButton.config(highlightbackground=bgcolor) encryptButton.grid(row=21, column=4) decryptButton.grid(row=22, column=4) emptyLabel1.grid(row=24, columnspan=5) root.finalLabel.grid(row=25, columnspan=5) horSeparator.grid(row=26, columnspan=5, sticky="EW")
def __create_header(self, parent): sep = Separator(parent, orient=HORIZONTAL) sep.grid(row=1, column=0, columnspan=6, sticky=W + E) label = Label(parent, text="Seleccione un tipo de analisis", width=20).grid(row=2, column=0, columnspan=2, pady=10) self.elements.append(label) for i in range(0, len(button_headers)): __full_option = partial(self.__full_option, i) button = Button(parent, text=button_headers[i], command=__full_option, width=10, activebackground='red').grid(row=2, column=i + 2, padx=5, pady=5) self.elements.append(button)
def create_param(root): root.paramLabel = Label(root, text="Machine Parameters", bg=bgcolor) root.kLabel = Label(root, text="K ", bg=bgcolor) root.nLabel = Label(root, text="N ", bg=bgcolor) root.lLabel = Label(root, text="L ", bg=bgcolor) root.delayLabel = Label(root, text="Time Delay(sec) ", bg=bgcolor) root.kEntry = Entry(root) root.kEntry.insert(END, '3') root.nEntry = Entry(root) root.nEntry.insert(END, '10') root.lEntry = Entry(root) root.lEntry.insert(END, '4') root.delayEntry = Entry(root) root.delayEntry.insert(END, '0') syncButton = Button(root, text="Synchronize weights", bg=bgcolor, command=handle_sync) emptyLabel2 = Label(root, text="", bg=bgcolor) horSeparator = Separator(root, orient="horizontal") root.paramLabel.grid(row=0, columnspan=5) root.kLabel.grid(row=1, column=0, sticky="W") root.nLabel.grid(row=1, column=2, sticky="W") root.lLabel.grid(row=2, column=0, sticky="W") root.delayLabel.grid(row=2, column=2, sticky="W") root.kEntry.config(highlightbackground=bgcolor) root.nEntry.config(highlightbackground=bgcolor) root.lEntry.config(highlightbackground=bgcolor) root.delayEntry.config(highlightbackground=bgcolor) root.kEntry.grid(row=1, column=1) root.nEntry.grid(row=1, column=3) root.lEntry.grid(row=2, column=1) root.delayEntry.grid(row=2, column=3) syncButton.config(highlightbackground=bgcolor) syncButton.grid(row=1, column=4, rowspan=2) emptyLabel2.grid(row=3, columnspan=5) horSeparator.grid(row=4, columnspan=5, sticky="EW")
def insertData(self) -> None: global rndto maxNum = int() new: list[Path] = list() nfols: dict[str, tuple[Path, str]] = dict() folders = [f for f in self.cwd.iterdir() if f.is_dir()] for fol in folders: m = re_match(r'(\d+)[\W]*(.+)$', fol.name) if m: maxNum = max(maxNum, int(m.group(1))) nfols[m.group(1)] = (fol, m.group(2)) else: new.append(fol) folct = len(folders) self.maxRow = max(maxNum, folct) rndto = len(str(self.maxRow)) self.lblRow = (self.maxRow + 1) self.lastRow = (self.lblRow + folct) newLbl = Label(master=self.scrFrm, text="Non-enumerated Folders:") newLbl.grid(column=0, row=self.lblRow, pady=((PAD * 5), (PAD // 2)), sticky='nsew') nLbl = Label(master=self.scrFrm, text="None") nLbl.grid(column=0, row=self.lastRow, sticky='nsew') for n in range(folct): s = Separator(master=self.scrFrm, orient='horizontal') s.grid(column=0, row=(n + 1), sticky='ew', pady=3) for num, (fol, name) in nfols.items(): self.fillInfo(curRow=int(num), path=fol, name=name) for i, fol in enumerate(new): num = (self.lastRow - i) self.fillInfo(curRow=num, path=fol)
def __init__(self, master: Tk) -> None: """ Creates the editor window. :param master: the parent widget """ super().__init__(master) self._document = FileDocument(master) self._document.text = _DEFAULT_DOCUMENT self.master.title(self._document.name) self.master.configure(menu=self._create_menu()) self.grid_rowconfigure(0, weight=1) self.grid_columnconfigure(0, weight=1) self.grid_columnconfigure(2, weight=1) self._editor = _Editor(self, self._document, width=500, height=500) self._editor.text = _DEFAULT_DOCUMENT self._editor.grid(row=0, column=0, sticky=NSEW) self._editor.focus_set() def update_title() -> None: self.master.title(self._document.name + (" — Edited" if self._document.modified else "")) for name in "<<Opened>>", "<<Modified>>", "<<SavedAs>>": self._document.bind(name, lambda event: update_title(), add=True) sep = Separator(self, orient=VERTICAL) sep.grid(row=0, column=1, sticky=NS) preview = _Preview(self, self._document, width=500, height=500) preview.grid(row=0, column=2, sticky=NSEW) def on_delete() -> None: if self._can_reset_document(): self.master.destroy() self.pack(expand=YES, fill=BOTH) self.master.wm_protocol("WM_DELETE_WINDOW", on_delete) self.master.createcommand( "tkAboutDialog", lambda: self.master.call("::tk::mac::standardAboutPanel")) self.master.createcommand("::tk::mac::Quit", on_delete)
def __init__(self, fr, widg, widg1=None): ''' Used to enable state change Creates radio buttons showing states Creates check button with "Enabled", useful for testing check and radio buttons Args: fr: frame reference in calling program widg: widget reference widg1: optional widget ''' self.fr = fr self.widg = widg self.widg1 = widg1 # Create radio buttons which will display widget states # except alternate and background states = [ 'active', 'disabled', 'focus', 'invalid', 'pressed', 'readonly', 'selected' ] self.rb = [] self.state_val = StringVar() for iy, state in enumerate(states): st_rb = Radiobutton(fr, value=state, text=state, variable=self.state_val, command=self.change_state) st_rb.grid(column=0, row=iy + 2, padx=5, pady=5, sticky='nw') self.rb.append(st_rb) st_rb.state(['disabled']) self.enabled = IntVar() self.cbOpt = Checkbutton(fr, text='Enabled', variable=self.enabled, command=self.change_state) self.cbOpt.grid(column=0, row=0) sep = Separator(orient='h') sep.grid(column=0, row=1, sticky='ew')
def create_result(root): root.resLabel = Label(root, text="Synchronization Results", bg=bgcolor) root.totalIterLabel = Label(root, text="Total iterations ", bg=bgcolor) root.maxIterLabel = Label(root, text="Max iterations ", bg=bgcolor) root.keyLengthLabel = Label(root, text="Key length ", bg=bgcolor) root.bytesLabel = Label(root, text="(bytes)", bg=bgcolor) root.keyLabel = Label(root, text="Key ", bg=bgcolor) root.totalIterEntry = Entry(root) root.totalIterEntry.insert(END, '') root.maxIterEntry = Entry(root) root.maxIterEntry.insert(END, '') root.keyLengthEntry = Entry(root) root.keyLengthEntry.insert(END, '') root.keyEntry = Entry(root) root.keyEntry.insert(END, '') emptyLabel1 = Label(root, text="", bg=bgcolor) horSeparator = Separator(root, orient="horizontal") root.resLabel.grid(row=14, columnspan=5) root.totalIterLabel.grid(row=15, column=0, sticky="W") root.maxIterLabel.grid(row=15, column=2, sticky="W") root.keyLengthLabel.grid(row=16, column=0, sticky="W") root.bytesLabel.grid(row=16, column=2, sticky="W") root.keyLabel.grid(row=17, column=0, sticky="W") root.totalIterEntry.config(highlightbackground=bgcolor, state='readonly') root.maxIterEntry.config(highlightbackground=bgcolor, state='readonly') root.keyLengthEntry.config(highlightbackground=bgcolor, state='readonly') root.keyEntry.config(highlightbackground=bgcolor, state='readonly') root.totalIterEntry.grid(row=15, column=1) root.maxIterEntry.grid(row=15, column=3) root.keyLengthEntry.grid(row=16, column=1) root.keyEntry.grid(row=17, column=1, columnspan=3, sticky="NEWS") emptyLabel1.grid(row=18, columnspan=5) horSeparator.grid(row=19, columnspan=5, sticky="EW")
def __init__(self): super().__init__() # __________ ROOT WINDOW MENU BAR __________ self.geometry("500x600") self.title("Magic Session Mixer") # set icon: dirname = os.path.dirname(__file__) icon_path = os.path.join(dirname, 'magic_session_mixer.ico') self.iconbitmap(icon_path) # ________________ STYLING ________________ s = Style() s.configure("Active.TFrame", background='#007AD9') # s.configure("Inactive.TFrame", background='#A2A2A2') s.configure("Inactive.TFrame", background='#AF3118') s.configure("Unmuted.TButton", foreground='#007AD9') # s.configure("Muted.TButton", foreground='#C33C54') s.configure("Muted.TButton", foreground='#AF3118') # _________________ HEADER _________________ header = Frame(self) title = Label(header, text="Magic Session Mixer", font=("Calibri", 20, "bold")) # ________________ SEPARATE ________________ separate = Separator(header, orient=HORIZONTAL) # ____________ ARRANGE ELEMENTS ____________ header.columnconfigure(0, weight=1) title.grid(row=0, column=0, pady=10, sticky="W") separate.grid(row=1, column=0, sticky="EW", pady=10) # _______________ PACK FRAME _______________ header.pack(fill='x', padx=15) # ____________ BUILD WITH PYCAW ____________ turbo_anonym = Label(self, text="created by TurboAnonym with pycaw", font=("Consolas", 8, "italic")) turbo_anonym.pack(side=BOTTOM, fill="x", pady=6, padx=6)
def _initconsole(self): separator = Separator(self, orient=HORIZONTAL) separator.grid(row=1, columnspan=3, sticky=W + E, padx=5, pady=5) self.console = Text(self) self.console.grid(row=2, columnspan=3, sticky=W + E, padx=5, pady=5) vsl = Scrollbar(self, orient=VERTICAL) vsl.grid(row=2, column=3, sticky=N + S + W) hsl = Scrollbar(self, orient=HORIZONTAL) hsl.grid(row=3, column=0, columnspan=3, sticky=W + E + N) hsl.config(command=self.console.xview) vsl.config(command=self.console.yview) resbtn = Button(self, text="Search", width=7, comman=self._showsearchresult) resbtn.grid(row=4, column=2, padx=5, pady=5, sticky=E)
def create_widgets(self): ''' Creates widgets of this object. ''' yScrollbar = Scrollbar(self, orient=VERTICAL) yScrollbar.grid(row=2, column=3, sticky=N + S) canvas = StyledCanvas(self, height=HEIGHT_WITHOUT_CHECKBOXES, yscrollcommand=yScrollbar.set) self.canvas = canvas canvas.grid(row=2, column=0, columnspan=3, sticky=N + E + W) self._config_columns(self) canvas.columnconfigure(0, weight=1) if self.add_headers: non_discr_lbl = Label(self, text='Non-\ndiscretionary') non_discr_lbl.grid(row=0, column=1, padx=3, pady=1) weakly_disp_lbl = Label(self, text='Weakly\ndisposable') weakly_disp_lbl.grid(row=0, column=2, padx=3, pady=1) sep = Separator(self) sep.grid(row=1, column=0, columnspan=3, sticky=E + W, pady=10, padx=3) self.frame_with_boxes = Frame(canvas) self._config_columns(self.frame_with_boxes) self.frame_with_boxes.grid(sticky=N + S + W + E, pady=15, padx=3) canvas.create_window(0, 0, window=self.frame_with_boxes, anchor=N + W) canvas.update_idletasks() canvas['scrollregion'] = (0, 0, 0, HEIGHT_WITHOUT_CHECKBOXES) yScrollbar['command'] = canvas.yview MouseWheel(self).add_scrolling(canvas, yscrollbar=yScrollbar)
def __set_up_separators(self): vertical_sep1 = Separator(self.__main_frame, orient="vertical") vertical_sep2 = Separator(self.__main_frame, orient="vertical") vertical_sep1.grid(column=1, row=0, sticky="ns", rowspan=5) vertical_sep2.grid(column=3, row=0, sticky="ns", rowspan=5) horizontal_sep = Separator(self.__main_frame, orient="horizontal") horizontal_sep.grid(column=0, row=0, sticky="ew", columnspan=5) self.__main_frame.grid_rowconfigure( 0, minsize=4, pad=0) # create some space from the top sty = Style(self.__main_frame) sty.configure("TSeparator", background="DeepSkyBlue2")
def __init__(self,parent): LabelFrame.__init__(self,parent,text="Model",borderwidth=5) self.selection = tkinter.IntVar() self.exponential = Radiobutton(self,text="Exponential model",variable=self.selection,value=Model.EXP.value,command=self.changeSelection) self.powerlaw = Radiobutton(self,text="Power law model",variable=self.selection,value=Model.POW.value,command=self.changeSelection) self.weibull = Radiobutton(self,text="Weibull model",variable=self.selection,value=Model.WEI.value,command=self.changeSelection) self.exponential.grid(row=0,column=0,sticky="W",padx=10,pady=(self.topPadding,5)) self.powerlaw.grid(row=1,column=0,sticky="W",padx=10,pady=5) self.weibull.grid(row=2,column=0,sticky="W",padx=10,pady=(5,0)) seperator = Separator(self, orient=tkinter.VERTICAL) seperator.grid(row=0, column=1, rowspan=3, sticky="NS", padx=(20,10), pady=(self.topPadding,0)) ## Exponential setup self.expNumberOfSegments_L = Label(self,text="Number of segments: ") self.expNumberOfSegments_E = Entry(self,width=5, justify="right") self.expNumberOfSegments_E.insert(0, settings.EXP_DEFAULT_NUMBER_OF_SEGMENTS) self.expWidgets = [self.expNumberOfSegments_L,self.expNumberOfSegments_E] ## Power law setup self.powProximalLimit_L = Label(self,text="Proximal limit of integration: ") self.powProximalLimit_E = Entry(self,width=5, justify="right") self.powDistalLimit_L = Label(self,text="Distal limit of integration: ") self.powDistalLimit_E = Entry(self,width=5, justify="right") self.powProximalLimit_E.insert(0, settings.POW_DEFAULT_PROXIMAL_LIMIT) self.powDistalLimit_E.insert(0, settings.POW_DEFAULT_DISTAL_LIMIT) self.powWidgets = [self.powProximalLimit_L,self.powProximalLimit_E, self.powDistalLimit_L,self.powDistalLimit_E] ## Weibull setup self.weiNumberOfRuns_L = Label(self,text="Number of runs: ") self.weiNumberOfRuns_E = Entry(self,width=5, justify="right") self.weiIterationsPerRun_L = Label(self,text="Iterations per run: ") self.weiIterationsPerRun_E = Entry(self,width=5, justify="right") self.weiEstimatedTime_L = Label(self,text="Estimated time (s): ") self.weiEstimatedTime_E = CustomEntry(self,width=5, justify="right") self.weiEstimatedTime_E.setUserEditable(False) self.weiLambdaLowerBoundL = Label(self,text="\u03BB lower bound:") self.weiLambdaUpperBoundL = Label(self,text="\u03BB upper bound:") self.weiLambdaLowerBoundE = Entry(self,width=5, justify="right") self.weiLambdaUpperBoundE = Entry(self,width=5, justify="right") self.weiKLowerBoundL = Label(self,text="k lower bound:") self.weiKUpperBoundL = Label(self,text="k upper bound:") self.weiKLowerBoundE = Entry(self,width=5, justify="right") self.weiKUpperBoundE = Entry(self,width=5, justify="right") self.weiNumberOfRuns_E.insert(0, settings.WEI_DEFAULT_NUMBER_OF_RUNS) self.weiIterationsPerRun_E.insert(0, settings.WEI_DEFAULT_ITERATIONS_PER_RUN) self.weiLambdaLowerBoundE.insert(0, settings.WEI_DEFAULT_LAMBDA_LOWER_BOUND) self.weiLambdaUpperBoundE.insert(0, settings.WEI_DEFAULT_LAMBDA_UPPER_BOUND) self.weiKLowerBoundE.insert(0, settings.WEI_DEFAULT_K_LOWER_BOUND) self.weiKUpperBoundE.insert(0, settings.WEI_DEFAULT_K_UPPER_BOUND) self.weiWidgets = [self.weiNumberOfRuns_L,self.weiNumberOfRuns_E, self.weiIterationsPerRun_L,self.weiIterationsPerRun_E, self.weiEstimatedTime_L,self.weiEstimatedTime_E, self.weiLambdaLowerBoundL,self.weiLambdaUpperBoundL,self.weiLambdaLowerBoundE,self.weiLambdaUpperBoundE, self.weiKLowerBoundL,self.weiKUpperBoundL,self.weiKLowerBoundE,self.weiKUpperBoundE] ## General self.currentWidgets = [] self.selection.set(Model.EXP.value) self.changeSelection()
class LocationView(BaseView): ######## # Initializes and places all GUI elements. def _create_widgets(self): # left frame self._leftFrame = Frame(self) self._imgLabel = Label(self._leftFrame) self._storeLabel = Label(self._leftFrame, text="Stores", font=BaseView.NORMAL_FONT) self._storeVar = StringVar(self) self._storeCombo = Combobox(self._leftFrame, state="readonly", textvariable=self._storeVar) self._storePreview = SimpleStoreView(self._leftFrame) self._leftSep1 = Separator(self._leftFrame, orient="horizontal") self._inhabitantLabel = Label(self._leftFrame, text="Inhabitants:", font=BaseView.NORMAL_FONT) self._inhabitantVar = StringVar(self) self._inhabitantCombo = Combobox(self._leftFrame, state="readonly", textvariable=self._inhabitantVar) self._inhabitantPreview = SimpleCreatureView(self._leftFrame) self._inhabitantNotesFrame = Frame(self._leftFrame) self._inhabitantNotesLabel = Label(self._leftFrame, text="Notes:", font=BaseView.NORMAL_FONT) self._inhabitantNotes = Text(self._inhabitantNotesFrame, width=30, height=2, state=DISABLED, wrap=WORD, font=BaseView.NORMAL_FONT) self._inhabitantNotesScroll = Scrollbar( self._inhabitantNotesFrame, command=self._inhabitantNotes.yview) self._inhabitantNotes.config( yscrollcommand=self._inhabitantNotesScroll.set) # right frame self._rightFrame = Frame(self) self._nameLabel = Label(self._rightFrame, text="Name", font=BaseView.LARGE_FONT) self._descLabel = Label(self._rightFrame, text="Description:", font=BaseView.NORMAL_FONT) self._descFrame = Frame(self._rightFrame) self._descText = Text(self._descFrame, width=50, height=8, state=DISABLED, wrap=WORD, font=BaseView.NORMAL_FONT) self._descScroll = Scrollbar(self._descFrame, command=self._descText.yview) self._descText.config(yscrollcommand=self._descScroll.set) self._notesLabel = Label(self._rightFrame, text="Notes:", font=BaseView.NORMAL_FONT) self._notesFrame = Frame(self._rightFrame) self._notesText = Text(self._notesFrame, width=50, height=8, state=DISABLED, wrap=WORD, font=BaseView.NORMAL_FONT) self._notesScroll = Scrollbar(self._notesFrame, command=self._notesText.yview) self._notesText.config(yscrollcommand=self._notesScroll.set) # placement: scrollbars self._inhabitantNotes.grid(row=0, column=0, sticky=N + W + E + S) self._inhabitantNotesScroll.grid(row=0, column=1, sticky=N + S) self._descText.grid(row=0, column=0, sticky=N + W + E + S) self._descScroll.grid(row=0, column=1, sticky=N + S) self._notesText.grid(row=0, column=0, sticky=N + W + E + S) self._notesScroll.grid(row=0, column=1, sticky=N + S) # placement: left frame self._imgLabel.grid(row=0, column=0, columnspan=2, sticky=N + W + E + S) self._storeLabel.grid(row=1, column=0, sticky=N + W) self._storeCombo.grid(row=1, column=1, sticky=E) self._storePreview.grid(row=2, column=0, columnspan=2, sticky=W + E) self._leftSep1.grid(row=3, column=0, columnspan=2, sticky=W + E) self._inhabitantLabel.grid(row=4, column=0, sticky=N + W) self._inhabitantCombo.grid(row=4, column=1, sticky=E) self._inhabitantPreview.grid(row=5, column=0, columnspan=2, sticky=W + E) self._inhabitantNotesLabel.grid(row=6, column=0, columnspan=2, sticky=N + W) self._inhabitantNotesFrame.grid(row=7, column=0, columnspan=2, sticky=N + W + E) # placement: right frame self._nameLabel.grid(row=0, column=0, sticky=W) self._descLabel.grid(row=1, column=0, sticky=W) self._descFrame.grid(row=2, column=0, sticky=W) self._notesLabel.grid(row=3, column=0, sticky=W) self._notesFrame.grid(row=4, column=0, sticky=W) self._leftFrame.grid(row=0, column=0, sticky=N + W) self._rightFrame.grid(row=0, column=1, sticky=N + W) ######## # Add callbacks for all GUI element events and Tkinter variables. def _bind_widgets(self): self._storeVar.trace('w', self._preview_store) self._inhabitantVar.trace('w', self._preview_inhabitant) self._storePreview.bind("<Double-Button-1>", self._open_store) self._inhabitantPreview.bind("<Double-Button-1>", self._open_inhabitant) ######## # Populates all GUI elements with new data. def populate(self, data): self._data = data if data == None: # null check self.set_defaults() return for k, v in data.items(): if k == "img": if v == None: # null check v = BaseView.DEFAULT_IMG utility.update_img(self._imgLabel, v, maxSize=300) elif k == "name": # non-null self._nameLabel.config(text=v) elif k == "description": if v == None: # null check v = "" utility.update_text(self._descText, v) elif k == "notes": if v == None: # null check v = "" utility.update_text(self._notesText, v) elif k == "stores": if v == None: # null check v = [] utility.update_combobox(self._storeCombo, [store["name"] for store in v]) elif k == "creatures": if v == None: # null check v = [] utility.update_combobox( self._inhabitantCombo, [creature["creature"]["name"] for creature in v]) ######## # Resets GUI elements to default values. def set_defaults(self): utility.update_img(self._imgLabel, BaseView.DEFAULT_IMG, maxSize=300) utility.update_text(self._descText, BaseView.EMPTY_STR) utility.update_text(self._notesText, BaseView.EMPTY_STR) utility.update_combobox(self._storeCombo, []) utility.update_combobox(self._inhabitantCombo, []) ######## # Updates equipment preview. def _preview_store(self, *args, **kwargs): # first reset all self._storePreview.set_defaults() # update with new values if self._data == None or self._storeCombo.current() == -1: return newStore = self._data["stores"][self._storeCombo.current()] if newStore != None: self._storePreview.populate(newStore) ######## # Updates drop preview. def _preview_inhabitant(self, *args, **kwargs): # first reset all self._inhabitantPreview.set_defaults() utility.update_text(self._inhabitantNotes, BaseView.EMPTY_STR) # update with new values if self._data == None or self._inhabitantCombo.current() == -1: return newInhabitant = self._data["creatures"][ self._inhabitantCombo.current()] if newInhabitant != None: self._inhabitantPreview.populate(newInhabitant["creature"]) if newInhabitant["notes"] != None: utility.update_text(self._inhabitantNotes, newInhabitant["notes"]) ######## # Opens store view through refBook. def _open_store(self, *args, **kwargs): idx = self._storeCombo.current() if self._refBook == None or self._data == None or idx == -1 or len( self._data["stores"]) == 0: return self._refBook.show_store(self._data["stores"][idx]["name"], self._data["name"]) ######## # Opens creature view through refBook. def _open_inhabitant(self, *args, **kwargs): idx = self._inhabitantCombo.current() if self._refBook == None or self._data == None or idx == -1 or len( self._data["creatures"]) == 0: return self._refBook.show_creature( self._data["creatures"][idx]["creature"]["name"])
def main_menu(self): root = tk.Tk() root.title("Pathfinding") left = tk.Frame(root, bg="#b3b3b6", width=200, height=200) left.pack_propagate(False) tk.Label(left, text="1: Choose algorthm.", fg="black", bg="#b3b3b6", anchor="center", justify="center").pack() left.grid(column=0, row=0, pady=5, padx=10, sticky="n") sepl = Separator(root, orient="vertical") sepl.grid(column=1, row=0, sticky="ns") sty = Style(root) sty.configure("TSeparator", background="#eaeaef") center = tk.Frame(root, bg="#b3b3b6", width=200, height=200) center.pack_propagate(False) tk.Label(center, text="2: Choose level.", fg="black", bg="#b3b3b6").pack() center.grid(column=2, row=0, pady=5, padx=10, sticky="n") sepr = Separator(root, orient="vertical") sepr.grid(column=3, row=0, sticky="ns") bfs_button = tk.Button(left, text="Breadth First Search", bg="#D6AA5B", command=lambda *args: self.set_algo("bfs"), width=15) bfs_button.grid(row=0, column=0) d_button = tk.Button(left, text="Dijkstra", command=lambda *args: self.set_algo("d"), width=15) d_button.grid(row=1, column=0) a_button = tk.Button(left, text="A* Pathfinder", command=lambda *args: self.set_algo("a"), width=15) a_button.grid(row=2, column=0) level11_button = tk.Button(center, text="1-1", command=lambda *args: self.set_level("1-1")) level11_button.grid(row=0, column=0) level12_button = tk.Button(center, text="1-2", command=lambda *args: self.set_level("1-2")) level12_button.grid(row=1, column=0) level13_button = tk.Button(center, text="1-3", command=lambda *args: self.set_level("1-3")) level13_button.grid(row=2, column=0) level14_button = tk.Button(center, text="1-4", command=lambda *args: self.set_level("1-4")) level14_button.grid(row=3, column=0) level21_button = tk.Button(center, text="2-1", command=lambda *args: self.set_level("2-1")) level21_button.grid(row=0, column=1) level22_button = tk.Button(center, text="2-2", command=lambda *args: self.set_level("2-2")) level22_button.grid(row=1, column=1) level23_button = tk.Button(center, text="2-3", command=lambda *args: self.set_level("2-3")) level23_button.grid(row=2, column=1) level24_button = tk.Button(center, text="2-4", command=lambda *args: self.set_level("2-4")) level24_button.grid(row=3, column=1) execute_button = tk.Button(root, text="Run!", bg="green", command=lambda *args: self.run(self.algo, self.level)) execute_button.grid(row=0, column=4, padx=5) root.mainloop()
class AppRow(MagicSession, Frame): """ Row for each app in mixer. handles refreshing the gui if session is changed external. handles user input and changing session volume/mute. """ def __init__(self, root_frame_instance): super().__init__(volume_callback=self.update_volume, mute_callback=self.update_mute, state_callback=self.update_state) self.root_frame_instance = root_frame_instance # ______________ DISPLAY NAME ______________ self.app_name = self.magic_root_session.app_exec print(f":: new session: {self.app_name}") # ______________ CREATE FRAME ______________ # super(MagicSession, self).__init__(root_frame_instance) Frame.__init__(self, root_frame_instance) # _______________ NAME LABEL _______________ self.name_label = Label(self, text=self.app_name, font=("Consolas", 12, "italic")) # _____________ VOLUME SLIDER _____________ self.volume_slider_state = DoubleVar() self.volume_slider = Scale(self, variable=self.volume_slider_state, command=self._slide_volume, from_=0, to=100, takefocus=False, orient=HORIZONTAL) # set initial: self.volume_slider_state.set(self.volume * 100) # ______________ MUTE BUTTON ______________ self.mute_button_state = StringVar() self.mute_button = Button(self, style="", textvariable=self.mute_button_state, command=self._toogle_mute, takefocus=False) # set initial: self.update_mute(self.mute) # _____________ SESSION STATUS _____________ self.status_line = Frame(self, style="", width=6) # set initial: self.update_state(self.state) # ________________ SEPARATE ________________ self.separate = Separator(self, orient=HORIZONTAL) # ____________ ARRANGE ELEMENTS ____________ # set column[1] to take the most space # and make all others as small as possible: self.columnconfigure(1, weight=1) # grid self.name_label.grid(row=0, column=0, columnspan=2, sticky="EW") self.mute_button.grid(row=1, column=0) self.volume_slider.grid(row=1, column=1, sticky="EW", pady=10, padx=20) self.separate.grid(row=2, column=0, columnspan=3, sticky="EW", pady=10) self.status_line.grid(row=0, rowspan=2, column=2, sticky="NS") # _____________ DISPLAY FRAME _____________ self.pack(pady=0, padx=15, fill='x') def update_volume(self, new_volume): """ when volume is changed externally (see callback -> AudioSessionEvents -> OnSimpleVolumeChanged ) """ # compare if the windows callback is because we set the slider: # if so drop update since we made the change # and all is already up to date - this will prevent lagg print(f"{self.app_name} volume: {new_volume}") self.volume_slider_state.set(new_volume * 100) def update_mute(self, new_mute): """ when mute state is changed by user or through other app """ if new_mute: icon = "🔈" self.mute_button.configure(style="Muted.TButton") else: icon = "🔊" self.mute_button.configure(style="Unmuted.TButton") # .set is a method of tkinters variables # it will change the button text print(f"{self.app_name} mute: {icon}") self.mute_button_state.set(icon) def update_state(self, new_state): """ when status changed (see callback -> AudioSessionEvents -> OnStateChanged) """ print(f"{self.app_name} state: {new_state}") if new_state == AudioSessionState.Inactive: # AudioSessionStateInactive self.status_line.configure(style="Inactive.TFrame") elif new_state == AudioSessionState.Active: # AudioSessionStateActive self.status_line.configure(style="Active.TFrame") elif new_state == AudioSessionState.Expired: # AudioSessionStateExpired self.status_line.configure(style="TFrame") """when session expires""" print(f":: closed session: {self.app_name}") self.destroy() def _slide_volume(self, value): """ when slider moved by user """ new_volume = float(value) / 100 # check if new user value really is new: (ttk bug) if self.volume != new_volume: # since self.volume is true data through windows # it will generally differ, but 1.0 == 1 print(f"with pycaw: {self.app_name} volume: {new_volume}") self.volume = new_volume def _toogle_mute(self): """ when mute button pressed """ new_mute = self.toggle_mute() self.update_mute(new_mute)
def updateOutput(self): ''' Reads from output variable to update GUI. Rather contrived in how it does it. The grid might look a bit ugly, but it took me a stupid amount of time, so it means a lot to me. ''' global output # Only edit if something has changed if self.lastOutput != output: # Clear previous display (dynamically adding/removing is not worth the effort) for tupl in self.seriesOfLabels: tupl[0].grid_forget() tupl[0].destroy() # In try block because the last one only has 3 elements, and # it wasn't worth trying to find a way to do this without a # try block since the None will always be the last element. try: tupl[1].grid_forget() tupl[1].destroy() tupl[2].grid_forget() tupl[2].destroy() tupl[3].grid_forget() tupl[3].destroy() except: pass self.seriesOfLabels = [] # This prevents it from rendering grid if no output if output != "": self.outputL['text'] = "\t" lines = output.split('\n') # This variable helps the loop tell where to place objects grid = 19 # Make topmost line line1 = Separator(self) line1.grid(row=18, column=1, columnspan=2, sticky="ew") # Sequentially make labels for each of the devices found for address in lines: if (address != ""): addresses = address.split('::') #self.seriesOfIPA.append(addresses[2]) name = Label(self, text=addresses[0] + " ") mac = Label(self, text=addresses[1]) ip = Label(self, text=addresses[2], cursor="hand2", highlightthickness=2, relief='raised') # Make it so you can click on the IP addresses to copy # them to clipboard ip.bind("<Button-1>", self.copy) name.grid(column=0, row=grid, sticky='e') mac.grid(column=1, row=grid) ip.grid(column=2, row=grid) # Add line that separates elements line = Separator(self) line.grid(row=grid + 1, column=1, columnspan=2, sticky="ew") # Basic iteration stuff grid += 2 self.seriesOfLabels.append((name, mac, ip, line)) if grid > 32: self.root.geometry("500x1000") # Fill out the grid with things that go on the side span = grid - 19 if span < 1: span = 1 line2 = Separator(self, orient='vertical').grid(column=0, row=19, rowspan=span, sticky='nse') line3 = Separator(self, orient='vertical').grid(column=3, row=19, rowspan=span, sticky='nsw') self.seriesOfLabels.append((line1, line2, line3, None)) self.lastOutput = output # Call itself soon to update any changes while searching for # devices. if (self.searching > 0): # 5 times a second self.after(200, self.updateOutput) self.searching -= 1 if self.searching == 0: self.spin['text'] = "" if output == "": self.outputL['text'] = "\t[None Found]" else: self.spin['text'] = self.spinner[self.counter] self.counter += 1 if self.counter == self.spinlength: self.counter = 0
class CollectDataWindow(Frame): def __init__(self, master=None): Frame.__init__(self, master) self.master = master self.pack(fill=BOTH, expand=1) self.user_path = "" self.sessions_label = Label(self, text="Durchgänge") self.record_time_label = Label(self, text="Zeit pro Geste") self.device_r_label = Label(self, text="Armband rechts") self.device_l_label = Label(self, text="Armband links") self.sep1 = Separator(self, orient=HORIZONTAL) self.sep2 = Separator(self, orient=HORIZONTAL) self.session_val = IntVar(self, value=10) self.record_time_val = IntVar(self, value=5) self.sessions_input = Entry(self, textvariable=self.session_val, width=3) self.record_time_input = Entry(self, textvariable=self.record_time_val, width=3) self.collect_separate_btn = Button( master=self, text="Collect Separate", command=lambda: self.introduction_screen_ui(mode=SEPARATE, trial=False)) self.collect_continues_btn = Button( master=self, text="Collect Continues", command=lambda: self.introduction_screen_ui(mode=CONTINUES, trial=False)) self.trial_separate_btn = Button( master=self, text="Trial Separate", command=lambda: self.introduction_screen_ui(mode=SEPARATE, trial=True)) self.trial_continues_btn = Button( master=self, text="Trial Continues", command=lambda: self.introduction_screen_ui(mode=CONTINUES, trial=True)) self.close_btn = Button(self, text="Close", command=collect_window.withdraw) self.sessions_label.grid(row=0, column=0, pady=4, padx=2) self.sessions_input.grid(row=0, column=1) self.record_time_label.grid(row=1, column=0, pady=4, padx=2) self.record_time_input.grid(row=1, column=1) self.collect_separate_btn.grid(row=4, column=0, pady=4, padx=8) self.collect_continues_btn.grid(row=4, column=2, pady=4, padx=8) self.trial_separate_btn.grid(row=5, column=0, pady=4, padx=8) self.trial_continues_btn.grid(row=5, column=2, pady=4, padx=8) self.sep1.grid(row=6, column=0, sticky="ew", columnspan=3, padx=4, pady=8) self.close_btn.grid(row=7, column=1, pady=8, padx=4, sticky=E) def introduction_screen_ui(self, mode, trial): introduction_screen = IntroductionScreen( introduction_window, record_time=self.record_time_val.get(), sessions=self.session_val.get()) introduction_window.deiconify() if mode == SEPARATE: title = "Collect separate data" raw_path = self.user_path + "/raw_separate" else: title = "Collect continues data" raw_path = self.user_path + "/raw_continues" if trial: title += " TRIAL" introduction_window.title(title) introduction_screen.init_sessionbar() initialize_data_collection(raw_path=raw_path, trial=trial, mode=mode, introduction_screen=introduction_screen, record_time=self.record_time_val.get()) introduction_window.mainloop()
class MainWindow(Frame): def __init__(self, master=None): self.released_anime = [] Frame.__init__(self, master) self.grid() self.createWidgets() #master.resizable(False, False) #making the window un-resizable master.config(menu=self.menubar) def createWidgets(self): # The menu bar at the top self.menubar = Menu(self) # The submenu of the menubar self.filemenu = Menu(self.menubar, tearoff=0) self.filemenu.add_command(label="Open") self.menubar.add_cascade(label="File", menu=self.filemenu) # The list that will contain all the anime names self.list = Listbox(self, width=50, selectmode=EXTENDED) self.list.grid(row=0, column=0, rowspan=2) # The button that generates the listing self.list_button = Button(self, text="Create list", command=lambda: self.generate_list()) self.list_button.grid(row=0, column=1) # The button that generates the listing self.list_and_download_button = Button( self, text="Create & download list", command=lambda: self.generate_and_download_list()) self.list_and_download_button.grid(row=1, column=1) # The button that downloads the selected items self.download_button = Button(self, text="Download", command=lambda: self.download_selected()) self.download_button.grid(row=2, column=1) #seperator in the middle self.seperator = Separator(orient=HORIZONTAL) self.seperator.grid(row=3, column=0, pady=5, padx=20, columnspan=2, sticky="ew") #Log box at the bottom self.log_box = Text(width=57, height=14, bg="silver") self.log_box.grid(row=4, column=0, padx=10, pady=10, columnspan=2) def generate_list(self): self.log("Creating List...") self.released_anime = create_list() for anime in self.released_anime: self.list.insert(END, anime.raw_name) self.log("List made!") def generate_and_download_list(self): self.generate_list() for anime in self.released_anime: if anime.list_type == 'pref_list': if ( anime.episode_no > Database.pref_anime[anime.name] ): # Checking if the episode number of the released anime is newer than what i had previously downloaded self.log("Downloading " + anime.title) downloaded = anime.download() if downloaded: Database.increment(anime.name, anime.episode_no) elif anime.list_type == False: AddAnimeDialog(anime, Tk()).mainloop() self.log("Done!") def download_selected(self): for index in self.list.curselection(): self.log(f"Downloading {self.released_anime[index].title}") self.released_anime[index].download() def log(self, message): self.log_box.insert(INSERT, message + "\n") time.sleep(0.1)
def printInfo(): print(f"Account:{accountE.get()}\nPassword:{passwordE.get()}") root = Tk() root.title("Python GUI - Entry") root.geometry("300x160") labelTitle = Label(root, text="Login Form", font=("Segoe UI", 16, "bold", "roman")) labelTitle.grid(row=0, columnspan=2) sep = Separator(root) sep.grid(row=1, columnspan=2, sticky="nswe", padx=2, pady=5) accountL = Label(root, text="Account ") accountL.grid(row=2, padx=(50, 5), sticky='e') passwordL = Label(root, text="Password ") passwordL.grid(row=3, padx=(50, 5), sticky='e') accountE = Entry(root) accountE.grid(row=2, column=1, padx=(5, 50)) passwordE = Entry(root, show='*') passwordE.grid(row=3, column=1, padx=(5, 50)) loginbtn = Button(root, text="Login", command=printInfo) loginbtn.grid(row=4, column=0, sticky="e")
class ResultsFrame(LabelFrame): padY = 5 padX = 30 def __init__(self,parent): LabelFrame.__init__(self, parent,text="Results", width=825, height=485) # Terrible kludgy hack to force the app to stay the right size # Need to work out how to remove self.grid_propagate(False) self.resultsDict = None self.modelType = None self.currentSegment = 0 # Stats frame self.statsFrame = StatsFrame(self, self.padX, self.padY) self.statsFrame.calculate_B.bind("<Button-1>", self._parametersChanged) self.statsFrame.reset_B.bind("<Button-1>", self._parametersReset) def onComboBoxSelect(e): self.currentSegment = e.widget.current() self._updateDisplay(True) self.statsFrame.expSeg_CB.bind("<<ComboboxSelected>>", onComboBoxSelect) # Error frame self.errorSurfaceFrame = ErrorSurfaceFrame(self) self.errorSurfaceFrame.errorSurfaceB.bind("<Button-1>", self._displayErrorSurface) # Graph notebook self.errorSurfaceSeperator = Separator(self,orient=tkinter.HORIZONTAL) self.graphNotebook = ImprovedNotebook(self) self.modelGraphFrame = GraphFrame(self.graphNotebook, dim=2) self.modelGraphFrame.axes.set_ylabel(r'$thickness(m)$') self.regressionGraphFrame = GraphFrame(self.graphNotebook, dim=2) self.regressionGraphFrame.axes.set_ylabel(r'$\ln{(thickness(m))}$') self.errorSurfaceGraphFrame = GraphFrame(self.graphNotebook, dim=3) self.errorSurfaceGraphFrame.axes.set_zlabel(r'$error$') self.graphNotebook.addFrame(self.modelGraphFrame, text="Model") def displayNewModel(self, modelType, resultsDict): self.modelType = modelType self.isopachs = resultsDict["isopachs"] self.sqrtAreaKM = [isopach.sqrtAreaKM for isopach in self.isopachs] self.thicknessM = [isopach.thicknessM for isopach in self.isopachs] self.currentParameters = resultsDict self.defaultParameters = deepcopy(self.currentParameters) self.statsFrame.grid(row=0,column=0,padx=10,pady=5,sticky="NESW") self.graphNotebook.grid(row=0,column=1,padx=10, pady=5,sticky="NEW") if self.modelType == Model.EXP: self._displayExp() self.config(text="Results (Exponential)") else: self.errorSurfaceSeperator.grid(row=1, column=0, columnspan=2, padx=20, pady=(20,0), sticky="EW") self.errorSurfaceFrame.grid(row=2, column=0, columnspan=2, padx=10, pady=0, sticky="EW") if self.modelType == Model.POW: self._displayPow() self.config(text="Results (Power law)") elif self.modelType == Model.WEI: self._displayWei() self.config(text="Results (Weibull)") self._updateDisplay(False) def _updateDisplay(self, comboboxUpdate): if not comboboxUpdate: self.modelGraphFrame.clear() self.regressionGraphFrame.clear() thicknessM = [isopach.thicknessM for isopach in self.isopachs] sqrtArea = [isopach.sqrtAreaKM for isopach in self.isopachs] self.modelGraphFrame.plotScatter(sqrtArea,thicknessM,True) self.modelGraphFrame.axes.set_xlabel(r"$\sqrt{Area}$") if self.modelType == Model.EXP: self._updateExp(comboboxUpdate) elif self.modelType == Model.POW: self._updatePow() elif self.modelType == Model.WEI: self._updateWei() def _displayExp(self): fr = self.statsFrame padX = self.padX padY = self.padY fr.expSeg_CB.grid(row=3,column=0,sticky="W",padx=10,pady=padY) vals = ["Segment " + str(i) for i in range(1,self.currentParameters["numberOfSegments"]+1)] fr.expSeg_CB.configure(values=vals) fr.expSeg_CB.current(0) fr.expSegVolume_L.grid(row=4,column=0,padx=10,sticky="W",pady=padY) fr.expSegVolume_E.grid(row=4,column=1,padx=10,sticky="E") fr.equation_L.grid(row=5,column=0,sticky="W",padx=10,pady=padY) fr.equation_E.grid(row=5,column=1,padx=10,sticky="E") fr.equation_L.configure(text="Segment equation:") fr.parameters_L.grid(row=6,column=0,padx=10,pady=padY,sticky="W") fr.expSegStartLimit_L.grid(row=7,column=0,sticky="W",padx=padX,pady=padY) fr.expSegStartLimit_E.grid(row=7,column=1,padx=10,sticky="E") fr.expSegEndLimit_L.grid(row=8,column=0,sticky="W",padx=padX,pady=padY) fr.expSegEndLimit_E.grid(row=8,column=1,padx=10,sticky="E") fr.expSegCoefficent_L.grid(row=9,column=0,sticky="W",padx=padX,pady=padY) fr.expSegCoefficent_E.grid(row=9,column=1,padx=10,sticky="E") fr.expSegExponent_L.grid(row=10,column=0,sticky="W",padx=padX,pady=padY) fr.expSegExponent_E.grid(row=10,column=1,padx=10,sticky="E") # Recalculate buttons fr.calculate_B.grid(row=11,column=0,padx=padX,pady=padY,sticky="W") fr.reset_B.grid(row=11,column=1,padx=10,sticky="E") self.graphNotebook.addFrame(self.regressionGraphFrame, text="Regression") def _displayPow(self): fr = self.statsFrame padX = self.padX padY = self.padY fr.equation_L.grid(row=2,column=0,sticky="W",padx=10,pady=padY) fr.equation_E.grid(row=2,column=1,padx=10,sticky="E") fr.equation_L.configure(text="Equation:") fr.parameters_L.grid(row=3,column=0,padx=10,pady=padY,sticky="W") fr.powCoefficient_L.grid(row=4,column=0,sticky="W",padx=padX,pady=padY) fr.powCoefficient_E.grid(row=4,column=1,padx=10,sticky="E") fr.powExponent_L.grid(row=5,column=0,sticky="W",padx=padX,pady=padY) fr.powExponent_E.grid(row=5,column=1,padx=10,sticky="E") fr.powProximalLimit_L.grid(row=6,column=0,sticky="W",padx=padX,pady=padY) fr.powProximalLimit_E.grid(row=6,column=1,padx=10,sticky="E") fr.powDistalLimit_L.grid(row=7,column=0,sticky="W",padx=padX,pady=padY) fr.powDistalLimit_E.grid(row=7,column=1,padx=10,sticky="E") # Recalculate buttons fr.calculate_B.grid(row=8,column=0,padx=padX,pady=padY,sticky="W") fr.reset_B.grid(row=8,column=1,padx=10,sticky="E") fr.powSuggestedProximalLimit_L.grid(row=9,column=0,sticky="W",padx=10,pady=padY) fr.powSuggestedProximalLimit_E.grid(row=9,column=1,padx=10,sticky="E") self.graphNotebook.addFrame(self.regressionGraphFrame, text="Regression") self.errorSurfaceFrame.update("c", "m", 0.0, 5.0, 0.0, 5.0) def _displayWei(self): fr = self.statsFrame padX = self.padX padY = self.padY fr.equation_L.grid(row=2,column=0,sticky="W",padx=10,pady=padY) fr.equation_E.grid(row=2,column=1,padx=10,sticky="E") fr.equation_L.configure(text="Equation:") fr.parameters_L.grid(row=3,column=0,padx=10,pady=padY,sticky="W") fr.weiLambdaL.grid(row=4,column=0,padx=padX,pady=padY,sticky="W") fr.weiLambdaE.grid(row=4,column=1,padx=10,sticky="E") fr.weiKL.grid(row=5,column=0,padx=padX,pady=padY,sticky="W") fr.weiKE.grid(row=5,column=1,padx=10,sticky="E") fr.weiThetaL.grid(row=6,column=0,padx=padX,pady=padY,sticky="W") fr.weiThetaE.grid(row=6,column=1,padx=10,sticky="E") # Recalculate buttons fr.calculate_B.grid(row=7,column=0,padx=padX,pady=padY,sticky="W") fr.reset_B.grid(row=7,column=1,padx=10,sticky="E") parameterLimits = self.currentParameters["limits"] lambdaLower, lambdaUpper = parameterLimits[0] kLower, kUpper = parameterLimits[1] self.errorSurfaceFrame.update("\u03BB", "k", lambdaLower, lambdaUpper, kLower, kUpper) def _updateExp(self, comboboxUpdate): n = self.currentParameters["numberOfSegments"] coefficients = self.currentParameters["segmentCoefficients"] exponents = self.currentParameters["segmentExponents"] limits = self.currentParameters["segmentLimits"] ########### ## Stats ## ########### fr = self.statsFrame # Segment start start = limits[self.currentSegment] startStr = helper_functions.roundToSF(start, NUMBER_OF_SF) fr.expSegStartLimit_E.insertNew(start) fr.expSegStartLimit_E.setUserEditable(self.currentSegment != 0) # Segment end end = limits[self.currentSegment+1] endStr = helper_functions.roundToSF(end, NUMBER_OF_SF) fr.expSegEndLimit_E.insertNew(end) fr.expSegEndLimit_E.setUserEditable(self.currentSegment != n-1) # Segment coefficient coefficient = coefficients [self.currentSegment] coefficientStr = helper_functions.roundToSF(coefficient, NUMBER_OF_SF) fr.expSegCoefficent_E.insertNew(coefficient) # Segment exponent exponent = exponents[self.currentSegment] exponentStr = helper_functions.roundToSF(exponent, NUMBER_OF_SF) fr.expSegExponent_E.insertNew(exponent) # Segment volume segmentVolumes = [calculateExponentialSegmentVolume(coefficients[i], exponents[i], limits[i], limits[i+1]) for i in range(n)] segmentVolumeStr = helper_functions.roundToSF(segmentVolumes[self.currentSegment], NUMBER_OF_SF) fr.expSegVolume_E.insertNew(segmentVolumeStr) # Total volume totalVolume = sum(segmentVolumes) estimatedTotalVolumeStr = helper_functions.roundToSF(totalVolume, NUMBER_OF_SF) fr.totalEstimatedVolume_E.insertNew(estimatedTotalVolumeStr) # Error def thicknessFunction(x): for i in range(n): if limits[i] <= x < limits[i+1]: return coefficients[i]*math.exp(-exponents[i]*x) error = regression_methods.meanRelativeSquaredError(self.sqrtAreaKM, self.thicknessM, thicknessFunction) errorStr = helper_functions.roundToSF(error, NUMBER_OF_SF) fr.relativeSquaredError_E.insertNew(errorStr) # Equation equationStr = "T = " + coefficientStr if exponent > 0: equationStr += "exp(-" + exponentStr + "x)" elif exponent < 0: equationStr += "exp(" + exponentStr[1:] + "x)" fr.equation_E.insertNew(equationStr) ############ ## Graphs ## ############ if not comboboxUpdate: # Model endXs = limits[1:-1] + [1.5*max(self.sqrtAreaKM)-0.5*min(self.sqrtAreaKM)] for i in range(n): xs = helper_functions.getStaggeredPoints(limits[i], endXs[i], MODEL_PLOTTING_PRECISION) ys = [coefficients[i]*math.exp(-exponents[i]*x) for x in xs] self.modelGraphFrame.plotFilledLine(xs, ys, color=colours[i]) # Regression logThicknessM = [np.log(t) for t in self.thicknessM] self.regressionGraphFrame.plotScatter(self.sqrtAreaKM, logThicknessM, False) self.regressionGraphFrame.axes.set_xlabel(r"$\sqrt{Area}$") for i in range(n): xs = [limits[i], endXs[i]] ys = [np.log(thicknessFunction(x)) for x in xs] self.regressionGraphFrame.plotLine(xs,ys, color=colours[i]) def _updatePow(self): ########### ## Stats ## ########### fr = self.statsFrame # Coefficient c = self.currentParameters["coefficient"] coefficientStr = helper_functions.roundToSF(c, NUMBER_OF_SF) fr.powCoefficient_E.insertNew(c) # Exponent m = self.currentParameters["exponent"] exponentStr = helper_functions.roundToSF(m, NUMBER_OF_SF) fr.powExponent_E.insertNew(m) # Proximal limit proximalLimitKM = self.currentParameters["proximalLimitKM"] proximalLimitStr = helper_functions.roundToSF(proximalLimitKM, NUMBER_OF_SF) fr.powProximalLimit_E.insertNew(proximalLimitKM) # Distal limit distalLimitKM = self.currentParameters["distalLimitKM"] distalLimitStr = helper_functions.roundToSF(distalLimitKM, NUMBER_OF_SF) fr.powDistalLimit_E.insertNew(distalLimitKM) # Volume volume = calculatePowerLawVolume(c, m, proximalLimitKM, distalLimitKM) volumeStr = helper_functions.roundToSF(volume, NUMBER_OF_SF) fr.totalEstimatedVolume_E.insertNew(volumeStr) # Error thicknessFunction = lambda x : c*(x**(-m)) error = regression_methods.meanRelativeSquaredError(self.sqrtAreaKM, self.thicknessM, thicknessFunction) errorStr = helper_functions.roundToSF(error, NUMBER_OF_SF) fr.relativeSquaredError_E.insertNew(errorStr) # Equation equationStr = "T = " + coefficientStr if m > 0: equationStr += "x^-" + exponentStr elif m < 0: equationStr += "x^" + exponentStr[1:] fr.equation_E.insertNew(equationStr) # Suggested proximal limit suggestedProximalLimit = self.currentParameters["suggestedProximalLimit"] suggestedProximalLimitStr = helper_functions.roundToSF(suggestedProximalLimit, NUMBER_OF_SF) fr.powSuggestedProximalLimit_E.insertNew(suggestedProximalLimitStr) ############ ## Graphs ## ############ startX = proximalLimitKM*SQRT_PI endX = distalLimitKM*SQRT_PI # Model xs = helper_functions.getStaggeredPoints(startX, endX, MODEL_PLOTTING_PRECISION) ys = [thicknessFunction(x) for x in xs] self.modelGraphFrame.plotFilledLine(xs, ys, color=colours[0]) # Regression logXs = [np.log(a) for a in self.sqrtAreaKM] logYs = [np.log(t) for t in self.thicknessM] self.regressionGraphFrame.plotScatter(logXs, logYs, False) self.regressionGraphFrame.axes.set_xlabel(r"$\log{\sqrt{Area}}$") lineXs = [np.sqrt(startX), np.sqrt(endX)] lineYs = [np.log(c) - m*x for x in lineXs] self.regressionGraphFrame.plotLine(lineXs, lineYs, colours[0]) def _updateWei(self): ########### ## Stats ## ########### fr = self.statsFrame # lambda lamb = self.currentParameters["lambda"] lambdaStr = helper_functions.roundToSF(lamb, NUMBER_OF_SF) fr.weiLambdaE.insertNew(lamb) # k k = self.currentParameters["k"] kStr = helper_functions.roundToSF(k, NUMBER_OF_SF) fr.weiKE.insertNew(k) # theta theta = self.currentParameters["theta"] thetaStr = helper_functions.roundToSF(theta, NUMBER_OF_SF) fr.weiThetaE.insertNew(theta) # Volume volume = calculateWeibullVolume(lamb, k, theta) volumeStr = helper_functions.roundToSF(volume, NUMBER_OF_SF) fr.totalEstimatedVolume_E.insertNew(volumeStr) # Error thicknessFunction = lambda x : theta*((x/lamb)**(k-2))*math.exp(-((x/lamb)**k)) error = regression_methods.meanRelativeSquaredError(self.sqrtAreaKM, self.thicknessM, thicknessFunction) errorStr = helper_functions.roundToSF(error, NUMBER_OF_SF) fr.relativeSquaredError_E.insertNew(errorStr) # Equation invLambdaStr = helper_functions.roundToSF(1/lamb, NUMBER_OF_SF) kminus2Str = helper_functions.roundToSF(k-2, NUMBER_OF_SF) equationStr = "T = " + thetaStr + "((" + invLambdaStr + "x)^" +kminus2Str + ")exp(-(" + invLambdaStr + "x)^" + kStr + ")" fr.equation_E.insertNew(equationStr) ############ ## Graphs ## ############ # Model startX = 0 endX = (self.isopachs[-1].distanceFromVentKM()+50)*SQRT_PI xs = helper_functions.getStaggeredPoints(startX,endX,MODEL_PLOTTING_PRECISION)[1:] ys = [theta*((x/lamb)**(k-2))*math.exp(-((x/lamb)**k)) for x in xs] self.modelGraphFrame.plotFilledLine(xs, ys, colours[0]) def _displayErrorSurface(self,event): try: xLL, xUL, yLL, yUL, resolution = self.errorSurfaceFrame.getSurfaceParameters() except ValueError as ve: messagebox.showerror("Calculation error", ve.args[0]) return self.graphNotebook.addFrame(self.errorSurfaceGraphFrame, text="Error surface") if self.errorSurfaceFrame.xSymbol == "\u03BB": self.errorSurfaceGraphFrame.axes.set_xlabel("$\lambda$") else: self.errorSurfaceGraphFrame.axes.set_xlabel(self.errorSurfaceFrame.xSymbol) xs = [isopach.sqrtAreaKM for isopach in self.isopachs] ys = [isopach.thicknessM for isopach in self.isopachs] if self.modelType == Model.POW: def errorFunction(c,m): thicknessFunction = lambda x : c*(x**(-m)) return math.log(regression_methods.meanRelativeSquaredError(xs, ys, thicknessFunction)) elif self.modelType == Model.WEI: def errorFunction(lamb,k): theta = calculateTheta(xs,ys,lamb,k) def thicknessFunction(x): try: return np.exp(np.log(theta)+(k-2)*np.log(x/lamb)-(x/lamb)**k) except FloatingPointError: return 0 mrse = regression_methods.meanRelativeSquaredError(xs, ys, thicknessFunction) return math.log(mrse) self.errorSurfaceGraphFrame.axes.set_ylabel(self.errorSurfaceFrame.ySymbol) self.errorSurfaceGraphFrame.clear() self.errorSurfaceGraphFrame.plotSurface(errorFunction, xLL, xUL, yLL, yUL, resolution) self.graphNotebook.select(self.errorSurfaceGraphFrame) def _parametersReset(self,event): self.currentParameters = deepcopy(self.defaultParameters) self._updateDisplay(False) def _parametersChanged(self,event): try: newValues = self.statsFrame.getParameters(self.modelType) except ValueError as ve: messagebox.showerror("Calculation error", ve.args[0]) return if self.modelType == Model.EXP: self.currentParameters["segmentCoefficients"][self.currentSegment] = newValues["c"] self.currentParameters["segmentExponents"][self.currentSegment] = newValues["m"] self.currentParameters["segmentLimits"][self.currentSegment] = newValues["segStart"] self.currentParameters["segmentLimits"][self.currentSegment+1] = newValues["segEnd"] elif self.modelType == Model.POW: self.currentParameters["coefficient"] = newValues["c"] self.currentParameters["exponent"] = newValues["m"] elif self.modelType == Model.WEI: self.currentParameters["lambda"] = newValues["lambda"] self.currentParameters["k"] = newValues["k"] self.currentParameters["theta"] = newValues["theta"] self._updateDisplay(False) def clear(self): if self.modelType is not None: for component in self.statsFrame.components[self.modelType]: component.grid_remove() self.statsFrame.grid_remove() self.graphNotebook.grid_remove() self.errorSurfaceFrame.grid_remove() self.errorSurfaceSeperator.grid_remove() self.config(text="Results") self.modelGraphFrame.clear() self.regressionGraphFrame.clear() self.errorSurfaceGraphFrame.clear() self.graphNotebook.removeFrame(self.regressionGraphFrame) self.graphNotebook.removeFrame(self.errorSurfaceGraphFrame) self.modelType = None
class StoreView(BaseView): ######## # Initializes and places all GUI elements. def _create_widgets(self): # left frame self._leftFrame = Frame(self) self._imgLabel = Label(self._leftFrame) self._locLabel = Label(self._leftFrame, text="Location:", font=BaseView.NORMAL_FONT) self._locPreview = SimpleLocationView(self._leftFrame) # right frame self._rightFrame = Frame(self) self._nameLabel = Label(self._rightFrame, compound=LEFT, text="Name", font=BaseView.LARGE_FONT) self._descLabel = Label(self._rightFrame, text="Description:", font=BaseView.NORMAL_FONT) self._descFrame = Frame(self._rightFrame) self._descText = Text(self._descFrame, width=50, height=4, state=DISABLED, wrap=WORD, font=BaseView.NORMAL_FONT) self._descScroll = Scrollbar(self._descFrame, command=self._descText.yview) self._descText.config(yscrollcommand=self._descScroll.set) self._notesLabel = Label(self._rightFrame, text="Notes:", font=BaseView.NORMAL_FONT) self._notesFrame = Frame(self._rightFrame) self._notesText = Text(self._notesFrame, width=50, height=4, state=DISABLED, wrap=WORD, font=BaseView.NORMAL_FONT) self._notesScroll = Scrollbar(self._notesFrame, command=self._notesText.yview) self._notesText.config(yscrollcommand=self._notesScroll.set) # bottom self._sep1 = Separator(self, orient="horizontal") self._invLabel = Label(self, text="Inventory:", font=BaseView.NORMAL_FONT) self._invFrame = Frame(self) self._inventory = Treeview( self._invFrame, columns=["type", "price", "qty", "stockDays"], selectmode="browse", height=15) self._inventory.heading("#0", text="Item", anchor=N + W) self._inventory.column("#0", width=300, anchor=N + W, stretch=True) self._inventory.heading("type", text="Type", anchor=N + W) self._inventory.column("type", width=100, anchor=N + W) self._inventory.heading("price", text="Price", anchor=N + W) self._inventory.column("price", width=60, anchor=N + W) self._inventory.heading("qty", text="Qty", anchor=N + W) self._inventory.column("qty", width=40, anchor=N + W) self._inventory.heading("stockDays", text="Stock Days", anchor=N + W) self._inventory.column("stockDays", width=200, anchor=N + W, stretch=True) self._invScroll = Scrollbar(self._invFrame, command=self._inventory.yview) self._inventory.config(yscrollcommand=self._invScroll.set) # placement: scrollbars self._descText.grid(row=0, column=0, sticky=N + W + E + S) self._descScroll.grid(row=0, column=1, sticky=N + S) self._notesText.grid(row=0, column=0, sticky=N + W + E + S) self._notesScroll.grid(row=0, column=1, sticky=N + S) self._inventory.grid(row=0, column=0, sticky=N + W + E + S) self._invScroll.grid(row=0, column=1, sticky=N + S) # placement: left frame self._imgLabel.grid(row=0, column=0, sticky=N + W + E + S) self._locLabel.grid(row=1, column=0, sticky=N + W) self._locPreview.grid(row=2, column=0, sticky=W + E) # placement: right frame self._nameLabel.grid(row=0, column=0, sticky=W) self._descLabel.grid(row=1, column=0, sticky=W) self._descFrame.grid(row=2, column=0, sticky=W) self._notesLabel.grid(row=3, column=0, sticky=W) self._notesFrame.grid(row=4, column=0, sticky=W) # bottom self._sep1.grid(row=1, column=0, columnspan=2, sticky=W + E) self._invLabel.grid(row=2, column=0, columnspan=2, sticky=N + W) self._invFrame.grid(row=3, column=0, columnspan=2, sticky=W + E) self._leftFrame.grid(row=0, column=0, sticky=N + W) self._rightFrame.grid(row=0, column=1, sticky=N + W) ######## # Add callbacks for all GUI element events and Tkinter variables. def _bind_widgets(self): self._locPreview.bind("<Double-Button-1>", self._open_loc) self._inventory.bind("<Double-Button-1>", self._inventory_on_double_click) ######## # Populates all GUI elements with new data. def populate(self, data): self._data = data if data == None: # null check self.set_defaults() return for k, v in data.items(): if k == "name": # non-null self._nameLabel.config(text=v) elif k == "img": if v == None: # null check v = BaseView.DEFAULT_IMG utility.update_img(self._imgLabel, v, maxSize=300) elif k == "location": # non-null self._locPreview.populate(v) elif k == "description": if v == None: # null check v = BaseView.EMPTY_STR utility.update_text(self._descText, v) elif k == "notes": if v == None: # null check v = BaseView.EMPTY_STR utility.update_text(self._notesText, v) elif k == "sells": self._update_inventory() ######## # Resets GUI elements to default values. def set_defaults(self): utility.update_img(self._imgLabel, BaseView.DEFAULT_IMG, maxSize=300) utility.update_text(self._descText, BaseView.EMPTY_STR) utility.update_text(self._notesText, BaseView.EMPTY_STR) ######## # Populates inventory with correct values def _update_inventory(self): allItems = self._inventory.get_children() for item in allItems: self._inventory.delete(item) self._imgs = [] if self._data == None: return for entry in self._data["sells"]: img = entry["item"]["img"] if img == None: img = BaseView.DEFAULT_IMG img = utility.get_img(img, maxSize=20) name = entry["item"]["name"] fields = [ BaseView.TYPE_MAP[entry["item"]["type"]], entry["price"], entry["qty"], entry["stockDays"] ] for i in range(len(fields)): if fields[i] == None: fields[i] = BaseView.EMPTY_STR self._imgs.append(img) self._inventory.insert("", END, image=img, text=name, values=fields) ######## # Opens location view through refBook. def _open_loc(self, *args, **kwargs): if self._refBook == None or self._data == None: return self._refBook.show_location(self._data["location"]["name"]) ######## # Callback for double clicking in inventory treeview. def _inventory_on_double_click(self, *args, **kwargs): if self._refBook == None or self._data == None or len( self._inventory.selection()) == 0: return self._refBook.show_item(self._data["sells"][self._inventory.index( self._inventory.selection())]["item"]["name"])
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 HashClass: def __init__(self, master): self.filename = '' # By default drop down menu will have Text mode self.list_choice = 'Text' self.label = Label(master, text="DATA:", fg="#ED3276") self.label.grid(row=2, sticky=W, padx=5) self.entry = Entry(master, width="128") self.entry.grid(row=2, column=1, padx=5) # add mouse click event to the data entry field self.entry.bind('<Button-1>', self.clean_up) self.button = Button(master, text="Hashify!", command=self.calc_hash) self.button.grid(row=16, column=1, padx=5, pady=3) self.op_button = Button(master, text="Choose File", command=self.open_box) self.var = StringVar() self.lst = ["Text", "File"] # , "HexString"] self.var.set(self.lst[0]) self.drop_menu = OptionMenu(master, self.var, *self.lst, command=self.toggle_open_btn) self.drop_menu.grid(row=0, column=0, padx=5, sticky=W) self.sep1 = Separator(master, orient=HORIZONTAL) self.sep1.grid(row=1, sticky='we', columnspan=2, pady=5, padx=5) self.sep2 = Separator(master, orient=HORIZONTAL) self.sep2.grid(row=3, sticky='we', columnspan=2, pady=5, padx=5) self.l_md5 = Label(master, text="MD5:", fg="#ED3276") self.l_sha1 = Label(master, text="SHA1:", fg="#ED3276") self.l_sha224 = Label(master, text="SHA-224:", fg="#ED3276") self.l_sha256 = Label(master, text="SHA-256:", fg="#ED3276") self.l_sha384 = Label(master, text="SHA-384:", fg="#ED3276") self.l_sha512 = Label(master, text="SHA-512:", fg="#ED3276") self.l_ripemd = Label(master, text="RIPE-MD-160:", fg="#ED3276") self.l_md4 = Label(master, text="MD4:", fg="#ED3276") self.l_whirl = Label(master, text="WHIRLPOOL:", fg="#ED3276") self.l_dsa = Label(master, text="DSA:", fg="#ED3276") self.l_crc32 = Label(master, text="CRC-32:", fg="#ED3276") self.l_adler32 = Label(master, text="ADLER-32:", fg="#ED3276") self.entryMd5 = Entry(master, width="128") self.entryMd4 = Entry(master, width="128") self.entrySha1 = Entry(master, width="128") self.entrySha224 = Entry(master, width="128") self.entrySha256 = Entry(master, width="128") self.entrySha384 = Entry(master, width="128") self.entrySha512 = Entry(master, width="128") self.entryRipeMd = Entry(master, width="128") self.entryWhirl = Entry(master, width="128") self.entryDsa = Entry(master, width="128") self.entryCrc = Entry(master, width="128") self.entryAdler = Entry(master, width="128") self.l_md5.grid(row=4, sticky=W, padx=5) self.entryMd5.grid(row=4, column=1) self.l_sha1.grid(row=5, sticky=W, padx=5) self.entrySha1.grid(row=5, column=1) self.l_sha224.grid(row=6, sticky=W, padx=5) self.entrySha224.grid(row=6, column=1) self.l_sha256.grid(row=7, sticky=W, padx=5) self.entrySha256.grid(row=7, column=1) self.l_sha384.grid(row=8, sticky=W, padx=5) self.entrySha384.grid(row=8, column=1) self.l_sha512.grid(row=9, sticky=W, padx=5) self.entrySha512.grid(row=9, column=1) self.l_md4.grid(row=10, sticky=W, padx=5) self.entryMd4.grid(row=10, column=1) self.l_ripemd.grid(row=11, sticky=W, padx=5) self.entryRipeMd.grid(row=11, column=1) self.l_whirl.grid(row=12, sticky=W, padx=5) self.entryWhirl.grid(row=12, column=1) self.l_dsa.grid(row=13, sticky=W, padx=5) self.entryDsa.grid(row=13, column=1) self.l_crc32.grid(row=14, sticky=W, padx=5) self.entryCrc.grid(row=14, column=1) self.l_adler32.grid(row=15, sticky=W, padx=5) self.entryAdler.grid(row=15, column=1) # Disable all the Entry fields self.disable_entry() def clean_up(self, event): self.entry.delete(0, END) self.enable_entry() self.clear_fields() self.disable_entry() if self.filename != '': self.filename = '' def toggle_open_btn(self, val): # The method for cleanup self.clean_up(0) self.list_choice = val if val == "Text": self.op_button.grid_forget() if val == "File": self.op_button.grid(row=0, column=1, padx=5, pady=5, sticky=W) def open_box(self): self.clean_up(0) self.filename = filedialog.askopenfilename() self.entry.insert(0, self.filename) def calc_hash(self): if self.list_choice == "File": if os.path.isfile(self.filename): # read() from file as bytes txt = open(self.filename, 'rb').read() else: # No such file, warning self.filename = '' messagebox.showinfo('Error', 'File not found !\n' + self.entry.get()) return elif self.list_choice == "Text": txt = self.entry.get().encode() self.enable_entry() self.clear_fields() print(self.list_choice) # algorithms_guaranteed self.entryMd5.insert(0, hlb.md5(txt).hexdigest()) self.entrySha1.insert(0, hlb.sha1(txt).hexdigest()) self.entrySha224.insert(0, hlb.sha224(txt).hexdigest()) self.entrySha256.insert(0, hlb.sha256(txt).hexdigest()) self.entrySha384.insert(0, hlb.sha384(txt).hexdigest()) self.entrySha512.insert(0, hlb.sha512(txt).hexdigest()) # algorithms_not_guaranteed # Collisions might occur # Using the same object initialized in __init__ method results in unsecured hashes. # So initialize objects each time self.init_insecure_hashes() # ripemd160 self.ripe.update(txt) self.entryRipeMd.insert(0, self.ripe.hexdigest()) # md4 self.md4.update(txt) self.entryMd4.insert(0, self.md4.hexdigest()) # whirlpool self.whirl.update(txt) self.entryWhirl.insert(0, self.whirl.hexdigest()) # dsa self.dsa.update(txt) self.entryDsa.insert(0, self.dsa.hexdigest()) # Starting from index 2 to get rid of the '0x' # crc32 self.entryCrc.insert(0, (8 - len(hex(crc32(txt))[2:])) * '0' + hex(crc32(txt))[2:]) # adler32 self.entryAdler.insert(0, (8 - len(hex(adler32(txt))[2:])) * '0' + hex(adler32(txt))[2:]) self.disable_entry() def clear_fields(self): self.entryMd5.delete(0, END) self.entrySha1.delete(0, END) self.entrySha224.delete(0, END) self.entrySha256.delete(0, END) self.entrySha384.delete(0, END) self.entrySha512.delete(0, END) self.entryRipeMd.delete(0, END) self.entryMd4.delete(0, END) self.entryWhirl.delete(0, END) self.entryDsa.delete(0, END) self.entryCrc.delete(0, END) self.entryAdler.delete(0, END) def init_insecure_hashes(self): self.ripe = hlb.new("ripemd160") self.md4 = hlb.new("md4") self.whirl = hlb.new("whirlpool") self.dsa = hlb.new("dsaEncryption") def disable_entry(self): self.entryMd5.config(state="readonly") self.entryMd4.config(state="readonly") self.entrySha1.config(state="readonly") self.entrySha224.config(state="readonly") self.entrySha256.config(state="readonly") self.entrySha384.config(state="readonly") self.entrySha512.config(state="readonly") self.entryRipeMd.config(state="readonly") self.entryWhirl.config(state="readonly") self.entryDsa.config(state="readonly") self.entryCrc.config(state="readonly") self.entryAdler.config(state="readonly") def enable_entry(self): self.entryMd5.config(state=NORMAL) self.entryMd4.config(state=NORMAL) self.entrySha1.config(state=NORMAL) self.entrySha224.config(state=NORMAL) self.entrySha256.config(state=NORMAL) self.entrySha384.config(state=NORMAL) self.entrySha512.config(state=NORMAL) self.entryRipeMd.config(state=NORMAL) self.entryWhirl.config(state=NORMAL) self.entryDsa.config(state=NORMAL) self.entryCrc.config(state=NORMAL) self.entryAdler.config(state=NORMAL)
window.rowconfigure(5, pad=3) window.rowconfigure(6, pad=3) window.rowconfigure(7, pad=3) #lable to describe choose the csv file label1 = Label(window, text="You can choose a csv file") label1.grid(row=0, column=0, columnspan=2, padx = 10, sticky="w", pady=20) label2 = Label(window, text="Choose your file ...") label2.grid(row=1, column=1) button1 = Button(window, text="Browse", command=clicked_on_browse) button1.grid(row=1, column=2) sep = Separator(window, orient=HORIZONTAL) sep.grid(column=0, row=2,columnspan=8, sticky="ew", pady=20) label3 = Label(window, text="You can enter your process here (in a right format)") label3.grid(row=3, column=1, pady=10) txtFrame = scrolledtext.ScrolledText(window,width=40,height=10) txtFrame.grid(row=4, column=0, columnspan=2, padx=10) exit_button = Button(window, text="Exit", command=window.quit) exit_button.grid(row=5, column=5) ok_button = Button(window, text="Ok", command=send_file_name) ok_button.grid(row=5, column=6, padx=4) window.mainloop()
e3 = Entry(root) e3.grid(row=2, column=1) b3 = Button(root, text="ändern", command=btn_SchuelerHeute) b3.grid(row=2, column=2) l4 = Label(root, text="Verzeichnis Schüler -> MORGEN:") l4.grid(row=3, column=0) e4 = Entry(root) e4.grid(row=3, column=1) b4 = Button(root, text="ändern", command=btn_SchuelerMorgen) b4.grid(row=3, column=2) b5 = Button(root, text="start program", command=btn_start) b5.grid(row=4, column=0, columnspan=3) sep1 = Separator(root, orient=HORIZONTAL) sep1.grid(row=5, column=0, columnspan=3, sticky="ew") l5 = Label(root, text="Result:") l5.grid(row=6, column=0, columnspan=3) text1 = Text(root, width=60, height=10) text1.grid(row=7, column=0, columnspan=3) text1.tag_config('RED', foreground='red') text1.tag_config('GREEN', foreground='green') l6 = Label(root, text="*****@*****.**") l6.grid(row=8, column=0, columnspan=3) # read config file for input fields readConf() # start the GUI
window.title("Anna Du ROV V1.0 Microplastics Image Recognition System") lbl = Label(window, text="Anna Du ROV V1.0 Microplastics Image Recognition System", font=("Arial Bold", 50), bg="cyan") lbl.grid(column=10, row=20) lbls = Label(window, text="Choose An Option Below", font=("Arial Bold", 40), bg="medium orchid") lbls.grid(column=10, row=25, sticky="w") sep = Separator(window, orient="horizontal") sep.grid(column=5, row=23, columnspan=20, sticky="ew") sty = Style(window) sty.configure("TSeparator", background="red") btn = Button(window, command=open2, text="Infrared Comparison Color Mapper", font=("Arial Bold", 25), height=2) btn.grid(column=10, row=30, sticky="w") lblss = Label(window, text="Unnatural Colors", font=("Arial Bold", 40), bg="medium orchid") lblss.grid(column=10, row=35, sticky="w")
def initialize_components(self): """ Method that initialize the visual components for each form associated with the local administration """ # Resources for the Forms self.new_icon = PhotoImage(file=r"./Resources/create.png") self.modify_icon = PhotoImage(file=r"./Resources/modify.png") self.remove_icon = PhotoImage(file=r"./Resources/delete.png") self.save_icon = PhotoImage(file=r"./Resources/save.png") self.cancel_icon = PhotoImage(file=r"./Resources/cancel.png") # Components for List Form lbl_sep1 = Label(self.frm_child_list) lbl_sep1.grid(row=0, column=0, padx=10, pady=25) self.trv_available = Treeview(self.frm_child_list, height=15, columns=('N', 'Name', 'Surname', 'E-mail')) self.trv_available.heading('#0', text='ID', anchor=CENTER) self.trv_available.heading('#1', text='N', anchor=CENTER) self.trv_available.heading('#2', text='Name', anchor=CENTER) self.trv_available.heading('#3', text='Surname', anchor=CENTER) self.trv_available.heading('#4', text='E-mail', anchor=CENTER) self.trv_available.column('#0', width=0, minwidth=50, stretch=NO) self.trv_available.column('#1', width=20, minwidth=20, stretch=NO) self.trv_available.column('#2', width=200, minwidth=200, stretch=NO) self.trv_available.column('#3', width=200, minwidth=200, stretch=NO) self.trv_available.column('#4', width=400, minwidth=400, stretch=NO) self.trv_available.grid(row=0, column=1, sticky=W, pady=25) vsb_trv_av = Scrollbar(self.frm_child_list, orient="vertical", command=self.trv_available.yview) vsb_trv_av.grid(row=0, column=2, pady=25, sticky=NS) self.trv_available.configure(yscrollcommand=vsb_trv_av.set) frm_aux4 = Frame(self.frm_child_list) btn_new = Button(frm_aux4, image=self.new_icon, command=self.click_new) btn_new.grid(row=0, column=0, pady=5, padx=5, sticky=E) btn_new_ttp = CreateToolTip(btn_new, 'New ' + self.title.lower()) btn_edit = Button(frm_aux4, image=self.modify_icon, command=self.click_update) btn_edit.grid(row=1, column=0, pady=5, padx=5, sticky=E) btn_edit_ttp = CreateToolTip(btn_edit, 'Edit ' + self.title.lower()) btn_delete = Button(frm_aux4, image=self.remove_icon, command=self.click_delete) btn_delete.grid(row=2, column=0, pady=5, padx=5, sticky=E) btn_delete_ttp = CreateToolTip(btn_delete, 'Delete ' + self.title.lower()) frm_aux4.grid(row=0, column=3, pady=25, padx=25, sticky=NW) # Components for CRUD FRM lbl_name = Label(self.frm_child_crud, text='Name*') lbl_name.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_name.grid(row=0, column=0, pady=10, padx=20, sticky=W) lbl_surname = Label(self.frm_child_crud, text='Surname*') lbl_surname.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_surname.grid(row=1, column=0, pady=10, padx=20, sticky=W) lbl_email = Label(self.frm_child_crud, text='E-mail*') lbl_email.config(fg=TEXT_COLOR, font=LABEL_FONT) lbl_email.grid(row=2, column=0, pady=10, padx=20, sticky=W) self.lbl_old_passwd = Label(self.frm_child_crud, text='Old password*') self.lbl_old_passwd.config(fg=TEXT_COLOR, font=LABEL_FONT) self.lbl_passwd = Label(self.frm_child_crud, text='New password*') self.lbl_passwd.config(fg=TEXT_COLOR, font=LABEL_FONT) self.lbl_passwd_conf = Label(self.frm_child_crud, text='Confirm new password*') self.lbl_passwd_conf.config(fg=TEXT_COLOR, font=LABEL_FONT) self.txt_name = Entry(self.frm_child_crud) self.txt_name.grid(row=0, column=1, pady=10, padx=20, sticky=W) self.txt_surname = Entry(self.frm_child_crud) self.txt_surname.grid(row=1, column=1, pady=10, padx=20, sticky=W) self.txt_email = Entry(self.frm_child_crud) self.txt_email.grid(row=2, column=1, pady=10, padx=20, sticky=W) self.txt_old_passwd = Entry(self.frm_child_crud, show="*") self.txt_passwd = Entry(self.frm_child_crud, show="*") self.txt_passwd_conf = Entry(self.frm_child_crud, show="*") sep_aux2 = Separator(self.frm_child_crud, orient=VERTICAL) sep_aux2.grid(row=0, column=2, sticky=NS, rowspan=6) frm_aux = Frame(self.frm_child_crud) btn_save = Button(frm_aux, image=self.save_icon, command=self.click_save) btn_save.grid(row=0, column=0, padx=5, pady=5, sticky=E) btn_save_ttp = CreateToolTip(btn_save, 'Save ' + self.title.lower()) btn_cancel = Button(frm_aux, image=self.cancel_icon, command=self.click_cancel) btn_cancel.grid(row=1, column=0, padx=5, pady=5, sticky=E) btn_cancel_ttp = CreateToolTip(btn_cancel, 'Cancel') frm_aux.grid(row=0, column=3, pady=10, padx=25, sticky=N, rowspan=6)
class ResultsFrame(LabelFrame): padY = 5 padX = 30 def __init__(self,parent): LabelFrame.__init__(self, parent,text="Results", width=825, height=485) # Terrible kludgy hack to force the app to stay the right size # Need to work out how to remove self.grid_propagate(False) self.resultsDict = None self.modelType = None self.currentSegment = 0 # Stats frame self.statsFrame = StatsFrame(self, self.padX, self.padY) self.statsFrame.calculate_B.bind("<Button-1>", self._parametersChanged) self.statsFrame.reset_B.bind("<Button-1>", self._parametersReset) def onComboBoxSelect(e): self.currentSegment = e.widget.current() self._updateDisplay(True) self.statsFrame.expSeg_CB.bind("<<ComboboxSelected>>", onComboBoxSelect) # Error frame self.errorSurfaceFrame = ErrorSurfaceFrame(self) self.errorSurfaceFrame.errorSurfaceB.bind("<Button-1>", self._displayErrorSurface) # Graph notebook self.errorSurfaceSeperator = Separator(self,orient=tkinter.HORIZONTAL) self.graphNotebook = ImprovedNotebook(self) self.modelGraphFrame = GraphFrame(self.graphNotebook, dim=2) self.modelGraphFrame.axes.set_ylabel(r'$thickness(m)$') self.regressionGraphFrame = GraphFrame(self.graphNotebook, dim=2) self.regressionGraphFrame.axes.set_ylabel(r'$\log{(thickness(m))}$') self.errorSurfaceGraphFrame = GraphFrame(self.graphNotebook, dim=3) self.errorSurfaceGraphFrame.axes.set_zlabel(r'$error$') self.graphNotebook.addFrame(self.modelGraphFrame, text="Model") def displayNewModel(self, modelType, resultsDict): self.modelType = modelType self.isopachs = resultsDict["isopachs"] self.sqrtAreaKM = [isopach.sqrtAreaKM for isopach in self.isopachs] self.thicknessM = [isopach.thicknessM for isopach in self.isopachs] self.currentParameters = resultsDict self.defaultParameters = deepcopy(self.currentParameters) self.statsFrame.grid(row=0,column=0,padx=10,pady=5,sticky="NESW") self.graphNotebook.grid(row=0,column=1,padx=10, pady=5,sticky="NEW") if self.modelType == Model.EXP: self._displayExp() self.config(text="Results (Exponential)") else: self.errorSurfaceSeperator.grid(row=1, column=0, columnspan=2, padx=20, pady=(20,0), sticky="EW") self.errorSurfaceFrame.grid(row=2, column=0, columnspan=2, padx=10, pady=0, sticky="EW") if self.modelType == Model.POW: self._displayPow() self.config(text="Results (Power law)") elif self.modelType == Model.WEI: self._displayWei() self.config(text="Results (Weibull)") self._updateDisplay(False) def _updateDisplay(self, comboboxUpdate): if not comboboxUpdate: self.modelGraphFrame.clear() self.regressionGraphFrame.clear() thicknessM = [isopach.thicknessM for isopach in self.isopachs] sqrtArea = [isopach.sqrtAreaKM for isopach in self.isopachs] self.modelGraphFrame.plotScatter(sqrtArea,thicknessM,True) self.modelGraphFrame.axes.set_xlabel(r"$\sqrt{Area}$") if self.modelType == Model.EXP: self._updateExp(comboboxUpdate) elif self.modelType == Model.POW: self._updatePow() elif self.modelType == Model.WEI: self._updateWei() def _displayExp(self): fr = self.statsFrame padX = self.padX padY = self.padY fr.expSeg_CB.grid(row=3,column=0,sticky="W",padx=10,pady=padY) vals = ["Segment " + str(i) for i in range(1,self.currentParameters["numberOfSegments"]+1)] fr.expSeg_CB.configure(values=vals) fr.expSeg_CB.current(0) fr.expSegVolume_L.grid(row=4,column=0,padx=10,sticky="W",pady=padY) fr.expSegVolume_E.grid(row=4,column=1,padx=10,sticky="E") fr.equation_L.grid(row=5,column=0,sticky="W",padx=10,pady=padY) fr.equation_E.grid(row=5,column=1,padx=10,sticky="E") fr.equation_L.configure(text="Segment equation:") fr.parameters_L.grid(row=6,column=0,padx=10,pady=padY,sticky="W") fr.expSegStartLimit_L.grid(row=7,column=0,sticky="W",padx=padX,pady=padY) fr.expSegStartLimit_E.grid(row=7,column=1,padx=10,sticky="E") fr.expSegEndLimit_L.grid(row=8,column=0,sticky="W",padx=padX,pady=padY) fr.expSegEndLimit_E.grid(row=8,column=1,padx=10,sticky="E") fr.expSegCoefficent_L.grid(row=9,column=0,sticky="W",padx=padX,pady=padY) fr.expSegCoefficent_E.grid(row=9,column=1,padx=10,sticky="E") fr.expSegExponent_L.grid(row=10,column=0,sticky="W",padx=padX,pady=padY) fr.expSegExponent_E.grid(row=10,column=1,padx=10,sticky="E") # Recalculate buttons fr.calculate_B.grid(row=11,column=0,padx=padX,pady=padY,sticky="W") fr.reset_B.grid(row=11,column=1,padx=10,sticky="E") self.graphNotebook.addFrame(self.regressionGraphFrame, text="Regression") def _displayPow(self): fr = self.statsFrame padX = self.padX padY = self.padY fr.equation_L.grid(row=2,column=0,sticky="W",padx=10,pady=padY) fr.equation_E.grid(row=2,column=1,padx=10,sticky="E") fr.equation_L.configure(text="Equation:") fr.parameters_L.grid(row=3,column=0,padx=10,pady=padY,sticky="W") fr.powCoefficient_L.grid(row=4,column=0,sticky="W",padx=padX,pady=padY) fr.powCoefficient_E.grid(row=4,column=1,padx=10,sticky="E") fr.powExponent_L.grid(row=5,column=0,sticky="W",padx=padX,pady=padY) fr.powExponent_E.grid(row=5,column=1,padx=10,sticky="E") fr.powProximalLimit_L.grid(row=6,column=0,sticky="W",padx=padX,pady=padY) fr.powProximalLimit_E.grid(row=6,column=1,padx=10,sticky="E") fr.powDistalLimit_L.grid(row=7,column=0,sticky="W",padx=padX,pady=padY) fr.powDistalLimit_E.grid(row=7,column=1,padx=10,sticky="E") # Recalculate buttons fr.calculate_B.grid(row=8,column=0,padx=padX,pady=padY,sticky="W") fr.reset_B.grid(row=8,column=1,padx=10,sticky="E") fr.powSuggestedProximalLimit_L.grid(row=9,column=0,sticky="W",padx=10,pady=padY) fr.powSuggestedProximalLimit_E.grid(row=9,column=1,padx=10,sticky="E") self.graphNotebook.addFrame(self.regressionGraphFrame, text="Regression") self.errorSurfaceFrame.update("c", "m", 0.0, 5.0, 0.0, 5.0) def _displayWei(self): fr = self.statsFrame padX = self.padX padY = self.padY fr.equation_L.grid(row=2,column=0,sticky="W",padx=10,pady=padY) fr.equation_E.grid(row=2,column=1,padx=10,sticky="E") fr.equation_L.configure(text="Equation:") fr.parameters_L.grid(row=3,column=0,padx=10,pady=padY,sticky="W") fr.weiLambdaL.grid(row=4,column=0,padx=padX,pady=padY,sticky="W") fr.weiLambdaE.grid(row=4,column=1,padx=10,sticky="E") fr.weiKL.grid(row=5,column=0,padx=padX,pady=padY,sticky="W") fr.weiKE.grid(row=5,column=1,padx=10,sticky="E") fr.weiThetaL.grid(row=6,column=0,padx=padX,pady=padY,sticky="W") fr.weiThetaE.grid(row=6,column=1,padx=10,sticky="E") # Recalculate buttons fr.calculate_B.grid(row=7,column=0,padx=padX,pady=padY,sticky="W") fr.reset_B.grid(row=7,column=1,padx=10,sticky="E") parameterLimits = self.currentParameters["limits"] lambdaLower, lambdaUpper = parameterLimits[0] kLower, kUpper = parameterLimits[1] self.errorSurfaceFrame.update("\u03BB", "k", lambdaLower, lambdaUpper, kLower, kUpper) def _updateExp(self, comboboxUpdate): n = self.currentParameters["numberOfSegments"] coefficients = self.currentParameters["segmentCoefficients"] exponents = self.currentParameters["segmentExponents"] limits = self.currentParameters["segmentLimits"] ########### ## Stats ## ########### fr = self.statsFrame # Segment start start = limits[self.currentSegment] startStr = helper_functions.roundToSF(start, NUMBER_OF_SF) fr.expSegStartLimit_E.insertNew(start) fr.expSegStartLimit_E.setUserEditable(self.currentSegment != 0) # Segment end end = limits[self.currentSegment+1] endStr = helper_functions.roundToSF(end, NUMBER_OF_SF) fr.expSegEndLimit_E.insertNew(end) fr.expSegEndLimit_E.setUserEditable(self.currentSegment != n-1) # Segment coefficient coefficient = coefficients [self.currentSegment] coefficientStr = helper_functions.roundToSF(coefficient, NUMBER_OF_SF) fr.expSegCoefficent_E.insertNew(coefficient) # Segment exponent exponent = exponents[self.currentSegment] exponentStr = helper_functions.roundToSF(exponent, NUMBER_OF_SF) fr.expSegExponent_E.insertNew(exponent) # Segment volume segmentVolumes = [calculateExponentialSegmentVolume(coefficients[i], exponents[i], limits[i], limits[i+1]) for i in range(n)] segmentVolumeStr = helper_functions.roundToSF(segmentVolumes[self.currentSegment], NUMBER_OF_SF) fr.expSegVolume_E.insertNew(segmentVolumeStr) # Total volume totalVolume = sum(segmentVolumes) estimatedTotalVolumeStr = helper_functions.roundToSF(totalVolume, NUMBER_OF_SF) fr.totalEstimatedVolume_E.insertNew(estimatedTotalVolumeStr) # Error def thicknessFunction(x): for i in range(n): if limits[i] <= x < limits[i+1]: return coefficients[i]*math.exp(-exponents[i]*x) error = regression_methods.meanRelativeSquaredError(self.sqrtAreaKM, self.thicknessM, thicknessFunction) errorStr = helper_functions.roundToSF(error, NUMBER_OF_SF) fr.relativeSquaredError_E.insertNew(errorStr) # Equation equationStr = "T = " + coefficientStr if exponent > 0: equationStr += "exp(-" + exponentStr + "x)" elif exponent < 0: equationStr += "exp(" + exponentStr[1:] + "x)" fr.equation_E.insertNew(equationStr) ############ ## Graphs ## ############ if not comboboxUpdate: # Model endXs = limits[1:-1] + [1.5*max(self.sqrtAreaKM)-0.5*min(self.sqrtAreaKM)] for i in range(n): xs = helper_functions.getStaggeredPoints(limits[i], endXs[i], MODEL_PLOTTING_PRECISION) ys = [coefficients[i]*math.exp(-exponents[i]*x) for x in xs] self.modelGraphFrame.plotFilledLine(xs, ys, color=colours[i]) # Regression logThicknessM = [np.log(t) for t in self.thicknessM] self.regressionGraphFrame.plotScatter(self.sqrtAreaKM, logThicknessM, False) self.regressionGraphFrame.axes.set_xlabel(r"$\sqrt{Area}$") for i in range(n): xs = [limits[i], endXs[i]] ys = [np.log(thicknessFunction(x)) for x in xs] self.regressionGraphFrame.plotLine(xs,ys, color=colours[i]) def _updatePow(self): ########### ## Stats ## ########### fr = self.statsFrame # Coefficient c = self.currentParameters["coefficient"] coefficientStr = helper_functions.roundToSF(c, NUMBER_OF_SF) fr.powCoefficient_E.insertNew(c) # Exponent m = self.currentParameters["exponent"] exponentStr = helper_functions.roundToSF(m, NUMBER_OF_SF) fr.powExponent_E.insertNew(m) # Proximal limit proximalLimitKM = self.currentParameters["proximalLimitKM"] proximalLimitStr = helper_functions.roundToSF(proximalLimitKM, NUMBER_OF_SF) fr.powProximalLimit_E.insertNew(proximalLimitKM) # Distal limit distalLimitKM = self.currentParameters["distalLimitKM"] distalLimitStr = helper_functions.roundToSF(distalLimitKM, NUMBER_OF_SF) fr.powDistalLimit_E.insertNew(distalLimitKM) # Volume volume = calculatePowerLawVolume(c, m, proximalLimitKM, distalLimitKM) volumeStr = helper_functions.roundToSF(volume, NUMBER_OF_SF) fr.totalEstimatedVolume_E.insertNew(volumeStr) # Error thicknessFunction = lambda x : c*(x**(-m)) error = regression_methods.meanRelativeSquaredError(self.sqrtAreaKM, self.thicknessM, thicknessFunction) errorStr = helper_functions.roundToSF(error, NUMBER_OF_SF) fr.relativeSquaredError_E.insertNew(errorStr) # Equation equationStr = "T = " + coefficientStr if m > 0: equationStr += "x^-" + exponentStr elif m < 0: equationStr += "x^" + exponentStr[1:] fr.equation_E.insertNew(equationStr) # Suggested proximal limit suggestedProximalLimit = self.currentParameters["suggestedProximalLimit"] suggestedProximalLimitStr = helper_functions.roundToSF(suggestedProximalLimit, NUMBER_OF_SF) fr.powSuggestedProximalLimit_E.insertNew(suggestedProximalLimitStr) ############ ## Graphs ## ############ startX = proximalLimitKM*SQRT_PI endX = distalLimitKM*SQRT_PI # Model xs = helper_functions.getStaggeredPoints(startX, endX, MODEL_PLOTTING_PRECISION) ys = [thicknessFunction(x) for x in xs] self.modelGraphFrame.plotFilledLine(xs, ys, color=colours[0]) # Regression logXs = [np.log(a) for a in self.sqrtAreaKM] logYs = [np.log(t) for t in self.thicknessM] self.regressionGraphFrame.plotScatter(logXs, logYs, False) self.regressionGraphFrame.axes.set_xlabel(r"$\log{\sqrt{Area}}$") lineXs = [np.sqrt(startX), np.sqrt(endX)] lineYs = [np.log(c) - m*x for x in lineXs] self.regressionGraphFrame.plotLine(lineXs, lineYs, colours[0]) def _updateWei(self): ########### ## Stats ## ########### fr = self.statsFrame # lambda lamb = self.currentParameters["lambda"] lambdaStr = helper_functions.roundToSF(lamb, NUMBER_OF_SF) fr.weiLambdaE.insertNew(lamb) # k k = self.currentParameters["k"] kStr = helper_functions.roundToSF(k, NUMBER_OF_SF) fr.weiKE.insertNew(k) # theta theta = self.currentParameters["theta"] thetaStr = helper_functions.roundToSF(theta, NUMBER_OF_SF) fr.weiThetaE.insertNew(theta) # Volume volume = calculateWeibullVolume(lamb, k, theta) volumeStr = helper_functions.roundToSF(volume, NUMBER_OF_SF) fr.totalEstimatedVolume_E.insertNew(volumeStr) # Error thicknessFunction = lambda x : theta*((x/lamb)**(k-2))*math.exp(-((x/lamb)**k)) error = regression_methods.meanRelativeSquaredError(self.sqrtAreaKM, self.thicknessM, thicknessFunction) errorStr = helper_functions.roundToSF(error, NUMBER_OF_SF) fr.relativeSquaredError_E.insertNew(errorStr) # Equation invLambdaStr = helper_functions.roundToSF(1/lamb, NUMBER_OF_SF) kminus2Str = helper_functions.roundToSF(k-2, NUMBER_OF_SF) equationStr = "T = " + thetaStr + "((" + invLambdaStr + "x)^" +kminus2Str + ")exp(-(" + invLambdaStr + "x)^" + kStr + ")" fr.equation_E.insertNew(equationStr) ############ ## Graphs ## ############ # Model startX = 0 endX = (self.isopachs[-1].distanceFromVentKM()+50)*SQRT_PI xs = helper_functions.getStaggeredPoints(startX,endX,MODEL_PLOTTING_PRECISION)[1:] ys = [theta*((x/lamb)**(k-2))*math.exp(-((x/lamb)**k)) for x in xs] self.modelGraphFrame.plotFilledLine(xs, ys, colours[0]) def _displayErrorSurface(self,event): try: xLL, xUL, yLL, yUL, resolution = self.errorSurfaceFrame.getSurfaceParameters() except ValueError as ve: messagebox.showerror("Calculation error", ve.args[0]) return self.graphNotebook.addFrame(self.errorSurfaceGraphFrame, text="Error surface") if self.errorSurfaceFrame.xSymbol == "\u03BB": self.errorSurfaceGraphFrame.axes.set_xlabel("$\lambda$") else: self.errorSurfaceGraphFrame.axes.set_xlabel(self.errorSurfaceFrame.xSymbol) xs = [isopach.sqrtAreaKM for isopach in self.isopachs] ys = [isopach.thicknessM for isopach in self.isopachs] if self.modelType == Model.POW: def errorFunction(c,m): thicknessFunction = lambda x : c*(x**(-m)) return math.log(regression_methods.meanRelativeSquaredError(xs, ys, thicknessFunction)) elif self.modelType == Model.WEI: def errorFunction(lamb,k): theta = calculateTheta(xs,ys,lamb,k) def thicknessFunction(x): try: return np.exp(np.log(theta)+(k-2)*np.log(x/lamb)-(x/lamb)**k) except FloatingPointError: return 0 mrse = regression_methods.meanRelativeSquaredError(xs, ys, thicknessFunction) return math.log(mrse) self.errorSurfaceGraphFrame.axes.set_ylabel(self.errorSurfaceFrame.ySymbol) self.errorSurfaceGraphFrame.clear() self.errorSurfaceGraphFrame.plotSurface(errorFunction, xLL, xUL, yLL, yUL, resolution) self.graphNotebook.select(self.errorSurfaceGraphFrame) def _parametersReset(self,event): self.currentParameters = deepcopy(self.defaultParameters) self._updateDisplay(False) def _parametersChanged(self,event): try: newValues = self.statsFrame.getParameters(self.modelType) except ValueError as ve: messagebox.showerror("Calculation error", ve.args[0]) return if self.modelType == Model.EXP: self.currentParameters["segmentCoefficients"][self.currentSegment] = newValues["c"] self.currentParameters["segmentExponents"][self.currentSegment] = newValues["m"] self.currentParameters["segmentLimits"][self.currentSegment] = newValues["segStart"] self.currentParameters["segmentLimits"][self.currentSegment+1] = newValues["segEnd"] elif self.modelType == Model.POW: self.currentParameters["coefficient"] = newValues["c"] self.currentParameters["exponent"] = newValues["m"] elif self.modelType == Model.WEI: self.currentParameters["lambda"] = newValues["lambda"] self.currentParameters["k"] = newValues["k"] self.currentParameters["theta"] = newValues["theta"] self._updateDisplay(False) def clear(self): if self.modelType is not None: for component in self.statsFrame.components[self.modelType]: component.grid_remove() self.statsFrame.grid_remove() self.graphNotebook.grid_remove() self.errorSurfaceFrame.grid_remove() self.errorSurfaceSeperator.grid_remove() self.config(text="Results") self.modelGraphFrame.clear() self.regressionGraphFrame.clear() self.errorSurfaceGraphFrame.clear() self.graphNotebook.removeFrame(self.regressionGraphFrame) self.graphNotebook.removeFrame(self.errorSurfaceGraphFrame) self.modelType = None
yvar = Label(left, text="y : 0", anchor='w') piDegvar = Label(left, text="piDeg : 0", anchor='w') piDirvar = Label(left, text="piDir : none", anchor='w') Title.pack() xvar.pack() yvar.pack() piDegvar.pack() piDirvar.pack() canvas_width = 315 canvas_height = 208 w = Canvas(left, width=canvas_width, height=canvas_height) w.pack(anchor=SW) updateRect(xvar, yvar, piDegvar, piDirvar) left.grid(column=0, row=0, pady=5, padx=10, sticky='n') sep = Separator(master, orient="vertical") sep.grid(column=1, row=0, sticky="ns") # right hand side should be pixy4 right = Frame(master, width=400, height=400) right.pack_propagate(True) Title2 = Label(right, text='Pixy 4 GUI', anchor='center') xvar2 = Label(right, text="x : 0", anchor='e') yvar2 = Label(right, text="y : 0", anchor='e') piDegvar2 = Label(right, text="piDeg : 0", anchor='e') piDirvar2 = Label(right, text="piDir : none", anchor='e') Title2.pack() xvar2.pack() yvar2.pack() piDegvar2.pack() piDirvar2.pack() w2 = Canvas(right, width=canvas_width, height=canvas_height) w2.pack(anchor=SE)
button_compute_average_scores = tkinter.Button(window, text='计算成绩平均数', command=compute_all_average) button_compute_average_scores.grid(row=0, column=1) button_compute_median_scores = tkinter.Button(window, text='计算成绩中位数', command=compute_all_median) button_compute_median_scores.grid(row=0, column=2) button_show_chinese_details = tkinter.Button(window, text='显示语文详情', command=show_chinese_details) button_show_chinese_details.grid(row=1, column=0) button_show_mathematics_details = tkinter.Button(window, text='显示数学详情', command=show_mathematics_details) button_show_mathematics_details.grid(row=2, column=0) button_show_english_details = tkinter.Button(window, text='显示英语详情', command=show_english_details) button_show_english_details.grid(row=3, column=0) button_show_science_details = tkinter.Button(window, text='显示科学详情', command=show_science_details) button_show_science_details.grid(row=4, column=0) sep = Separator(window, orient=HORIZONTAL) sep.grid(row=5, columnspan=5, sticky=(tkinter.W, tkinter.E)) label_choice_score = tkinter.Label(window, text='选择判断题\n') label_choice_score.grid(row=6, column=1) label_fill_score = tkinter.Label(window, text='填空题\n') label_fill_score.grid(row=6, column=2) label_answer_score = tkinter.Label(window, text='简答题\n') label_answer_score.grid(row=6, column=3) button_read_scores = tkinter.Button(window, text='读入题型答对情况', command=read_question_scores) button_read_scores.grid(row=6, column=0) button_read_scores = tkinter.Button(window, text='智能诊断', command=show_comment) button_read_scores.grid(row=7, column=0) text_comment = tkinter.Text(window, height=5, width=30) #text_comment.config(state=DISABLED)
def toolbar_init(self): frame_toolbar = Frame(self.root) frame_toolbar.grid(column=0, row=0, sticky='nsew') # New file button button_new_file = Button(frame_toolbar, image=self.img_new_file, relief='flat', command=self.new_tab) button_new_file.grid(column=0, row=0, sticky='nsew') Tooltip(button_new_file, 'Create new file') # Open file button button_open = Button(frame_toolbar, image=self.img_open, relief='flat', command=self.open_file) button_open.grid(column=1, row=0, sticky='nsew') Tooltip(button_open, 'Open file') # Save file button button_save = Button(frame_toolbar, image=self.img_save, relief='flat', command=self.save_file) button_save.grid(column=2, row=0, sticky='nsew') Tooltip(button_save, 'Save file') # Separator separator_1 = Separator(frame_toolbar, orient='vertical') separator_1.grid(column=3, row=0, sticky='nsew') # Undo button button_undo = Button(frame_toolbar, image=self.img_undo, relief='flat', command=self.undo) button_undo.grid(column=4, row=0, sticky='nsew') Tooltip(button_undo, 'Undo') # Redo button button_redo = Button(frame_toolbar, image=self.img_redo, relief='flat', command=self.redo) button_redo.grid(column=5, row=0, sticky='nsew') Tooltip(button_redo, 'Redo') # Separator separator_2 = Separator(frame_toolbar, orient='vertical') separator_2.grid(column=6, row=0, sticky='nsew') # Cut button button_cut = Button(frame_toolbar, image=self.img_cut, relief='flat', command=self.cut) button_cut.grid(column=7, row=0, sticky='nsew') Tooltip(button_cut, 'Cut') # Copy button button_copy = Button(frame_toolbar, image=self.img_copy, relief='flat', command=self.copy) button_copy.grid(column=8, row=0, sticky='nsew') Tooltip(button_copy, 'Copy') # Paste button button_paste = Button(frame_toolbar, image=self.img_paste, relief='flat', command=self.paste) button_paste.grid(column=9, row=0, sticky='nsew') Tooltip(button_paste, 'Paste') # Separator separator_3 = Separator(frame_toolbar, orient='vertical') separator_3.grid(column=10, row=0, sticky='nsew') # Search button button_search = Button(frame_toolbar, image=self.img_search, relief='flat', command=self.find) button_search.grid(column=11, row=0, sticky='nsew') Tooltip(button_search, 'Search') # Replace button button_replace = Button(frame_toolbar, image=self.img_replace, relief='flat', command=self.find_and_replace) button_replace.grid(column=12, row=0, sticky='nsew') Tooltip(button_replace, 'Replace') return frame_toolbar