class Table: def __init__(self,columns=[],wname='Table'): self.root = Tk() self.root.title(wname) self.topFrame = Frame(self.root) self.topFrame.pack() self.bottomFrame = Frame(self.root) self.bottomFrame.pack(side='bottom') self.labels = [] self.entries = [] self.columns = list(columns.keys()) for column in self.columns: label = Label(self.topFrame) label.config(text=str(column),font=('Arial',12,'bold')) label.grid(row = 0,column=self.columns.index(column)) ex_label = Label(self.topFrame) ex_label.config(text='Ex: '+str(columns.get(column))) ex_label.grid(row = 1,column=self.columns.index(column)) curr_entry = Entry(self.topFrame, width=20, fg='Black', font=('Arial',14,'normal')) self.entries.append(curr_entry) curr_entry.grid(row = 2,column=self.columns.index(column)) self.button1 = Button(self.bottomFrame, text="Add Another Row", command=self.add_new_row).grid(row=0,column=0) self.button2 = Button(self.bottomFrame, text="Done", command=self.save).grid(row=0,column=2) self.root.mainloop() def add_new_row(self): total_columns,total_rows = self.topFrame.grid_size() for col in range(total_columns): curr_entry = Entry(self.topFrame, width=20, fg='black', font=('Arial',14,'normal')) curr_entry.grid(row=total_rows+1,column=col) self.entries.append(curr_entry) def save(self): total_columns,total_rows = self.topFrame.grid_size() strata = [] for row in range(total_rows): row_data = [str(entry.get()) for entry in self.entries if entry.grid_info()['row'] == row] strata.append(row_data) self.strata = [] for row in strata: if len(row) == total_columns: self.strata.append(row) self.root.destroy() def get_data(self): return self.strata
def fc(cls: type, master: tk.Frame, geom: str = ":", draw: bool = False, *args, **kwargs) -> Union[tk.Frame, Tuple[tk.Frame, Dict[str, int]]]: """Create a widget, set up geometry and adjust master's column/row weights. Geometry string may (not) include any of the following fields: row+span.weight:row+column.weight/gravity :param cls: widget class :param master: master widget to embed :param geom: geometry string :param draw: need to draw :param args: positional arguments tuple for cls() call :param kwargs: named arguments tuple for cls() call """ ret = cls(master, *args, **kwargs) groups = View.re_geom.match(geom or ":").groups() default = 0, 1, 0, master.grid_size()[0], 1, 0, "NEWS" y, wy, dy, x, wx, dx, s = (b if a in ('', None) else a for a, b in zip(groups, default)) geom = { "column": x, "columnspan": int(dx) + 1, "row": y, "rowspan": int(dy) + 1, "sticky": s } master.rowconfigure(y, weight=wy) master.columnconfigure(x, weight=wx) if draw: ret.grid(**geom) return ret else: return ret, geom
class checklist_board(Frame): """Frame containing multiple checkbuttons symbolizing options. Class contains all the options which can be used in optimize and checkbuttons telling if option should be used. Attributes: Checks: Checkboxes telling if box is checked. Entries: Entries containing data used in checked options. Checkbuttons: Actual Checkbuttons """ def __init__(self, master): """Inits the class connecting it to main window. Creates all of checks, checkbuttons and entries, putting them into their places. """ super().__init__(master) self.label = Label(self, text="Options", font=("Arial", 16)) self.label.grid(row=0, column=0) self.checklist_board = Frame(self) self.CAI_maximize_check = IntVar() self.Harmonization_check = IntVar() self.Hidden_STOP_check = IntVar() self.Repeat_remove_check = IntVar() self.Favored_sequences_check = IntVar() self.Forbidden_sequences_check = IntVar() self.Hidden_codons_entry = Entry(self.checklist_board, bd=1, state="disabled") self.Include_sequence_entry = Entry( self.checklist_board, bd=1, state="disabled" ) self.Forbid_sequence_entry = Entry(self.checklist_board, bd=1, state="disabled") self.CAI_checkbutton = Checkbutton( self.checklist_board, onvalue=1, offvalue=0, text="Maximize CAI", variable=self.CAI_maximize_check, ) self.Harmonization_checkbutton = Checkbutton( self.checklist_board, text="Harmonize sequence \n and balance CG", variable=self.Harmonization_check, ) self.Hidden_STOP_checkbutton = Checkbutton( self.checklist_board, text="Erase hidden codons", variable=self.Hidden_STOP_check, command=lambda entry=self.Hidden_codons_entry, var=self.Hidden_STOP_check: self.block_entry( entry, var ), ) self.Repeat_remove_checkbutton = Checkbutton( self.checklist_board, text="Remove repeating bases", variable=self.Repeat_remove_check, ) self.Favored_sequences_checkbutton = Checkbutton( self.checklist_board, text="Include sequence", variable=self.Favored_sequences_check, command=lambda entry=self.Include_sequence_entry, var=self.Favored_sequences_check: self.block_entry( entry, var ), ) self.Forbidden_sequences_checkbutton = Checkbutton( self.checklist_board, text="Forbid sequence", variable=self.Forbidden_sequences_check, command=lambda: self.block_entry( self.Forbid_sequence_entry, self.Forbidden_sequences_check ), ) self.CAI_checkbutton.grid(row=0, column=0, sticky="w") self.Harmonization_checkbutton.grid(row=1, column=0, sticky="w") self.Hidden_STOP_checkbutton.grid(row=0, column=1, sticky="w") self.Hidden_codons_entry.grid(row=0, column=1, sticky="s") self.Repeat_remove_checkbutton.grid(row=1, column=1, sticky="w") self.Favored_sequences_checkbutton.grid(row=0, column=2, sticky="w") self.Include_sequence_entry.grid(row=0, column=2, sticky="s") self.Forbidden_sequences_checkbutton.grid(row=1, column=2, sticky="w") self.Forbid_sequence_entry.grid(row=1, column=2, sticky="s") col_count, row_count = self.checklist_board.grid_size() for col in range(col_count): self.checklist_board.grid_columnconfigure(col, minsize=150) for row in range(row_count): self.checklist_board.grid_rowconfigure(row, minsize=65) self.checklist_board.grid(row=1, column=0) def block_entry(self, entry, var): """Defines if entry should be blocket based on check""" if var.get() == 0: entry.configure(state="disabled") else: entry.configure(state="normal") def get_forbidden(self): """Takes data from forbidden entry""" return self.Forbid_sequence_entry.get().replace("T", "U").split(", ") def get_favored(self): """Takes the data from include entry""" return self.Include_sequence_entry.get().replace("T", "U").split(", ") def get_hidden(self): """Takes the data form hidden entry""" return self.Hidden_codons_entry.get().replace("T", "U").split(", ")
class BasicCalendar(Frame): def __init__(self,parent,month=None,mode=0): super().__init__(parent) self.month = month if self.month is None: print('Month is None') self.month = Month(Date.today().year,Date.today().month) self.mode=mode self.active=False self._container_days = [] self.clicked_day=None self.padx_frame = 20 self.pady_frame = 10 self.padx=1 self.pady=1 self.calendar_month_frame=Frame(parent) self.calendar_month_frame.grid(column=0,row=0, padx=self.padx_frame,pady=self.pady_frame,rowspan=25, sticky='N') #rowspan anpassen parent.grid_rowconfigure(0,minsize=100) #header self.button_former_month = Button(self.calendar_month_frame,text='<',command=self.goto_previous_month,relief='flat') self.month_heading = Label(self.calendar_month_frame,font=Fonts.hel_10) self.button_next_month = Button(self.calendar_month_frame,text='>',command=self.goto_next_month,relief='flat') self.button_former_month.grid(column=0,row=0,padx=self.padx,pady=self.pady,sticky='nsew') self.month_heading.grid(column=1,row=0,padx=self.padx,pady=self.pady,columnspan=5,sticky='nsew') self.button_next_month.grid(column=6,row=0,padx=self.padx,pady=self.pady,sticky='nsew') #days weekday_labels=[] for weekday in ['Mo','Di','Mi','Do','Fr','Sa','So']: weekday_labels.append(Label(self.calendar_month_frame, text=weekday, font=Fonts.hel_8_b)) for column,weekday in enumerate(weekday_labels): weekday.grid(column=column,row=1,padx=self.padx,pady=self.pady,sticky='nsew') self.draw_container_days() self.update_displayed_month() @property def get_clicked_day(self): for day in self.days: if day.was_double_clicked: return day.day return False @property def days(self): days=[] for week in self._container_days: for day in week: days.append(day) return days def goto_next_month(self): self.month = self.month.next() self.update_displayed_month() def goto_previous_month(self): self.month = self.month.previous() self.update_displayed_month() def update_displayed_month(self): self.month_heading['text']=f"{self.month.name} {self.month.year}" self.update_display_days(self.month.calendardays) def position_widget_list(self,widget_list, column=0): for row,widget in enumerate(widget_list): widget.grid(column=column, row=row, padx=self.padx, pady=self.pady,sticky='nsew') def draw_container_days(self): self._container_days = [] for x in range(6): line = [] for y in range(7): line.append(CalendarDay(self.calendar_month_frame,mode=self.mode)) self._container_days.append(line) self.position_container_days(self._container_days,self.calendar_month_frame,row_offset=2) def position_container_days(self,widget_list, master=None, row_offset=0): for row,widgetline in enumerate(widget_list): for column,widget in enumerate(widgetline): widget.grid(column=column, row=row+row_offset, padx=self.padx, pady=self.pady,sticky='nsew') if master: master.grid_rowconfigure(row,weight=1) def update_display_days(self,days): unpositioned_weeks=[] for container_week in self._container_days: unpositioned_week = [] for container_day in container_week: if days: container_day.change_day(days[0].number) container_day.change_textcolor(days[0].color) del days[0] if not container_day.grid_info(): unpositioned_week.append(container_day) else: container_day.grid_forget() unpositioned_weeks.append(unpositioned_week) self.position_container_days(unpositioned_weeks,self.calendar_month_frame,row_offset=self.calendar_month_frame.grid_size()[1]) def clear_days(self, startitem=0): count = 0 for slave in self.calendar_month_frame.grid_slaves(): if type(slave) == CalendarDay: count+=1 if count>startitem: slave.forget() def popup(self, event): self.menu_food.tk_popup(event.x_root, event.y_root) self.print_found_foods()
class Tagging(Frame): def __init__(self, parent, options): if options == None: options = {} DefaultOptions = {'colorspace':'RGB', 'K':6, 'km_init':'first', 'verbose':False, 'single_thr':0.6, 'metric':'basic'} for op in DefaultOptions: if not op in options: options[op] = DefaultOptions[op] self.options = options self.K_ant = 0 self.num_im=-1 Frame.__init__(self, parent) self.parent = parent self.parent.title("TAGGING") self.F1 = Frame(parent, width=150,borderwidth=2,relief=GROOVE) self.F2 = Frame(parent, width=150,borderwidth=2,relief=GROOVE) self.F3 = Frame(parent) self.F4 = Frame(parent,borderwidth=2,relief=GROOVE) self.F5 = Frame(parent,borderwidth=2,relief=GROOVE) self.F1.pack(side=LEFT, fill=Y, pady = 4, padx=4) self.F2.pack(side=LEFT, fill=Y, pady = 4) self.F3.pack(side=TOP, expand=True, fill=BOTH, pady = 4, padx = 4) self.F4.pack(side=TOP, fill=BOTH, expand=0, padx = 4) self.F5.pack(side=BOTTOM, fill=BOTH, expand=0, pady = 4, padx = 4) self.F1.pack_propagate(0) self.F2.pack_propagate(0) self.F3.pack_propagate(0) lbl = Label(self.F1, text="Groundtruth") lbl.grid(row=0,sticky=W) Frame(self.F1,borderwidth=1,relief=GROOVE,height=2).grid(row=1,sticky=W) lbl = Label(self.F2, text="Detected") lbl.grid(row=0,sticky=W, columnspan=2) Frame(self.F2,borderwidth=1,relief=GROOVE,height=2).grid(row=1,sticky=W, columnspan=2) self.filename = Button(self.F3,text="filename",command=self.ChooseFile) self.filename.pack(side=TOP,expand=0) # #matplotlib setup # plt.ion() self.figure=plt.figure(figsize=(2,2), frameon=False) self.axes=self.figure.add_subplot(111) self.Canvas=FigureCanvasTkAgg(self.figure, master=self.F3) # self.Canvas.show() self.Canvas.get_tk_widget().pack(side=TOP,fill=BOTH,expand=1 ) plt.axis('off') b = Button(self.F4,text=" <<<10 ",command=self.PreviousFast) b.pack(side=LEFT, padx=(20,2), pady=3) b = Button(self.F4,text=" <<1 ",command=self.Previous) b.pack(side=LEFT, pady=3) self.im_name = Button(self.F4,text="image",bd=0, command=self.Results) self.im_name.pack(side=LEFT, expand=True) b = Button(self.F4,text=" 1>> ",command=self.Next) b.pack(side=LEFT) b = Button(self.F4,text=" 10>>> ",command=self.NextFast) b.pack(side=LEFT, padx=(2,20)) F51 = Frame(self.F5) F52 = Frame(self.F5) F53 = Frame(self.F5) F51.pack(fill=BOTH, expand=1, side=LEFT) Frame(self.F5,borderwidth=1,relief=GROOVE,width=2).pack(side=LEFT, fill=Y) F52.pack(fill=BOTH, expand=1, side=LEFT) Frame(self.F5,borderwidth=1,relief=GROOVE,width=2).pack(side=LEFT, fill=Y) F53.pack(fill=BOTH, expand=1, side=LEFT) Label(F51, text="Color space").pack() Frame(F51,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) Label(F52, text="K-Means").pack() Frame(F52,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) Label(F53, text="Labelling").pack() Frame(F53,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) self.ColorMode = StringVar() self.ColorMode.set(self.options[COLORSSPACE['key']]) for text, mode in COLORSSPACE['options_gui']: b = Radiobutton(F51, text=text, variable=self.ColorMode, value=mode, command=self.Results) b.pack(anchor=W) Frame(F51,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) Label(F51, text="Grouping", padx=20).pack() Frame(F51,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) self.Group = BooleanVar() self.Group.set(True) b = Checkbutton(F51, text='Group same label colors', variable=self.Group, command=self.Results) b.pack(anchor=W) F521 = Frame(F52) F522 = Frame(F52) F521.pack(fill=BOTH) F522.pack(fill=BOTH) # F523 = Frame(F52) # F523.pack(fill=BOTH) self.K = StringVar() self.K.set(self.options['K']) # f = Frame(F52) # f.pack(side=TOP, fill=BOTH, expand=0) Label(F521, text="K : ").pack(side=LEFT) Entry(F521, textvariable=self.K, width=3, justify=CENTER).pack(side=LEFT, padx=4) # Label(F52, text="Init", padx=20).pack(anchor=W) # Frame(F521,borderwidth=1,relief=GROOVE,width=2).pack(side=RIGHT, fill=Y, padx=2) self.Fitting = StringVar() self.Fitting.set(self.options[FITTING['key']]) # f = Frame(F52) # f.pack(side=RIGHT, fill=BOTH, expand=0) for text, mode in FITTING['options_gui']: b = Radiobutton(F521, text=text, variable=self.Fitting, value=mode, command=self.Results) b.pack(anchor=W,padx=4) Frame(F522,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) Label(F522, text="Centroid Init", padx=20).pack() Frame(F522,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) # IM = [('First points','first'),('Randomize', 'random'),('Distribtued','distributed'),('Other','Other')] self.KMInit = StringVar() self.KMInit.set(self.options[CENTROIDSINIT['key']]) for text, mode in CENTROIDSINIT['options_gui']: b = Radiobutton(F522, text=text, variable=self.KMInit, value=mode, command=self.Results) b.pack(anchor=W) self.Thr = StringVar() self.Thr.set(self.options['single_thr']) f = Frame(F53) f.pack(side=TOP, fill=BOTH, expand=0) Label(f, text="single\nbasic >\ncolor", justify=LEFT).pack(side=LEFT) Entry(f, textvariable=self.Thr, width=4, justify=CENTER).pack(side=LEFT) # self.Synonymous = BooleanVar() # self.Synonymous.set(self.options['synonyms']) # b = Checkbutton(F53, text='Synonymous', variable=self.Synonymous, command=self.Results) # b.pack(anchor=W) Frame(F53,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) Label(F53, text="Similarity Metric", padx=2).pack() Frame(F53,borderwidth=1,relief=GROOVE,height=2).pack(fill=X) self.Metric = StringVar() self.Metric.set(self.options[SIMILARITY['key']]) for text, mode in SIMILARITY['options_gui']: b = Radiobutton(F53, text=text, variable=self.Metric, value=mode, command=self.Results) b.pack(anchor=W) def ChooseFile(self): filename = filedialog.askopenfilename(initialdir='Images', filetypes=[("Text files","*.txt")]) if filename =='': return self.ImageFolder = os.path.dirname(filename) self.filename['text'] = os.path.basename(filename) self.GT = lb.loadGT(filename) self.num_im = 0 self.Results() def Previous(self): self.num_im -= 1 if self.num_im<-1: self.num_im=0 elif self.num_im<0: self.num_im=0 return self.Results() def PreviousFast(self): self.num_im -= 10 if self.num_im<0: self.num_im=0 self.Results() def Next(self): self.num_im += 1 if self.num_im>=len(self.GT): self.num_im=len(self.GT)-1 return self.Results() def NextFast(self): self.num_im += 10 if self.num_im>=len(self.GT): self.num_im=len(self.GT)-1 self.Results() def Results(self): if self.num_im<0 or self.num_im>=len(self.GT): return #self.parent.config(cursor="wait") self.parent.update() self.im_name['text'] = self.GT[self.num_im][0] im = io.imread(self.ImageFolder+"/"+self.GT[self.num_im][0]) self.options['K'] = int(self.K.get()) self.options['single_thr'] = float(self.Thr.get()) # self.options['synonyms'] = self.Synonymous.get() self.options[COLORSSPACE['key']] = self.ColorMode.get() self.options[CENTROIDSINIT['key']] = self.KMInit.get() self.options[SIMILARITY['key']] = self.Metric.get() self.options[FITTING['key']] = self.Fitting.get() if self.options['fitting'] != 'None': if self.K_ant==0: self.K_ant = self.options['K'] self.options['K'] = 0 self.K.set(0) pass else: if self.K_ant>0: self.K.set(self.K_ant) self.options['K'] = self.K_ant self.K_ant = 0 self.labels, self.which, self.km = lb.processImage(im, self.options) if self.options['K'] == 0: self.K.set(self.km.K) if not self.Group.get(): self.labels = [w for ww in [[w]*len(z) for w,z in zip(self.labels,self.which)] for w in ww] self.which = [[w] for ww in self.which for w in ww] # get percentages for every label percent = np.zeros((len(self.which),1)) for i,w in enumerate(self.which): for k in w: percent[i] += np.sum(self.km.clusters==k) percent = percent*100/self.km.clusters.size # get color for every label from image sh = im.shape; im = np.reshape(im, (-1, im.shape[2])) colors = np.zeros((len(self.which),3)) for i,w in enumerate(self.which): for k in [w[0]]: colors[i] += np.mean(im[self.km.clusters==k,:],0) colors[i] /= len(w) im = np.reshape(im, sh) self.im = im self.CBgt = self.CreateCheckList(self.F1, self.GT[self.num_im][1]) self.CBdetected = self.CreateCheckList(self.F2, self.labels, percent, colors) l = Label(self.F2,text='similarity: '+'%.2f' % (lb.similarityMetric(self.labels, self.GT[self.num_im][1], self.options)*100)+'%') l.grid(columnspan=2,sticky=W+E+N+S) self.F2.grid_rowconfigure(self.F2.grid_size()[1]-1, weight=1) self.CheckLabels() #self.parent.config(cursor="") self.parent.update() self.Segment() # self.ShowImage(im) def Segment(self): all_widgetes = self.F2.winfo_children() cb = [w for w in all_widgetes if w.winfo_class() == 'Checkbutton'] lab_colors = np.zeros((len(cb),3)) for i,c in enumerate(cb): lab_colors[i,0] = int(c.cget('bg')[1:3], 16) lab_colors[i,1] = int(c.cget('bg')[3:5], 16) lab_colors[i,2] = int(c.cget('bg')[5:7], 16) ims = np.empty_like(self.im) ims = np.reshape(ims, (-1, ims.shape[2])) for i,w in enumerate(self.which): for k in w: ims[self.km.clusters==k]=lab_colors[i] ims = np.reshape(ims, self.im.shape) self.ShowImage(np.hstack((ims,self.im))) def ShowImage(self,im): self.axes.imshow(im) plt.axis('off') self.Canvas.draw() def CreateCheckList(self, frame, labels, values=None, colors=None): all_widgetes = [w for w in frame.winfo_children() if w.winfo_class() == 'Checkbutton'] for w in all_widgetes: w.destroy() all_widgetes = [w for w in frame.winfo_children() if w.winfo_class() == 'Label'] for w in all_widgetes[1:]: w.destroy() var = [] if values is not None: add_text = ["%5.1f" % (values[i]) +'%' for i in range(len(values))] for i in range(len(labels)): var.append(BooleanVar()) fgc = "black" if colors is not None: mycolor = '#%02x%02x%02x' % (int(colors[i,0]), int(colors[i,1]), int(colors[i,2])) if (colors[i,0]+colors[i,1]+colors[i,2])/3/255<=0.5: fgc = "#FFFFFF" else: mycolor = frame.cget('bg') cb = Checkbutton(frame, text=labels[i], state=DISABLED, variable=var[i], bg=mycolor, disabledforeground=fgc, anchor=W) # cb.pack(anchor=W, fill=X, padx=2) cb.grid(row=i+2,column=0,sticky=W+E) if values is not None: cb = Label(frame, text=add_text[i], bg=mycolor, fg=fgc, anchor=E) cb.grid(row=i+2,column=1,sticky=W+E+N+S) frame.grid_rowconfigure(i+2, weight=0) return var def CheckLabels(self): for i in range(len(self.labels)): if self.labels[i] in self.GT[self.num_im][1]: self.CBdetected[i].set(True) for i in range(len(self.GT[self.num_im][1])): if self.GT[self.num_im][1][i] in self.labels: self.CBgt[i].set(True)
class PlatformFrame(Frame): '''Controls widgets relating to a particular Ad Platform''' def __init__(self, *args, name, row, init_states=None, **kwargs): super().__init__(*args, **kwargs) self.configure(bg='grey') self.columnconfigure((0, 1), weight=1) self.name = name # Whether it is needed to display additional Client ID column self.has_client_id = True if name in ['Facebook', 'MyTarget' ] else False self.DEL_BTN_COL = 10 # Frame with Platform Name self.name_frame = Frame(self) Label(self.name_frame, text=self.name, padx=2, pady=2).pack(padx=2, pady=2, expand=True) self.name_frame.grid(row=0, column=0, sticky='nsew', padx=2) # Frame with Campaign Rows self.rows_frame = Frame(self) ColumnRow(self.rows_frame, self.has_client_id) self.campaigns = OrderedDict() if init_states: for i, init_state in enumerate(init_states): self.campaigns[i + 1] = Row(self.rows_frame, i + 1, self.has_client_id, init_state=init_state) Button(self.rows_frame, text='Удалить', command=lambda x=i + 1: self.delete_row(x)).grid( row=i + 1, column=self.DEL_BTN_COL) Button(self.rows_frame, text=f'Добавить кампанию {self.name}', command=self.append_row).grid(row=1 + len(self.campaigns), column=0, columnspan=self.DEL_BTN_COL, sticky="nsew", pady=2) self.rows_frame.grid(row=0, column=1, sticky="nsew") # Gridding Frames immedeately on initialization self.grid(row=row, column=0, sticky="nsew", pady=2, padx=2) def append_row(self): ''' Creates data container and widgets for newly added campaign row ''' logger.info(f"Appending row to {self.name}") last_key = next(reversed(self.campaigns)) if self.campaigns else 0 columns, rows = self.rows_frame.grid_size() if rows - 1 == last_key + 1: self.rows_frame.grid_slaves(row=last_key + 1, column=0)[0].grid_forget() self.campaigns[last_key + 1] = Row(self.rows_frame, last_key + 1, self.has_client_id) Button(self.rows_frame, text='Удалить', command=lambda x=last_key + 1: self.delete_row(x)).grid( row=last_key + 1, column=self.DEL_BTN_COL) if rows - 1 == last_key + 1: Button(self.rows_frame, text=f'Добавить кампанию {self.name}', command=self.append_row).grid(row=last_key + 2, column=0, columnspan=self.DEL_BTN_COL, sticky="nsew", pady=2) def delete_row(self, row): ''' Deletes data container and widgets for unnecessary campaign row ''' logger.info(f"Deleting {row} row in {self.name} block") self.campaigns[row].forget() self.rows_frame.grid_slaves(row=row, column=self.DEL_BTN_COL)[0].grid_forget() self.campaigns.pop(row) def get(self): ''' Collects data from all Platforms rows ''' return {self.name: [self.campaigns[i].get() for i in self.campaigns]}
class Dayview(Frame): ''' Todo's: * Breite fixieren * Tag mit Scrollbar versehen (siehe Suche) * food_drop_event ''' def __init__(self, parent, date): super().__init__(parent) self._date = date self._today = Day(self._date) locale.setlocale(locale.LC_ALL, "") #self.grid() self.dayframe = Frame(self, background=Fonts.action_bg) self.dayframe.grid(column=0, row=0, padx=Fonts.framedistance, pady=Fonts.framedistance) # headline self.headline = Frame( self.dayframe, background='gainsboro') #todo edit color and add to Fonts self.heading = Label(self.headline, text='', font=Fonts.hel_11_b, bg=self.headline['background']) self.btn_previous = Button(self.headline, text='<', command=self.previous_day, relief='flat', bg=self.headline['background']) self.btn_next = Button(self.headline, text='>', command=self.next_day, relief='flat', bg=self.headline['background']) self.headline.grid(row=0, column=0, padx=Fonts.table_cell_distance, pady=(Fonts.table_cell_distance, 0), sticky='nsew') #columnspan self.heading.grid(row=0, column=1, sticky='nsew') self.btn_previous.grid(row=0, column=0) self.btn_next.grid(row=0, column=2) self.headline.columnconfigure(1, weight=1) # table self.table_entries = Frame(self.dayframe, background=Fonts.table_bg) self.table_entries.grid(row=1, column=0, padx=Fonts.table_cell_distance, pady=(0, Fonts.table_cell_distance), sticky='nsew') header = ['Name', 'Menge', 'kCal'] for col, columnheader in enumerate(header): temp_label = Label( self.table_entries, text=columnheader, font=Fonts.hel_8_b ) #todo später eigene Klasse, um Filtern zu ermöglichen temp_label.grid(column=col, row=0, padx=1, pady=1, sticky='nswe') self.update_day_view() def add(self, foods): for food in foods: Amount(self, food) self._today.add(food) self.update_day_view() def update_day_view(self): self.heading['text'] = self._date.strftime('%A %d. %B %Y') self._today = Day(self._date) self.delete_former_food_entries() self.draw_food_entries() def draw_food_entries(self): for row, entry in enumerate(self._today.food_entries): temp_row = [] temp_row.append( Label(self.table_entries, text=entry.name, anchor='w')) temp_row.append(Label(self.table_entries, text=entry.amount)) temp_row.append(Label(self.table_entries, text=entry.calories)) self.draw_food_entry_line(temp_row, row + 1) sum_name = Label(self.table_entries, text='GESAMT', bg=self.headline['background']) sum_amount = Label(self.table_entries, text='', bg=self.headline['background']) sum_calories = Label(self.table_entries, text=self._today.calories, bg=self.headline['background']) self.draw_food_entry_line([sum_name, sum_amount, sum_calories], self.table_entries.grid_size()[1]) self.table_entries.grid_columnconfigure(1, weight=1) self.table_entries.grid_columnconfigure(2, weight=1) def draw_food_entry_line(self, widgetlist, row_offset): for col, widget in enumerate(widgetlist): widget.grid(column=col, row=row_offset, padx=1, pady=1, sticky='nswe') def next_day(self): self._date += timedelta(days=1) self.update_day_view() def previous_day(self): self._date -= timedelta(days=1) self.update_day_view() def delete_former_food_entries(self): for element in self.table_entries.grid_slaves(): if int(element.grid_info()["row"]) > 0: element.grid_forget()
class UBXConfigDialog: """, UBXConfigDialog class. """ def __init__(self, app, *args, **kwargs): # pylint: disable=unused-argument """ Constructor. :param Frame app: reference to main tkinter application :param args: optional args to pass to parent class (not currently used) :param kwargs: optional kwargs to pass to parent class (not currently used) """ self.__app = app # Reference to main application class self.__master = self.__app.get_master() # Reference to root class (Tk) self._dialog = Toplevel() self._dialog.transient(self.__app) self._dialog.resizable(False, False) self._dialog.title = DLGUBXCONFIG # wd, hd = self.get_size() wd, hd = 750, 470 wa = self.__master.winfo_width() ha = self.__master.winfo_height() self._dialog.geometry("+%d+%d" % (int(wa / 2 - wd / 2), int(ha / 2 - hd / 2))) self._img_exit = ImageTk.PhotoImage(Image.open(ICON_EXIT)) self._cfg_msg_command = None self._pending_confs = { UBX_MONVER: (), UBX_MONHW: (), UBX_CFGPRT: (), UBX_CFGMSG: (), UBX_CFGVAL: (), UBX_PRESET: (), UBX_CFGRATE: (), } self._status = StringVar() self._status_cfgmsg = StringVar() self._body() self._do_layout() self._reset() def _body(self): """ Set up frame and widgets. """ self._frm_container = Frame(self._dialog, borderwidth=2, relief="groove") self._lbl_title = Label( self._frm_container, text=LBLUBXCONFIG, bg=BGCOL, fg=FGCOL, justify=LEFT, font=self.__app.font_md, ) self._frm_status = Frame(self._frm_container, borderwidth=2, relief="groove") self._lbl_status = Label(self._frm_status, textvariable=self._status, anchor="w") self._btn_exit = Button( self._frm_status, image=self._img_exit, width=50, fg="red", command=self._on_exit, font=self.__app.font_md, ) # add configuration widgets self._frm_device_info = UBX_INFO_Frame(self.__app, self, borderwidth=2, relief="groove") self._frm_config_port = UBX_PORT_Frame(self.__app, self, borderwidth=2, relief="groove") self._frm_config_rate = UBX_RATE_Frame(self.__app, self, borderwidth=2, relief="groove") self._frm_config_msg = UBX_MSGRATE_Frame(self.__app, self, borderwidth=2, relief="groove") self._frm_configdb = UBX_CFGVAL_Frame(self.__app, self, borderwidth=2, relief="groove") self._frm_preset = UBX_PRESET_Frame(self.__app, self, borderwidth=2, relief="groove") def _do_layout(self): """ Position widgets in frame. """ # top of grid col = 0 row = 0 self._frm_container.grid( column=col, row=row, columnspan=12, rowspan=22, padx=3, pady=3, ipadx=5, ipady=5, sticky=(N, S, W, E), ) self._lbl_title.grid(column=col, row=row, columnspan=12, ipadx=3, sticky=(W, E)) # left column of grid rowsp = 1 for frm in ( self._frm_device_info, self._frm_config_port, self._frm_config_rate, self._frm_config_msg, ): row += rowsp (colsp, rowsp) = frm.grid_size() frm.grid( column=col, row=row, columnspan=colsp, rowspan=rowsp, sticky=(N, S, W, E), ) # right column of grid row = 0 rowsp = 1 col += colsp for frm in (self._frm_configdb, self._frm_preset): row += rowsp (colsp, rowsp) = frm.grid_size() frm.grid( column=col, row=row, columnspan=colsp, rowspan=rowsp, sticky=(N, S, W, E), ) # bottom of grid col = 0 row += rowsp (colsp, rowsp) = self._frm_container.grid_size() self._frm_status.grid(column=col, row=row, columnspan=colsp, sticky=(W, E)) self._lbl_status.grid(column=0, row=0, columnspan=colsp - 1, ipadx=3, ipady=3, sticky=(W, E)) self._btn_exit.grid(column=colsp - 1, row=0, ipadx=3, ipady=3, sticky=(E)) for frm in (self._frm_container, self._frm_status): for i in range(colsp): frm.grid_columnconfigure(i, weight=1) for i in range(rowsp): frm.grid_rowconfigure(i, weight=1) self._frm_container.option_add("*Font", self.__app.font_sm) self._frm_status.option_add("*Font", self.__app.font_sm) def _reset(self): """ Reset configuration widgets. """ self._frm_config_rate.reset() self._frm_config_port.reset() self._frm_device_info.reset() def set_pending(self, key: int, val: list): """ Set pending confirmation flag for configuration widget to signify that it's waiting for a confirmation message. :param int key: integer representing UBX configuration widget (0-6) :param list val: list of confirmation messages that widget is awaiting """ self._pending_confs[key] = val def update_pending(self, cfgtype, **kwargs): """ Receives polled confirmation message from the ubx_handler and updates the widget that is waiting for this confirmation. :param str cfgtype: identity of UBX message containing config info :param kwargs: status keywords and values from UBX config message """ for (key, val) in self._pending_confs.items(): if cfgtype in val: self.set_status( f"{cfgtype} GET message received", "red" if cfgtype == "ACK-NAK" else "green", ) self._pending_confs[key] = () # reset awaiting conf flag if key == UBX_MONVER: self._frm_device_info.update_status(cfgtype, **kwargs) elif key == UBX_MONHW: self._frm_device_info.update_status(cfgtype, **kwargs) elif key == UBX_CFGPRT: self._frm_config_port.update_status(cfgtype, **kwargs) elif key == UBX_CFGRATE: self._frm_config_rate.update_status(cfgtype, **kwargs) elif key == UBX_CFGMSG: self._frm_config_msg.update_status(cfgtype, **kwargs) elif key == UBX_CFGVAL: self._frm_configdb.update_status(cfgtype, **kwargs) elif key == UBX_PRESET: self._frm_preset.update_status(cfgtype, **kwargs) def set_status(self, message: str, color: str = "blue"): """ Set status message. :param str message: message to be displayed :param str color: rgb color of text (blue) """ message = (message[:120] + "..") if len(message) > 120 else message self._lbl_status.config(fg=color) self._status.set(" " + message) def _on_exit(self, *args, **kwargs): # pylint: disable=unused-argument """ Handle Exit button press. """ self.__master.update_idletasks() self.__app.dlg_ubxconfig = None self._dialog.destroy() def get_size(self): """ Get current frame size. :return: window size (width, height) :rtype: tuple """ self.__master.update_idletasks( ) # Make sure we know about any resizing return (self._dialog.winfo_width(), self._dialog.winfo_height()) @property def container(self): """ Getter for container frame. :return: reference to container frame :rtype: tkinter.Frame """ return self._frm_container