class ManagerItem(Frame): def __init__(self, master, note_data, toggle_visibility_cmd): Frame.__init__(self, master, class_='ManagerItem', style='manager.TFrame') self.columnconfigure(0, weight=0, minsize=18) self.columnconfigure(1, weight=1, minsize=198) self.columnconfigure(2, weight=1, minsize=198) self.columnconfigure(3, weight=0, minsize=85) self.columnconfigure(4, weight=0, minsize=22) self.toggle_visibility_cmd = toggle_visibility_cmd title = note_data['title'] if title: title = title[:17] + (len(title) > 17) * '...' title = title.replace('\t', ' ') date = note_data.get('date', '??') txt = note_data['txt'].splitlines() if txt: txt = txt[0][:17] + (len(txt[0]) > 17 or len(txt) > 1) * '...' else: txt = '' txt = txt.replace('\t', ' ') self._data = {'title': title, 'text': txt, 'date': date} self.title = Label(self, text=title, anchor='w', style='manager.TLabel') self.text = Label(self, text=txt, anchor='w', style='manager.TLabel') self.date = Label(self, text=date, anchor='center', style='manager.TLabel') self.checkbutton = Checkbutton(self, style='manager.TCheckbutton') self.visibility = BooleanVar(self, note_data['visible']) self.toggle_visibility = Checkbutton(self, style='manager.Toggle', variable=self.visibility, command=self.toggle_visibility) self.checkbutton.grid(row=0, column=0, padx=(2, 0), pady=4, sticky='nsew') self.title.grid(row=0, column=1, padx=4, pady=4, sticky='ew') self.text.grid(row=0, column=2, padx=4, pady=4, sticky='ew') self.date.grid(row=0, column=3, padx=4, pady=4, sticky='ew') self.toggle_visibility.grid(row=0, column=4, padx=(0, 2), pady=4, sticky='wens') self.bind('<Enter>', self._on_enter) self.bind('<Leave>', self._on_leave) self.checkbutton.bind('<Enter>', self._on_enter) # override class binding self.checkbutton.bind('<Leave>', self._on_leave) # override class binding self.toggle_visibility.bind('<Enter>', self._on_enter) # override class binding self.toggle_visibility.bind('<Leave>', self._on_leave) # override class binding self.bind('<ButtonRelease-1>', self._on_click) self.text.bind('<ButtonRelease-1>', self._on_click) self.title.bind('<ButtonRelease-1>', self._on_click) self.date.bind('<ButtonRelease-1>', self._on_click) def state(self, statespec=None): return self.checkbutton.state(statespec) def toggle_visibility(self): self.toggle_visibility_cmd(self.visibility.get()) def get(self, key): if key == 'visibility': return self.visibility.get() else: return self._data[key] def get_values(self): return (self._data['title'], self._data['text'], self._data['date'], self.visibility.get()) def _on_enter(self, event): self.title.state(('active', )) self.text.state(('active', )) self.date.state(('active', )) self.checkbutton.state(('active', )) self.toggle_visibility.state(('active', )) Frame.state(self, ('active', )) return "break" def _on_leave(self, event): self.title.state(('!active', )) self.text.state(('!active', )) self.date.state(('!active', )) self.checkbutton.state(('!active', )) self.toggle_visibility.state(('!active', )) Frame.state(self, ('!active', )) return "break" def _on_click(self, event): self.checkbutton.invoke() return "break"
def create_main_frame(self): """ Large function creating all the basic elements of the main app frame. Creates the treeview and associated buttons, the scoring plugin frame and the go button. """ # Frame for the Treeview and New/Edit/Delete buttons main = Frame(self, padding=(3, 3, 12, 12)) main.rowconfigure(0, weight=1) main.columnconfigure(0, weight=1) main.columnconfigure(1, weight=0) main.grid(row=0, column=0, sticky="nsew") # ------------------------------------------------------- # # Frame for the Treeview and its scrollbars tree_frame = Frame(main, padding=(3, 3, 12, 12)) tree_frame.rowconfigure(0, weight=1) tree_frame.rowconfigure(1, weight=0) tree_frame.columnconfigure(0, weight=1) tree_frame.columnconfigure(1, weight=0) tree_frame.grid(row=0, column=0, sticky="nsew") # ------------------------------------------------------- # # Treeview with column headings self.treeview = Treeview(tree_frame) self.treeview["columns"] = ("class", "barcodes", "variants") self.treeview.column("class", width=120) self.treeview.heading("class", text="Type") self.treeview.column("barcodes", width=25, stretch=tk.NO, anchor=tk.CENTER) self.treeview.heading("barcodes", text="BC") self.treeview.column("variants", width=25, stretch=tk.NO, anchor=tk.CENTER) self.treeview.heading("variants", text="V") self.treeview.grid(row=0, column=0, sticky="nsew") # Treeview context menu bindings self.treeview.bind("<Button-2>", self.treeview_context_menu) # Treeview scrollbars tree_ysb = tk.Scrollbar(tree_frame, orient="vertical", command=self.treeview.yview) tree_xsb = tk.Scrollbar(tree_frame, orient="horizontal", command=self.treeview.xview) tree_ysb.grid(row=0, column=1, sticky="nsw") tree_xsb.grid(row=1, column=0, sticky="ewn") self.treeview.config(yscroll=tree_ysb.set, xscroll=tree_xsb.set) # ------------------------------------------------------- # # Frame for New/Edit/Delete buttons button_frame = Frame(main, padding=(3, 3, 12, 12)) button_frame.grid(row=1, column=0) new_button = Button(button_frame, text="New...", command=self.new_button_press) new_button.grid(row=0, column=0) edit_button = Button(button_frame, text="Edit...", command=self.edit_button_press) edit_button.grid(row=0, column=1) delete_button = Button(button_frame, text="Delete", command=self.delete_button_press) delete_button.grid(row=0, column=2) self.treeview_buttons = [new_button, delete_button, edit_button] # ------------------------------------------------------- # # Frame for Plugin and Analysis Options right_frame = Frame(main, padding=(3, 3, 12, 12)) right_frame.rowconfigure(0, weight=1) right_frame.rowconfigure(1, weight=0) right_frame.columnconfigure(0, weight=1) right_frame.columnconfigure(1, weight=0) right_frame.grid(row=0, column=1, sticky="new") # ------------------------------------------------------- # # LabelFrame for plugin and options scoring_plugin = ScorerScriptsDropDown(right_frame, text="Scoring Options", padding=(3, 3, 12, 12)) scoring_plugin.grid(row=0, column=0, sticky="new") self.scorer_widget = scoring_plugin # ------------------------------------------------------- # # LabelFrame for Analysis Options row = 0 options_frame = LabelFrame(right_frame, text="Analysis Options", padding=(3, 3, 12, 12)) options_frame.grid(row=1, column=0, sticky="new", pady=4) # force recalculate force_recalculate = Checkbutton(options_frame, text="Force Recalculation", variable=self.force_recalculate) force_recalculate.grid(column=0, row=row, sticky="w") row += 1 # component outliers component_outliers = Checkbutton( options_frame, text="Component Outlier Statistics", variable=self.component_outliers, ) component_outliers.grid(column=0, row=row, sticky="w") row += 1 # write tsv tsv_requested = Checkbutton(options_frame, text="Write TSV Files", variable=self.tsv_requested) tsv_requested.grid(column=0, row=row, sticky="w") tsv_requested.invoke() row += 1 # ------------------------------------------------------- # # Run Analysis button frame go_button_frame = Frame(main, padding=(3, 3, 12, 12)) go_button_frame.grid(row=1, column=1) go_button = Button(go_button_frame, text="Run Analysis", command=self.go_button_press) go_button.grid(column=0, row=0) self.go_button = go_button
class ToggledFrame(Frame): """ A frame that can be toggled to open and close """ def __init__(self, master=None, text="", **kwargs): font = kwargs.pop('font', '') Frame.__init__(self, master, **kwargs) self.style_name = self.cget('style') self.toggle_style_name = '%s.Toggle' % ('.'.join( self.style_name.split('.')[:-1])) self.columnconfigure(1, weight=1) self.rowconfigure(1, weight=1) self.style = Style(self) self.style.configure(self.toggle_style_name, background=self.style.lookup( self.style_name, 'background')) self.style.map(self.toggle_style_name, background=[]) self._checkbutton = Checkbutton(self, style=self.toggle_style_name, command=self.toggle, cursor='arrow') self.label = Label(self, text=text, font=font, style=self.style_name.replace('TFrame', 'TLabel')) self.interior = Frame(self, style=self.style_name) self.interior.grid(row=1, column=1, sticky="nswe", padx=(4, 0)) self.interior.grid_remove() self.label.bind('<Configure>', self._wrap) self.label.bind('<1>', lambda e: self._checkbutton.invoke()) self._grid_widgets() self.bind('<<ThemeChanged>>', self._theme_changed) def _theme_changed(self, event): self.style.configure(self.toggle_style_name, background=self.style.lookup( self.style_name, 'background')) def _wrap(self, event): self.label.configure(wraplength=self.label.winfo_width()) def _grid_widgets(self): self._checkbutton.grid(row=0, column=0) self.label.grid(row=0, column=1, sticky="we") def toggle(self): if 'selected' not in self._checkbutton.state(): self.interior.grid_remove() self.event_generate("<<ToggledFrameClose>>") else: self.interior.grid() self.event_generate("<<ToggledFrameOpen>>") def open(self): self._checkbutton.state(('selected', )) self.interior.grid() self.event_generate("<<ToggledFrameOpen>>") def close(self): self._checkbutton.state(('!selected', )) self.interior.grid_remove() self.event_generate("<<ToggledFrameClose>>")
class NewTwoArgsWindow(Toplevel): images = {} def __init__(self, master=None): super().__init__(master=master) self.set_basic() self.set_widgets() def set_basic(self): self.minsize(200, 200) self.maxsize(200, 200) self.title("Operacje logiczne") self.imageWindow1, self.imageWindow2 = None, None self.operations = ["DODAJ", "ODEJMIJ", "ZMIESZAJ", "AND", "OR", "XOR"] def set_widgets(self): self.firstChoice = StringVar(self) self.secondChoice = StringVar(self) self.operationChoice = StringVar(self) self.firstImageList = OptionMenu(self, self.firstChoice) self.secondImageList = OptionMenu(self, self.secondChoice) self.operationList = OptionMenu(self, self.operationChoice) self.update_list() self.operationChoice.set(self.operations[0]) for oper in self.operations: self.operationList['menu'].add_command( label=oper, command=lambda v=oper: self.operationChoice.set(v)) self.cbVal = IntVar() self.cb = Checkbutton(self, width=0, variable=self.cbVal) self.saveButton = Button(self, image=saveIcon, command=self.update_image) self.cancelButton = Button(self, image=closeIcon, command=self.cancel) self.place_widgets() def update_image(self): for obj, name in NewTwoArgsWindow.images.items(): if name == self.firstChoice.get(): self.imageWindow1 = obj break for obj, name in NewTwoArgsWindow.images.items(): if name == self.secondChoice.get(): self.imageWindow2 = obj break outputImage = self.imageWindow1.image.two_args_operations( self.operationChoice.get(), self.imageWindow2.image) if self.cbVal: windowName = self.imageWindow1.name + " " + self.operationChoice.get( ) + " " + self.imageWindow2.name self.imageWindow1.create_another(self.master, None, windowName, ImageSaved(None, outputImage)) else: self.imageWindow1.image.cv2Image = outputImage self.master.image.copy = copy.deepcopy(self.master.image.cv2Image) self.imageWindow1.image.fill_histogram() self.imageWindow1.manager.new_state( self.imageWindow1.image.cv2Image) self.imageWindow1.update_visible_image() self.imageWindow1.update_child_windows() self.cancel() def cancel(self): self.destroy() def update_list(self): if len(NewTwoArgsWindow.images) <= 0: self.cancel() return openFilesNames = list(NewTwoArgsWindow.images.values()) self.firstChoice.set(openFilesNames[0]) self.secondChoice.set(openFilesNames[0]) if len( NewTwoArgsWindow.images) == 1 else self.secondChoice.set( openFilesNames[1]) self.firstImageList['menu'].delete(0, 'end') self.secondImageList['menu'].delete(0, 'end') for file in openFilesNames: self.firstImageList['menu'].add_command( label=file, command=lambda v=file: self.firstChoice.set(v)) self.secondImageList['menu'].add_command( label=file, command=lambda v=file: self.secondChoice.set(v)) def place_widgets(self): Label(self, text="Obraz1: ").place(relx=0.05, y=7) Label(self, text="Operacja: ").place(relx=0.05, y=42) Label(self, text="Obraz2: ").place(relx=0.05, y=77) Label(self, text="Obraz wynikowy").place(relx=0.05, y=102) Label(self, text="w nowym okienku?").place(relx=0.05, y=120) self.firstImageList.place(y=5, relx=0.35) self.operationList.place(y=40, relx=0.35) self.secondImageList.place(y=75, relx=0.35) self.cb.place(y=110, relx=0.7) self.cb.invoke() self.saveButton.place(width=40, height=40, x=50, y=150) self.cancelButton.place(width=40, height=40, x=110, y=150)
class NewSliderWindow(Toplevel): def __init__(self, master=None): super().__init__(master=master) self.set_basic() self.bind('<Configure>', lambda e: self.place_buttons()) def set_basic(self): self.overrideredirect(1) self.set_geometry() self.set_scale() self.set_checkButton() self.set_save_closeButtons() def set_geometry(self): self.width = 60 parentX = self.master.winfo_rootx() parentY = self.master.winfo_rooty() parentHeight = self.master.winfo_height() parentWidth = self.master.winfo_width() self.geometry( '%dx%d+%d+%d' % (self.width, parentHeight, parentX + parentWidth + 2, parentY)) def set_save_closeButtons(self): self.saveButton = Button(self, image=saveIcon, command=self.update_image) self.cancelButton = Button(self, image=closeIcon, command=self.cancel) self.saveButton.place(relx=0.1, rely=0.8, relwidth=0.4) self.cancelButton.place(relx=0.55, rely=0.8, relwidth=0.4) self.saveButton.place( relx=0.1, rely=1 - ((0.4 * self.width) / self.master.winfo_height()), relwidth=0.4) self.cancelButton.place( relx=0.55, rely=1 - ((0.4 * self.width) / self.master.winfo_height()), relwidth=0.4) def place_buttons(self): self.saveButton.place( relx=0.03, rely=1 - ((0.45 * self.width) / self.master.winfo_height()), relwidth=0.45) self.cancelButton.place( relx=0.52, rely=1 - ((0.45 * self.width) / self.master.winfo_height()), relwidth=0.45) def set_scale(self): self.var = IntVar() self.scale = Scale(self, length=256, from_=0, to=255, orient=VERTICAL, command=lambda e: self.update_preview( int(self.var.get()), self.cbVal.get()), variable=self.var, digits=1, resolution=1) self.scale.place(relx=0, rely=0.1, relwidth=0.9, relheight=0.7) self.scale.set(0) def set_checkButton(self): self.cbVal = IntVar() self.cb = Checkbutton(self, width=0, variable=self.cbVal, command=lambda: self.update_preview( int(self.var.get()), self.cbVal.get())) self.cb.place(relx=0.4, rely=0.78) self.cb.invoke() #UPDATE IMAGE ON SLIDER CHANGE def update_preview(self, thresholdVal, checkBoxVal): self.master.image.threshold(thresholdVal, checkBoxVal) self.master.update_visible_image() #UPDATE IMAGE ON "SAVE" AND UPDATE HISTOGRAM def update_image(self): self.master.update_visible_image() self.master.image.copy = copy.deepcopy(self.master.image.cv2Image) self.master.image.fill_histogram() self.master.update_child_windows() self.master.thresholdScaleWindow = None self.master.manager.new_state(self.master.image.cv2Image) self.destroy() #GO BACK TO ORIGINAL ON "CANCEL" def cancel(self): self.master.image.cv2Image = copy.deepcopy(self.master.image.copy) self.master.update_visible_image() self.master.image.fill_histogram() self.master.update_child_windows() self.master.thresholdScaleWindow = None self.destroy()