def init_window(self): self.parent.title("SupMold: SpringCalc") self.grid(column=0, row=0, sticky="nwse") mainFrame = Frame(self, relief='raised', borderwidth=1) mainFrame.grid(column=0, row=0, sticky='nsew') closeButton = Button(mainFrame, text='Cerrar', command=self.appQuit) closeButton.grid(column=0, row=3, padx=5, pady=5) nb = Notebook(mainFrame) tab1 = Frame(nb) tab2 = Frame(nb) tab3 = Frame(nb) nb.add(tab1, text="Compresión") nb.add(tab2, text="Extensión") nb.add(tab3, text="Torsión") nb.grid(column=0, row=1, sticky='nsew', padx=5, pady=5) msg = consoleFrame(mainFrame, 'Mensages') dataB = resource_path('wires.db') if not os.path.isfile(dataB): self.centerWindow() messagebox.showerror( "ERROR", "Base de datos {} inaccesible. " "Favor verificar permisos de lectura o " "ubicación de la misma".format(dataB)) return self.sub1 = subWindow(tab1, Spring(database=dataB)) self.sub1.init_widgets() self.sub2 = subWindow2(tab2, eSpring(database=dataB)) self.sub2.init_widgets() self.sub3 = subWindow3(tab3, tSpring(database=dataB)) self.sub3.init_widgets() self.centerWindow() nb.bind("<<NotebookTabChanged>>", self.tabChangedEvent)
class GuiMain: def __init__(self): """ Main Gui Entrance """ tkinter.Tk.report_callback_exception = self.throw # Main window self.destroyed = False LoggerGui.info("Initializing GUI") self.main_window = tkinter.Tk() self.main_window.wm_title("DRC Sim Server") icon = tkinter.PhotoImage(data=Resource("image/icon.gif").resource) self.main_window.tk.call("wm", "iconphoto", self.main_window, icon) self.main_window.protocol("WM_DELETE_WINDOW", self.on_closing) self.main_window.resizable(False, False) # Notebook self.tab_id = None self.notebook = Notebook(self.main_window, width=600, height=300) self.notebook.grid(column=0, row=0) self.notebook.bind("<<NotebookTabChanged>>", self.on_tab_changed) # Run Server Frame self.frame_run_server = FrameRunServer(self.notebook) self.notebook.add(self.frame_run_server, text="Run Server") # Get Key Frame self.frame_get_key = FrameGetKey(self.notebook) self.notebook.add(self.frame_get_key, text="Get Key") # Log Frame self.frame_log = FrameLog(self.notebook) self.notebook.add(self.frame_log, text="Log") # About Frame self.frame_about = FrameAbout(self.notebook) self.notebook.add(self.frame_about, text="About") @staticmethod def throw(*args): """ Throw exceptions from Tkinter :param args: arguments :return: None """ for arg in args: if isinstance(arg, Exception): LoggerGui.throw(arg) def after(self): """ Empty loop to catch KeyboardInterrupt :return: None """ self.main_window.after(1000, self.after) def start(self): """ Start the main window loop :return: """ LoggerGui.info("Opening GUI") self.after() self.main_window.mainloop() LoggerGui.info("GUI Closed") def stop(self): """ Convenience function to call on_closing() :return: None """ self.on_closing() def on_closing(self): """ Close the main window and current tab :return: None """ if self.destroyed: return self.destroyed = True LoggerGui.info("Closing GUI") if self.tab_id in self.notebook.children: self.notebook.children[self.tab_id].deactivate() try: self.main_window.destroy() except Exception as e: LoggerGui.exception(e) # noinspection PyUnusedLocal def on_tab_changed(self, event): """ Close the previous tab and initialize a new one :param event: tab event :return: None """ tab_id = self.notebook.select() tab_index = self.notebook.index(tab_id) tab_name = self.notebook.tab(tab_index, "text") LoggerGui.debug("Notebook tab changed to \"%s\" with id %d", tab_name, tab_index) self.tab_id = tab_id.split(".")[len( tab_id.split(".")) - 1] # Parse notebook/tab id to only tab id if self.notebook.children[self.tab_id].kill_other_tabs(): for tab in self.notebook.children: if tab != self.tab_id: self.notebook.children[tab].deactivate() self.notebook.children[self.tab_id].activate()
print('y:', event.y) #selected = nb.identify(event.x, event.y) #print('selected:', selected) # it's not usefull clicked_tab = Tab.tk.call(Tab._w, "identify", "tab", event.x, event.y) print('clicked tab:', clicked_tab) active_tab = Tab.index(Tab.select()) print(' active tab:', active_tab) if clicked_tab == 2: E1.focus() # if clicked_tab == active_tab: # Tab.forget(clicked_tab) Tab.bind('<Button-1>', on_click) ##### STATUS BAR #### v_statusbar = StringVar() statusbar = Label(F3, textvariable=v_statusbar, bd=1, relief=SUNKEN, anchor='w') statusbar.pack(side=BOTTOM, fill=X) GUI.mainloop()
class App: def __init__(self): # создание основного окна Tkinter self.window = Tk() self.window.title("Треугольники") self.window.geometry('520x520') self.window.minsize(520, 520) self.window.maxsize(520, 520) self.press_x, self.press_y = 0, 0 self.release_x, self.release_y = 0, 0 # флаги нажатия/отжатия кнопки self.pressed = False # размещение элементов интерфейса # основной элемент - Canvas self.canvas_x = 470 self.canvas_y = 270 self.c = Canvas(self.window, width=self.canvas_x, height=self.canvas_y, bg='black') self.c.pack(side=TOP, padx=10, pady=(10, 10)) # элементы управления: настройки, отображение параметров, очистка/выход setup = Frame(self.window, width=470) setup_left = Frame(setup, width=270) setup_right = Frame(setup, width=200) self.setup_notebook = Notebook(setup_left) setup1 = Frame(setup_left, width=250, height=140) setup2 = Frame(setup_left, width=250, height=140) setup3 = Frame(setup_left, width=250, height=140) # элементы управления на вкладках # вкладка 1 Label(setup1, text='Длина стороны').pack(side=TOP, pady=(10, 0), padx=(10, 0), anchor=W) self.scal_b = Scale(setup1, orient=HORIZONTAL, length=200, from_=0, to=300, tickinterval=100, resolution=10) self.scal_b.pack(side=TOP) self.scal_b.set(100) self.scal_b.bind("<ButtonRelease-1>", self.draw_triangle) Label(setup1, text='Угол \u03b1').pack(side=TOP, pady=(10, 0), padx=(10, 0), anchor=W) self.scal_alpha = Scale(setup1, orient=HORIZONTAL, length=200, from_=0, to=180, tickinterval=30, resolution=15) self.scal_alpha.pack(side=TOP) self.scal_alpha.set(30) self.scal_alpha.bind("<ButtonRelease-1>", self.draw_triangle) # вкладка 2 Label(setup2, text='Угол \u03b1').pack(side=TOP, pady=(10, 0), padx=(10, 0), anchor=W) self.scal_alpha2 = Scale(setup2, orient=HORIZONTAL, length=200, from_=0, to=90, tickinterval=15, resolution=5) self.scal_alpha2.pack(side=TOP) self.scal_alpha2.set(60) self.scal_alpha2.bind("<ButtonRelease-1>", self.draw_triangle) Label(setup2, text='Угол \u03b2').pack(side=TOP, pady=(10, 0), padx=(10, 0), anchor=W) self.scal_beta = Scale(setup2, orient=HORIZONTAL, length=200, from_=0, to=90, tickinterval=15, resolution=5) self.scal_beta.pack(side=TOP) self.scal_beta.set(60) self.scal_beta.bind("<ButtonRelease-1>", self.draw_triangle) # вкладка 3 Label(setup3, text='Длина стороны 2').pack(side=TOP, pady=(10, 0), padx=(10, 0), anchor=W) self.scal_a = Scale(setup3, orient=HORIZONTAL, length=200, from_=0, to=300, tickinterval=100, resolution=10) self.scal_a.pack(side=TOP) self.scal_a.set(100) self.scal_a.bind("<ButtonRelease-1>", self.draw_triangle) Label(setup3, text='Длина стороны 3').pack(side=TOP, pady=(10, 0), padx=(10, 0), anchor=W) self.scal_b2 = Scale(setup3, orient=HORIZONTAL, length=200, from_=0, to=300, tickinterval=100, resolution=10) self.scal_b2.pack(side=TOP) self.scal_b2.set(100) self.scal_b2.bind("<ButtonRelease-1>", self.draw_triangle) setup1.pack() setup2.pack() setup3.pack() self.setup_notebook.add(setup1, text='Задача 1') self.setup_notebook.add(setup2, text='Задача 2') self.setup_notebook.add(setup3, text='Задача 3') self.setup_notebook.bind('<<NotebookTabChanged>>', self.draw_triangle) self.setup_notebook.pack(side=LEFT) columns = ('#1', '#2') self.params = Treeview(setup_right, show='headings', columns=columns, height=5) self.params.heading('#1', text='Параметр') self.params.heading('#2', text='Значение') self.params.column('#1', width=110, minwidth=50, stretch=NO, anchor=N) self.params.column('#2', width=110, minwidth=50, stretch=NO, anchor=N) self.params.pack(side=TOP, padx=(15, 0), pady=(15, 5)) butframe = Frame(setup_right) Button(butframe, text='Очистить', width=10, command=self.draw_base()).pack(side=LEFT, padx=(25, 5)) Button(butframe, text='Выход', width=10, command=lambda x=0: sys.exit(x)).pack(side=LEFT, padx=(0, 10)) butframe.pack(side=TOP, pady=(17, 5)) setup_left.pack(side=LEFT, padx=(0, 20)) setup_right.pack(side=LEFT) setup.pack(side=TOP, pady=(5, 10), padx=(5, 5)) self.window.bind('<Button-1>', self.press) self.window.bind('<ButtonRelease-1>', self.release) self.window.bind('<Motion>', self.motion) self.draw_base() self.window.mainloop() def motion(self, event): if self.pressed: if event.widget.master is not None: if event.widget.widgetName == 'canvas': self.draw_base() self.c.create_line( [self.press_x, self.press_y, event.x, event.y], dash=True, fill='yellow') def draw_base(self): self.c.delete("all") # базовые оси self.c.create_line([10, 250, 460, 250], arrow=LAST, fill='white') self.c.create_line([20, 260, 20, 10], arrow=LAST, fill='white') # метки for i in range(1, 5): self.c.create_line([100 * i + 20, 247, 100 * i + 20, 253], fill='white') for i in range(1, 3): self.c.create_line([17, 250 - 100 * i, 23, 250 - 100 * i], fill='white') # надписи # наименование осей self.c.create_text(457, 258, text='x', fill='white') self.c.create_text(30, 15, text='y', fill='white') # наименование меток for i in range(0, 5): self.c.create_text(100 * i + 25, 260, text=str(100 * i), fill='white') for i in range(1, 3): self.c.create_text(34, 250 - 100 * i, text=str(100 * i), fill='white') def press(self, event): """ Обработчик события "нажатие кнопки мыши" :param event: :return: """ if event.widget.master is not None: if event.widget.widgetName == 'canvas': self.draw_base() self.press_x, self.press_y = event.x, event.y self.pressed = True def release(self, event): if event.widget.master is not None: if event.widget.widgetName == 'canvas': self.release_x, self.release_y = event.x, event.y if (self.release_x in range(450)) & (self.release_y in range(250)): self.draw_triangle(None) self.pressed = False def check_coordinates(self, C): if (C[0] < 0) | (C[1] < 0): return False if (C[0] > self.canvas_x) | (C[1] > self.canvas_y): return False return True def draw_triangle(self, event): if (self.press_x > 0) & (self.press_y > 0) & (self.release_x > 0) & ( self.release_y > 0): self.draw_base() triangle = Math((self.press_x, self.press_y), (self.release_x, self.release_y), (20, 250)) task = self.setup_notebook.index(self.setup_notebook.select()) + 1 if task == 1: data_dict = { 'b': self.scal_b.get(), 'alpha': self.scal_alpha.get() } elif task == 2: data_dict = { 'alpha': self.scal_alpha2.get(), 'beta': self.scal_beta.get() } elif task == 3: data_dict = {'a': self.scal_a.get(), 'b': self.scal_b2.get()} else: return C1, C2, data_dict = triangle.get_c(task, data_dict) if self.check_coordinates(C1) & self.check_coordinates(C2): self.c.create_polygon([ self.press_x, self.press_y, self.release_x, self.release_y, C1[0], C1[1] ], fill='red') self.c.create_polygon([ self.press_x, self.press_y, self.release_x, self.release_y, C2[0], C2[1] ], fill='blue') self.update_treeview(data_dict) else: self.c.create_text(300, 100, text='Одна из точек вне области построения', fill='white') def update_treeview(self, data): """ запись параметров в элемент Treeview :return: None """ for x in self.params.get_children(): self.params.delete(x) for key in data.keys(): self.params.insert("", END, values=[key, data[key]])
class App(Frame): def __init__(self, master): super().__init__(master) self.master = master self.syncFunc = [] def setupUI(self, master, theme): self.master = master self.theme = theme self.username = None self.TkBal = StringVar() self.Admin = None # self.MainFrame = Frame(self) self.headerFrame = Frame(self.MainFrame) self.headerFrame.grid_columnconfigure(1, weight=1) self.head = Label(self.headerFrame, text="SVK BANKING SYSTEMS", font=("Arial", 18)) self.ballb = Label(self.headerFrame, text="Balance: ", font=("Arial", 18)) self.ballb2 = Label(self.headerFrame, textvariable=self.TkBal, font=("Arial", 18)) self.head.grid(row=0, column=0, sticky="w") self.headerFrame.pack(fill="x") self.MainFrame.pack(fill="both", expand=True) self.update # self.login() def login(self): self.loginContainer = Login.login(self.MainFrame, self.panel, self.TkBal) self.loginContainer.place(relx=0.5, rely=0.5, anchor="center") def panel(self): self.ballb.grid(row=0, column=1, sticky="e") self.ballb2.grid(row=0, column=2, sticky="e") self.username = self.loginContainer.username mycursor.execute( f"SELECT AcNo FROM profile WHERE username = '******';") self.acno = mycursor.fetchone()[0] style = Style(self) style.configure("leftTab.TNotebook", tabposition="s") style.theme_settings( self.theme, {"TNotebook.Tab": { "configure": { "padding": [10, 10] } }}) self.notebook = Notebook(self.MainFrame, style="leftTab.TNotebook", width=800, height=500) self.notebook.pack(expand=True, fill="both") self.notebook.bind("<<NotebookTabChanged>>", self.logout) self.tabs = { "Dasboard": Dasboard.dasboard(self.notebook, self.username), "Transactions": Transaction.transaction(self.notebook, self.acno, self.TkBal), "Pay": Pay.pay(self.notebook, self.acno, self.TkBal), "Change Password": ChangePsswd.change(self.notebook, self.username), "Settings": Admin.user(self.notebook, self.username), } self.syncFunc = [ Dasboard.dasboard, Transaction.transaction, Pay.pay, ChangePsswd.change, Admin.user, ] mycursor.execute( f"SELECT Admin FROM profile WHERE username = '******';") self.images = {} self.Tkimages = {} self.ImageIter = 0 for image in [ "Dasboard", "Transactions", "Pay", "Change Password", "Settings", "add_user", "view", "leave", ]: self.images[image] = Image.open(f".//assets//{image}.png") self.images[image].thumbnail((30, 30), Image.ANTIALIAS) self.Tkimages[image] = ImageTk.PhotoImage(self.images[image]) for tab in self.tabs.keys(): self.notebook.add( self.tabs[tab], text=tab, image=self.Tkimages[tab.strip()], compound="top", ) self.ImageIter += 1 if mycursor.fetchone()[0]: self.notebook.add( Admin.admin(self.notebook, self.username), text="Add/Edit Ac", image=self.Tkimages["add_user"], compound="top", ) self.syncFunc.append(Admin.admin) self.notebook.add( Transaction.view(self.notebook), text="View Clients", image=self.Tkimages["view"], compound="top", ) self.syncFunc.append(Transaction.view) self.notebook.add(Frame(), text="Logout", image=self.Tkimages["leave"], compound="top") def logout(self, key=None): try: if key.widget.select() == self.notebook.tabs()[-1]: self.master.quit() self.master.destroy() mydb.close() with open("isExit", "w") as isExit: isExit.write("true") sys.exit() except: pass
class App(tk.Tk): window = None def get_title(self, info): return "Музыка {} {} (id{})".format(info["first_name"], info["last_name"], info["id"]) def __init__(self, audio_obj, vk_audio, info): #initialize self if (App.window is not None): return super().__init__() self.vk_audio = vk_audio self.geometry('733x450') self.columnconfigure(0, weight=1) self.count, self.SortDir, self.player_window = False, True, None #initialize notebook self.tabs = Notebook(self) self.tabs.place(x=0, y=0, relwidth=1, relheight=1) self.tabs.bind('<<NotebookTabChanged>>', self.tab_changed) self.list = [] self.add_tab(audio_obj, info) App.window = self def add_tab(self, audio: vk_audio.Audio, info): if (audio in self.list): self.tabs.select(self.list.index(audio)) return title = self.get_title(info) f = tk.Frame(self.tabs) tk.Button(f, text="Закрыть", command=self.on_close_tab_clicked).pack() #add_albums_frame if (audio.Playlists): AlbumsFrame(f, audio.Playlists, self.add_tab_playlist, self.author_clicked).pack(side=tk.TOP, fill=tk.BOTH, expand=False) #add_audios_frame AudiosFrame(f, audio.Audios, True).pack(fill=tk.BOTH, expand=True, side=tk.BOTTOM) self.tabs.add(f, text=title) self.list.append(audio) self.focus_force() self.tabs.select(len(self.list) - 1) return self def on_close_tab_clicked(self): t = self.tabs.select() index = self.tabs.tabs().index(t) self.list.pop(index) if (not self.list): self.destroy() self.tabs.forget(t) def tab_changed(self, event): tab = self.tabs.tab( event.widget.index("current" ) if not isinstance(event, int) else event) self.title(tab['text']) def add_tab_playlist(self, playlist: vk_audio.Playlist): if (playlist in self.list): self.tabs.select(self.list.index(playlist)) return self.list.append(playlist) title = "Плейлист {} (id{})".format(playlist.title, playlist.owner_id) f = tk.Frame(self.tabs) tk.Button(f, text="Закрыть", command=self.on_close_tab_clicked).pack() #region add playlist info tk.Label(f, text=playlist.title, font=('times', 16)).pack() author = tk.Label(f, text=",".join(i['name'] for i in playlist.author_info), font=AlbumsFrame.DEFAULT_FONT, fg=AlbumsFrame.DEF_FG, cursor="hand2") author.pack() author.bind("<Button-1>", lambda _: self.author_clicked(playlist)) author.bind( "<Enter>", lambda _: author.config(font=AlbumsFrame.HOVER_FONT, fg=AlbumsFrame.HOVER_FG)) author.bind( "<Leave>", lambda _: author.config(font=AlbumsFrame.DEFAULT_FONT, fg=AlbumsFrame.DEF_FG)) img = tk.Canvas(f, width=160, height=160) img.pack(pady=5) AlbumsFrame.set_image_from_album(None, img, playlist) #endregion AudiosFrame(f, playlist.Audios, True).pack(fill=tk.BOTH, expand=True, side=tk.BOTTOM) self.tabs.add(f, text=title) self.focus_force() self.tabs.select(len(self.list) - 1) def author_clicked(self, playlist): if (playlist.author_hrefs): for i, item in enumerate(self.list): if (isinstance(item, vk_audio.Audio) and item.owner_id == playlist.owner_id): self.tabs.select(i) break else: artist_music = playlist.artist_music(0) self.add_tab( artist_music, { "first_name": artist_music.nick, "last_name": "", "id": artist_music.owner_id }) elif (playlist.owner_id > 0): for i, item in enumerate(self.list): if (isinstance(item, vk_audio.Audio) and item.owner_id == playlist.owner_id): self.tabs.select(i) break else: self.add_tab(self.vk_audio.load(playlist.owner_id)) else: messagebox.showerror("Ошибка", "Пока брать музыку у артиста(") def destroy(self): if (App.window is self): App.window = None return super().destroy() @staticmethod def get(item=None, owner_id=None, vk_audio=None, info=None): if (item is None and vk_audio is not None): item = vk_audio.load(owner_id=owner_id) return App( audio_obj=item, info=info, vk_audio=vk_audio) if App.window is None else App.window.add_tab( item, info)
def tab_changed(event): """notebook handler changes width and height after a tab is selected Parameters ---------- event : str bind event """ event.widget.update_idletasks() tc1 = event.widget.nametowidget(event.widget.select()) event.widget.configure(height=tc1.winfo_reqheight(), width=tc1.winfo_reqwidth()) nb1 = Notebook(root, style='green.TNotebook') nb1.bind("<<NotebookTabChanged>>", tab_changed) nb1.grid(row=0, column=0) nb1.enable_traversal() # first page page1 = Frame(root, background='red', height=70 * mult) enabler = Button(page1, text='Enable Tab two\n Test it out', command=lambda: nb1.tab(1, state='normal')) enabler.pack(ipadx=5, ipady=5) nb1.add(page1, text='one', underline=0, padding=2) # second page page2 = Frame(root, background='yellow', height=20 * mult)
class Manager(Toplevel): """Note manager.""" def __init__(self, master): """Create note manager to easily delete multiple notes.""" Toplevel.__init__(self, master, class_='MyNotes') self.title(_("Note Manager")) self.minsize(width=546, height=200) self.grab_set() categories = CONFIG.options("Categories") categories.sort() self.im_del = PhotoImage(file=IM_DELETE, master=self) self.im_change = PhotoImage(file=IM_CHANGE, master=self) self.im_visible = PhotoImage(file=IM_VISIBLE_24, master=self) self.im_hidden = PhotoImage(file=IM_HIDDEN_24, master=self) tooltipwrapper = TooltipWrapper(self) self.notebook = Notebook(self) self.notebook.pack(fill='both', expand=True) self.texts = {} self.frames = {} self.notes = {} # to change notes category menu_cat = Menu(self, tearoff=False) self.category = StringVar(self) # create one tab per category for cat in categories: menu_cat.add_radiobutton(label=cat.capitalize(), value=cat, variable=self.category, command=self.change_cat_selection) self.notes[cat] = {} frame = Frame(self.notebook, padding=2) self.texts[cat] = Text(frame, width=1, height=1, bg=self.cget('bg'), relief='flat', highlightthickness=0, padx=0, pady=0, cursor='arrow') frame.columnconfigure(0, weight=1) frame.rowconfigure(1, weight=1) self.texts[cat].grid(row=1, column=0, sticky='ewsn') scrolly = Scrollbar(frame, orient='vertical', command=self.texts[cat].yview) scrolly.grid(row=1, column=1, sticky='ns', pady=(2, 0)) scrollx = Scrollbar(frame, orient='horizontal', command=self.texts[cat].xview) scrollx.grid(row=2, column=0, sticky='ew') self.texts[cat].configure(xscrollcommand=scrollx.set, yscrollcommand=scrolly.set) self.frames[cat] = Frame(self.texts[cat], style='bg.TFrame', padding=1, height=29, width=523) self.frames[cat].columnconfigure(0, weight=1, minsize=170) headings = Frame(frame, padding=(1, 0, 1, 0)) headings.columnconfigure(0, weight=0, minsize=20) headings.columnconfigure(1, weight=1, minsize=198) headings.columnconfigure(2, weight=1, minsize=198) headings.columnconfigure(3, weight=0, minsize=84) headings.columnconfigure(4, weight=0, minsize=22) Heading(headings, cat, 'title', command=self.sort_column, text=_('Title')).grid(row=0, column=1, sticky='ew') Heading(headings, cat, 'text', command=self.sort_column, text=_('Text')).grid(row=0, column=2, sticky='ew') Heading(headings, cat, 'date', command=self.sort_column, text=_('Date')).grid(row=0, column=3, sticky='ew') Heading(headings, cat, 'select_all', style='select.heading.TLabel', padding=0, command=self.toggle_selectall).place(x=0, y=0, anchor='nw', relheight=1, width=20) Heading(headings, cat, 'visibility', command=self.sort_column).place(relx=1, y=0, anchor='ne', bordermode='outside', width=23, relheight=1) headings.place(x=0, y=2, anchor='nw') self.update_idletasks() frame.rowconfigure(0, minsize=headings.winfo_reqheight()) self.texts[cat].window_create('1.0', window=self.frames[cat]) b_frame = Frame(frame) b_frame.grid(row=3, columnspan=2) m = Menubutton(b_frame, image=self.im_change, text=_('Change category'), compound='right', menu=menu_cat, padding=1) m.pack(side='left', padx=4, pady=4, fill='y') tooltipwrapper.add_tooltip(m, _('Change category of selected notes')) b_show = Button(b_frame, image=self.im_visible, padding=1, command=self.show_selection) b_show.pack(side='left', padx=4, pady=4) tooltipwrapper.add_tooltip(b_show, _('Show selected notes')) b_hide = Button(b_frame, image=self.im_hidden, padding=1, command=self.hide_selection) b_hide.pack(side='left', padx=4, pady=4) tooltipwrapper.add_tooltip(b_hide, _('Hide selected notes')) b_del = Button(b_frame, image=self.im_del, command=self.del_selection, padding=1) b_del.pack(side='left', padx=4, pady=4, fill='y') tooltipwrapper.add_tooltip(b_del, _('Delete selected notes')) self.notebook.add(frame, text=cat.capitalize(), sticky="ewsn", padding=0) # display notes by category for key, note_data in self.master.note_data.items(): self.display_note(key, note_data) for txt in self.texts.values(): txt.configure(state='disabled') self.geometry('410x450') self.bind("<Button-4>", lambda e: self.scroll(-1)) self.bind("<Button-5>", lambda e: self.scroll(1)) self.notebook.bind('<<NotebookTabChanged>>', self.on_change_tab) def toggle_selectall(self, event): heading = event.widget cat = heading.category sel = self.get_selection(cat) if len(sel) == len(self.notes[cat]): for widget in self.notes[cat].values(): widget.state(('!selected', )) else: for widget in self.notes[cat].values(): widget.state(('selected', )) def show_selection(self): cat = self.notebook.tab('current', 'text').lower() sel = self.get_selection(cat) if sel: for key in sel: self.notes[cat][key].visibility.set(True) self.toggle_visibility(key, True) def hide_selection(self): cat = self.notebook.tab('current', 'text').lower() sel = self.get_selection(cat) if sel: for key in sel: self.notes[cat][key].visibility.set(False) self.toggle_visibility(key, False) def select_all(self): cat = self.notebook.tab('current', 'text').lower() for widget in self.notes[cat].values(): widget.state(('selected', )) def deselect_all(self): cat = self.notebook.tab('current', 'text').lower() for widget in self.notes[cat].values(): widget.state(('!selected', )) def sort_column(self, event): """Sort column.""" heading = event.widget notes = [(item.get(heading.column), item.get_values(), item) for item in self.notes[heading.category].values()] notes.sort(reverse=heading.reverse, key=lambda x: x[:-1]) for i, (val, values, item) in enumerate(notes): item.grid_configure(row=i) heading.reverse = not heading.reverse heading.state(['!' * heading.reverse + 'alternate']) def toggle_visibility(self, key, visible): if visible: if key not in self.master.notes: self.master.show_note(key) else: if key in self.master.notes: self.master.notes[key].hide() self.after(2, self.focus_set) self.after(4, self.grab_set) def display_note(self, key, note_data): """Display note in note manager.""" cat = note_data["category"] c, r = self.frames[cat].grid_size() self.notes[cat][key] = ManagerItem( self.frames[cat], note_data, lambda vis: self.toggle_visibility(key, vis)) self.notes[cat][key].grid(row=r, sticky='ew') def on_change_tab(self, event): self.category.set(self.notebook.tab("current", "text").lower()) def del_selection(self): """Delete selected notes.""" cat = self.notebook.tab('current', 'text').lower() sel = self.get_selection(cat) if sel: rep = askokcancel(_("Confirmation"), _("Delete the selected notes?")) if rep: for key in sel: self.master.delete_note(key) self.notes[cat][key].destroy() del self.notes[cat][key] self.update_idletasks() def change_cat_selection(self): """Change selected notes category.""" cat = self.notebook.tab('current', 'text').lower() new_cat = self.category.get() sel = self.get_selection(cat) if sel and new_cat != cat: rep = askokcancel(_("Confirmation"), _("Change the category of the selected notes?")) if rep: for key in sel: self.master.change_note_category(key, new_cat) self.notes[cat][key].destroy() del self.notes[cat][key] self.display_note(key, self.master.note_data[key]) self.update_idletasks() self.category.set(cat) self.grab_set() def get_selection(self, cat): sel = [] for key, widget in self.notes[cat].items(): if 'selected' in widget.state(): sel.append(key) return sel def scroll(self, delta): cat = self.notebook.tab("current", "text").lower() top, bottom = self.texts[cat].yview() top += delta * 0.05 top = min(max(top, 0), 1) self.texts[cat].yview_moveto(top)
class Window: def __init__(self, width, height, title="MyWindow", resizable=(False, False), icon=r"resources/feather.ico"): self.root = Tk() self.root.title(title) # self.root.geometry(f"{width}x{height}+200+200") self.root.geometry("+600+300") # self.root.resizable(resizable[0], resizable[1]) if icon: self.root.iconbitmap(icon) self.tabs_control = Notebook(self.root, height=100, width=30, padding=(10, 20, 30, 40)) self.tabs_control.enable_traversal() self.tab_1 = Frame(self.tabs_control) self.tabs_control.add(self.tab_1, text="First tab", underline=0) self.tab_2 = Frame(self.tabs_control) self.tabs_control.add(self.tab_2, text="Second tab", underline=1) self.tabs_control.bind("<<NotebookTabChanged>>", self.tab_changed) def run(self): self.draw_widgets() self.root.mainloop() def draw_widgets(self): self.draw_menu() self.tabs_control.pack(fill=BOTH, expand=1) Label(self.tab_1, text="Hello on the fist tab!", height=5, bg="green").pack() Text(self.tab_2).pack() # self.tabs_control.forget(self.tab_2) # self.tabs_control.forget(1) tab_3 = Frame(self.tabs_control) # self.tabs_control.insert(END, tab_3, text="Third tab") self.tabs_control.insert("end", tab_3, text="Third tab") tab_4 = Frame(self.tabs_control) self.tabs_control.insert(2, tab_4, text="Fourth tab") self.tabs_control.select(tab_3) print(f"Selected tab: {self.tabs_control.select()}") print(f"tab_4 params: {self.tabs_control.tab(tab_4)}") print(f"tab_4 params: {self.tabs_control.tab(tab_4, 'sticky')}") self.tabs_control.tab(tab_4, text="4th tab", underline=1) print(f"tab_4 params: {self.tabs_control.tab(tab_4)}") print(f"Managed tabs: {self.tabs_control.tabs()}") print(f"Params: {self.tabs_control.tab(0)}") print(f"Params: {self.tabs_control.tab('current')}") # print(f"Params: {self.tabs_control.tab(CURRENT)}") print(f"Params: {self.tabs_control.tab(self.tab_2)}") def draw_menu(self): menu_bar = Menu(self.root) file_menu = Menu(menu_bar, tearoff=0) file_menu.add_separator() file_menu.add_command(label="Выйти", command=self.exit) info_menu = Menu(menu_bar, tearoff=0) info_menu.add_command(label="О приложении", command=self.show_info) menu_bar.add_cascade(label="Файл", menu=file_menu) menu_bar.add_cascade(label="Справка", menu=info_menu) self.root.configure(menu=menu_bar) def tab_changed(self, event): print(f"Changed tab to: {self.tabs_control.select()}") def show_info(self): mb.showinfo("Информация", "Лучшее графическое приложение на свете") def exit(self): choice = mb.askyesno("Quit", "Do you want to quit?") if choice: self.root.destroy() def create_child(self, width, height, title="Child", resizable=(False, False), icon=None): ChildWindow(self.root, width, height, title, resizable, icon)
class OptionsView: def __init__(self, settings, root, textFrameManager): self._settings = settings self._root = root self._textFrameManager = textFrameManager self._highlightWorker = None self._guiWorker = None self._showing = False self._saving = False self._textFrame: TF.TextFrame = None def linkWorkers(self, workers): self._highlightWorker = workers.highlightWorker self._guiWorker = workers.guiWorker def linkTextFrame(self, textFrame): self._textFrame = textFrame def _onClosing(self, savingSettings=False): # Delete all variable observers for settingsLine in list(self._setsDict.values()): for entry in list(settingsLine.entries.values()): try: entry.var.trace_vdelete("w", entry.observer) except: pass # Delete all view elements del self._setsDict # Close window self._view.destroy() if not savingSettings: self._showing = False class SettingsLineTemplate: def __init__(self, setGroup, setId, setDisplayName, setType): self.setGroup = setGroup self.setId = setId self.setDisplayName = setDisplayName self.setType = setType class SettingsLine: def __init__(self, group): self.group = group self.entries = dict() class LineColorSettingsLine(SettingsLine): def __init__(self, group): super().__init__(group) self.lineFrame = None class Entry: def __init__(self, entryType, entryVar): self.label: tk.Label = None self.var = None self.observer = None self.input: tk.Entry = None self.button: tk.Button = None self.data = OptionsView.EntryData(entryType, entryVar) def isVarUpdated(self): updated = False try: updated = self.var.get() != self.data.entryVar except AttributeError: traceLog(LogLevel.ERROR, "Tkinter var in OptionsView not initiated") updated = True return updated class EntryData: def __init__(self, entryType, entryVar): self.entryType = entryType self.entryVar = entryVar self.validation = OptionsView.EntryDataValidation( OptionsView.ENTRY_VALIDATION_OK, "white", "") class EntryDataValidation: def __init__(self, status, backgroundColor, infoText): self.status = status self.backgroundColor = backgroundColor self.infoText = infoText ENTRY_TYPE_COLOR = "typeColor" ENTRY_TYPE_STRING = "typeString" ENTRY_TYPE_INT = "typeInt" ENTRY_TYPE_REGEX = "typeRegex" ENTRY_TYPE_TOGGLE = "typeToggle" ENTRY_TYPE_OTHER = "typeOther" ENTRY_VALIDATION_OK = "entryValidationOk" ENTRY_VALIDATION_FAILED = "entryValidationFailed" ENTRY_VALIDATION_DUPLICATE = "entryValidationDuplicate" GROUP_TEXT_AREA = "groupTextArea" GROUP_SEARCH = "groupSearch" GROUP_LOGGING = "groupLogging" GROUP_LINE_COLORING = "groupLineColoring" EDIT_UP = "editUp" EDIT_DOWN = "editDown" EDIT_DELETE = "editDelete" ROW_HIGHLIGHT_COLOR = "gray" LOG_EXAMPLE_FILE = r"appdata\log_example.txt" def _loadLogExample(self): log = "[12:34:56.789] Main::test\n[12:34:56.789] Main::TestTwo" try: with open( os.path.join(self._settings.get(Sets.CT_HOMEPATH_FULL), self.LOG_EXAMPLE_FILE), "r") as file: log = file.read() except FileNotFoundError: traceLog(LogLevel.WARNING, "Log example file not found. Using default example") return log def show(self): # Only allow one options view at a time # TODO Can be done with a global var, then a global instance of OptionsView is not needed if not self._showing: self._showing = True self._lineColorMap = self._textFrame.getLineColorMap() self._view = tk.Toplevel(self._root) self._view.title("Options") self._view.protocol("WM_DELETE_WINDOW", self._onClosing) self._view.iconbitmap(self._settings.get(Sets.ICON_PATH_FULL)) self._setsDict = dict() ############################## # TAB CONTROL self._tabsFrame = tk.Frame(self._view) self._tabsFrame.grid(row=0, column=0, sticky="nsew") self._view.columnconfigure(0, weight=1) self._view.rowconfigure(0, weight=1) self._tabControl = Notebook(self._tabsFrame, padding=10) self._tabControl.grid(row=0, column=0, sticky=tk.N) self._tabList = list() ############################## # TEXT EXAMPLE logExample = self._loadLogExample() exampleTextFrameHeightMin = 400 exampleTextFrameWidth = 650 self._exampleTextFrame = tk.Frame(self._tabsFrame, height=exampleTextFrameHeightMin, width=exampleTextFrameWidth) self._exampleTextFrame.grid(row=0, column=1, padx=(0, 10), pady=(10, 10), sticky="nsew") self._exampleTextFrame.grid_propagate(False) self._tabsFrame.columnconfigure(1, weight=1) self._tabsFrame.rowconfigure(0, weight=1) tFont = Font(family=self._settings.get(Sets.TEXTAREA_FONT_FAMILY), size=self._settings.get(Sets.TEXTAREA_FONT_SIZE)) self._exampleText = tk.Text(self._exampleTextFrame,height=1, width=2,\ background=self._settings.get(Sets.TEXTAREA_BACKGROUND_COLOR),\ selectbackground=self._settings.get(Sets.TEXTAREA_SELECT_BACKGROUND_COLOR),\ foreground=self._settings.get(Sets.TEXTAREA_COLOR),\ font=tFont) self._exampleText.grid(row=0, column=0, padx=(0, 0), pady=(10, 0), sticky="nsew") self._exampleTextFrame.columnconfigure(0, weight=1) self._exampleTextFrame.rowconfigure(0, weight=1) self._updateExampleTextLineWrap( self._settings.get(Sets.TEXTAREA_LINE_WRAP)) self._exampleText.insert(1.0, logExample) xscrollbar = tk.Scrollbar(self._exampleTextFrame, orient=tk.HORIZONTAL, command=self._exampleText.xview) xscrollbar.grid(row=1, column=0, sticky=tk.W + tk.E) self._exampleText["xscrollcommand"] = xscrollbar.set yscrollbar = tk.Scrollbar(self._exampleTextFrame, orient=tk.VERTICAL, command=self._exampleText.yview) yscrollbar.grid(row=0, column=1, sticky=tk.N + tk.S) self._exampleText["yscrollcommand"] = yscrollbar.set ############### # Tab: Line Coloring self._lineColoringFrame = tk.Frame(self._tabControl, padx=5, pady=5) self._lineColoringFrame.grid(row=0, column=0, sticky=tk.N) self._tabControl.add(self._lineColoringFrame, text="Line Coloring") self._tabList.append(self.GROUP_LINE_COLORING) self._setsDict.update( self._createLineColorRows(self._lineColoringFrame, self._lineColorMap)) upButton = tk.Button(self._lineColoringFrame, text="UP", command=partial(self._editLineColorRow, self.EDIT_UP)) upButton.grid(row=0, column=2, padx=2) downButton = tk.Button(self._lineColoringFrame, text="DOWN", command=partial(self._editLineColorRow, self.EDIT_DOWN)) downButton.grid(row=1, column=2, padx=2) deleteButton = tk.Button(self._lineColoringFrame, text="Delete", command=partial(self._editLineColorRow, self.EDIT_DELETE)) deleteButton.grid(row=2, column=2, padx=2) self._lastFocusInRowId = "" self._lastFocusOutRowId = "" self._newButtonRow = len(self._lineColorMap) self._newButton = tk.Button(self._lineColoringFrame, text="New Line", command=partial( self._addNewEmptyLineColor)) self._newButton.grid(row=self._newButtonRow, column=0, sticky=tk.W, padx=(2, 100), pady=2) self._deletedLineColorRows = list() ############### # Tab: Text Area self._textAreaFrame = tk.Frame(self._tabControl, padx=5, pady=5) self._textAreaFrame.grid(row=0, column=0, sticky=tk.N) self._tabControl.add(self._textAreaFrame, text="Text Area") self._tabList.append(self.GROUP_TEXT_AREA) setLines = list() setLines.append( self.SettingsLineTemplate(self.GROUP_TEXT_AREA, Sets.TEXTAREA_BACKGROUND_COLOR, "Background Color", self.ENTRY_TYPE_COLOR)) setLines.append( self.SettingsLineTemplate( self.GROUP_TEXT_AREA, Sets.TEXTAREA_SELECT_BACKGROUND_COLOR, "Background Color Select", self.ENTRY_TYPE_COLOR)) setLines.append( self.SettingsLineTemplate(self.GROUP_TEXT_AREA, Sets.TEXTAREA_COLOR, "Text Color", self.ENTRY_TYPE_COLOR)) setLines.append( self.SettingsLineTemplate(self.GROUP_TEXT_AREA, Sets.TEXTAREA_FONT_FAMILY, "Font Family", self.ENTRY_TYPE_STRING)) setLines.append( self.SettingsLineTemplate(self.GROUP_TEXT_AREA, Sets.TEXTAREA_FONT_SIZE, "Font Size", self.ENTRY_TYPE_INT)) setLines.append( self.SettingsLineTemplate(self.GROUP_TEXT_AREA, Sets.TEXTAREA_LINE_WRAP, "Line Wrap", self.ENTRY_TYPE_TOGGLE)) self._setsDict.update( self._createStandardRows(self._textAreaFrame, setLines, 0)) ############### # Tab: Search self._searchFrame = tk.Frame(self._tabControl, padx=5, pady=5) self._searchFrame.grid(row=0, column=0, sticky=tk.N) self._tabControl.add(self._searchFrame, text="Search") self._tabList.append(self.GROUP_SEARCH) setLines = list() setLines.append( self.SettingsLineTemplate(self.GROUP_SEARCH, Sets.SEARCH_MATCH_COLOR, "Search match background color", self.ENTRY_TYPE_COLOR)) setLines.append( self.SettingsLineTemplate(self.GROUP_SEARCH, Sets.SEARCH_SELECTED_COLOR, "Search selected background color", self.ENTRY_TYPE_COLOR)) setLines.append( self.SettingsLineTemplate( self.GROUP_SEARCH, Sets.SEARCH_SELECTED_LINE_COLOR, "Search selected line background color", self.ENTRY_TYPE_COLOR)) self._setsDict.update( self._createStandardRows(self._searchFrame, setLines, 0)) ############### # Tab: Logging self._loggingFrame = tk.Frame(self._tabControl, padx=5, pady=5) self._loggingFrame.grid(row=0, column=0, sticky=tk.N) self._tabControl.add(self._loggingFrame, text="Logging") self._tabList.append(self.GROUP_LOGGING) setLines = list() setLines.append( self.SettingsLineTemplate(self.GROUP_LOGGING, Sets.LOG_FILE_PATH, "Log file path", self.ENTRY_TYPE_OTHER)) setLines.append( self.SettingsLineTemplate(self.GROUP_LOGGING, Sets.LOG_FILE_BASE_NAME, "Log file base name", self.ENTRY_TYPE_OTHER)) setLines.append( self.SettingsLineTemplate(self.GROUP_LOGGING, Sets.LOG_FILE_TIMESTAMP, "Time stamp", self.ENTRY_TYPE_OTHER)) self._setsDict.update( self._createStandardRows(self._loggingFrame, setLines, 0)) ############################## # CONTROL ROW self._optionsControlFrame = tk.Frame(self._view) self._optionsControlFrame.grid(row=1, column=0, padx=(10, 10), pady=(0, 10), sticky=tk.W + tk.E) self._optionsInfoLabel = tk.Label(self._optionsControlFrame, text="", justify=tk.LEFT) self._optionsInfoLabel.grid(row=0, column=0, sticky=tk.W) self._optionsControlFrame.columnconfigure(0, weight=1) self._optionsCancelButton = tk.Button(self._optionsControlFrame, text="Cancel", command=self._onClosing) self._optionsCancelButton.grid(row=0, column=1, padx=5, sticky=tk.E) self._optionsSaveButton = tk.Button(self._optionsControlFrame, text="Save", command=self._saveSettings) self._optionsSaveButton.grid(row=0, column=2, sticky=tk.E) if self._saving: self._optionsSaveButton.config(state=tk.DISABLED) else: self._optionsSaveButton.config(state=tk.NORMAL) self._tabControl.bind("<<NotebookTabChanged>>", self._tabChanged) # print("Number of settings " + str(len(self._setsDict))) def _saveSettings(self): saveSettingsThread = threading.Thread(target=self._saveSettingsProcess, name="SaveSettings") saveSettingsThread.start() self._saving = True def _setSaveButtonState(self, state): if self._showing: try: self._optionsSaveButton.config(state=state) except: # Catch if function is called while save button does not exist traceLog(LogLevel.ERROR, "Error updating save button state") def _saveSettingsProcess(self): # Saving will block, so must be done in different thread # setsDict will be deleted in the onClosing function tempSetsDict = self._setsDict # Close options view self._root.after(10, self._onClosing, True) # Get registered textFrames textFrames = self._textFrameManager.getTextFrames() # Show saving message for textFrame in textFrames: textFrame.showSpinner("Reloading View") # Stop workers using the settings self._highlightWorker.stopWorker(emptyQueue=False) self._guiWorker.stopWorker() # Save all settings tempLineColorMap = dict() tempLineColorRows = dict() # Sort settings to guarantee right order of line coloring for rowId in sorted(tempSetsDict.keys()): if Sets.LINE_COLOR_MAP in rowId: tempLineColorMap[rowId] = dict() tempLineColorRows[rowId] = tempSetsDict[rowId] for entryName in tempSetsDict[rowId].entries.keys(): setting = tempSetsDict[rowId].entries[entryName].var.get() if Sets.LINE_COLOR_MAP in rowId: tempLineColorMap[rowId][entryName] = setting else: self._settings.setOption(rowId, setting) self._settings.setOption(Sets.LINE_COLOR_MAP, tempLineColorMap) # Once settings have been saved, allow for reopen of options view self._showing = False # Delete line color tags for deletedRowData in self._deletedLineColorRows: for textFrame in textFrames: textFrame.deleteTextTag(deletedRowData["tagName"]) # Process added or updated line color rows for rowId in tempLineColorRows.keys(): if tempLineColorRows[rowId].entries["regex"].isVarUpdated(): if tempLineColorRows[rowId].entries["regex"].data.entryVar: oldTagName = TF.createLineColorTagName( tempLineColorRows[rowId].entries["regex"].data.entryVar ) for textFrame in textFrames: textFrame.deleteTextTag(oldTagName) # print("Delete edited row id: " + rowId) for textFrame in textFrames: textFrame.createAndAddLineColorTag( tempLineColorRows[rowId].entries["regex"].var.get(), tempLineColorRows[rowId].entries["color"].var.get()) # print("Added line color row: " + rowId) elif tempLineColorRows[rowId].entries["color"].isVarUpdated(): tagName = TF.createLineColorTagName( tempLineColorRows[rowId].entries["regex"].var.get()) for textFrame in textFrames: textFrame.updateTagColor( tagName, tempLineColorRows[rowId].entries["color"].var.get()) # Reorder line color tags rowIds = sorted(tempLineColorRows.keys()) if rowIds: preTagName = TF.createLineColorTagName( tempLineColorRows[rowIds[0]].entries["regex"].var.get()) for rowId in rowIds[1:-1]: tagName = TF.createLineColorTagName( tempLineColorRows[rowId].entries["regex"].var.get()) for textFrame in textFrames: textFrame.textArea.tag_raise(tagName, aboveThis=preTagName) preTagName = tagName # print(*self._textFrame.textArea.tag_names(),sep=", ") # Reload main interface for textFrame in textFrames: textFrame.reloadLineColorMap() textFrame.reloadTextFrame() # Start workers self._highlightWorker.startWorker() self._guiWorker.startWorker() # Remove spinners for textFrame in textFrames: textFrame.closeSpinner() # Update save button, if window has been opened again self._root.after(10, self._setSaveButtonState, tk.NORMAL) self._saving = False #################################### # View Creation def _addNewEmptyLineColor(self): # print("New Button " + str(self.newButtonRow)) self._newButton.grid(row=self._newButtonRow + 1) rowId = self._getRowId(self._newButtonRow) self._setsDict[rowId] = self._createSingleLineColorRow( self._lineColoringFrame, self._newButtonRow, rowId, "", "white") self._newButtonRow += 1 def _editLineColorRow(self, edit): # print("Last focus in " + self.lastFocusInRowId) # print("Last focus out " + self.lastFocusOutRowId) # If lastFocusIn is not the same as lastFocusOut, # we know that lastFocusIn is currently selected. if self._lastFocusInRowId != self._lastFocusOutRowId: if Sets.LINE_COLOR_MAP in self._lastFocusInRowId: # print("EDIT: " + self.lastFocusInRowId) # Get row number # TODO Use getRowNum?? rowNum = int( self._lastFocusInRowId.replace(Sets.LINE_COLOR_MAP, "")) # Find index of rows to edit indexToChange = list() if edit == self.EDIT_UP: if rowNum > 0: indexToChange = [rowNum - 1, rowNum] elif edit == self.EDIT_DOWN: if rowNum < (self._newButtonRow - 1): indexToChange = [rowNum, rowNum + 1] elif edit == self.EDIT_DELETE: indexToChange = range(rowNum, self._newButtonRow) if indexToChange: tempTextColorMap = list() for i in indexToChange: # Save regex and color rowId = self._getRowId(i) tempTextColorMap.append((self._setsDict[rowId].entries["regex"].var.get(), \ self._setsDict[rowId].entries["regex"].data, \ self._setsDict[rowId].entries["color"].var.get(), \ self._setsDict[rowId].entries["color"].data)) # Remove rows to edit from view self._setsDict[rowId].lineFrame.destroy() del self._setsDict[rowId] # Reorder or delete saved rows newRowNum = -1 if edit == self.EDIT_UP: tempTextColorMap[1], tempTextColorMap[ 0] = tempTextColorMap[0], tempTextColorMap[1] newRowNum = rowNum - 1 elif edit == self.EDIT_DOWN: tempTextColorMap[1], tempTextColorMap[ 0] = tempTextColorMap[0], tempTextColorMap[1] newRowNum = rowNum + 1 elif edit == self.EDIT_DELETE: deletedRowData = dict() deletedRowData["tagName"] = TF.createLineColorTagName( tempTextColorMap[0][0]) self._deletedLineColorRows.append(deletedRowData) del tempTextColorMap[0] # Recreate saved rows for i, (regexVar, regexData, colorVar, colorData) in enumerate(tempTextColorMap): rowId = self._getRowId(indexToChange[i]) self._setsDict[rowId] = self._createSingleLineColorRow( self._lineColoringFrame, indexToChange[i], rowId, regexVar, colorVar) self._setsDict[rowId].entries["regex"].data = regexData self._setsDict[rowId].entries["color"].data = colorData # If move up or down, refocus if newRowNum > -1: rowId = self._getRowId(newRowNum) self._focusInSet(rowId) # If delete, update row count and move newButton else: self._newButtonRow = self._newButtonRow - 1 self._newButton.grid(row=self._newButtonRow) self._lastFocusInRowId = "" self._updateExampleText(self.GROUP_LINE_COLORING) def _createLineColorRows(self, parent, lineColorMap): setDict = dict() for rowId in sorted(lineColorMap.keys()): rowNum = int(rowId.replace(Sets.LINE_COLOR_MAP, "")) setDict[rowId] = self._createSingleLineColorRow( parent, rowNum, rowId, lineColorMap[rowId]["regex"], lineColorMap[rowId]["color"]) return setDict def _createSingleLineColorRow(self, parent, row, rowId, regex, color): colorLine = self.LineColorSettingsLine(self.GROUP_LINE_COLORING) colorLine.lineFrame = tk.Frame(parent, highlightcolor=self.ROW_HIGHLIGHT_COLOR, highlightthickness=2) colorLine.lineFrame.grid(row=row, column=0) colorLine.lineFrame.bind("<Button-1>", partial(self._focusInSet, rowId)) colorLine.lineFrame.bind("<FocusOut>", partial(self._focusOut, rowId)) regexEntry = self.Entry(self.ENTRY_TYPE_REGEX, regex) entryName = "regex" regexEntry.label = tk.Label(colorLine.lineFrame, text="Regex") regexEntry.label.grid(row=0, column=0) regexEntry.label.bind("<Button-1>", partial(self._focusInSet, rowId)) regexEntry.var = tk.StringVar(colorLine.lineFrame) regexEntry.var.set(regex) regexEntry.observer = regexEntry.var.trace( "w", partial(self._validateInput, rowId, entryName)) regexEntry.input = tk.Entry(colorLine.lineFrame, textvariable=regexEntry.var, width=30, takefocus=False) regexEntry.input.grid(row=0, column=1) regexEntry.input.bind("<Button-1>", partial(self._focusInLog, rowId)) colorLine.entries[entryName] = regexEntry colorEntry = self.Entry(self.ENTRY_TYPE_COLOR, color) entryName = "color" colorEntry.label = tk.Label(colorLine.lineFrame, text="Color") colorEntry.label.grid(row=0, column=2) colorEntry.label.bind("<Button-1>", partial(self._focusInSet, rowId)) colorEntry.var = tk.StringVar(colorLine.lineFrame) colorEntry.var.set(color) colorEntry.observer = colorEntry.var.trace( "w", partial(self._validateInput, rowId, entryName)) colorEntry.input = tk.Entry(colorLine.lineFrame, textvariable=colorEntry.var, width=10, takefocus=False) colorEntry.input.grid(row=0, column=3) colorEntry.input.bind("<Button-1>", partial(self._focusInLog, rowId)) colorEntry.button = tk.Button(colorLine.lineFrame, bg=color, width=3, command=partial(self._getColor, rowId, entryName, True)) colorEntry.button.grid(row=0, column=4, padx=4) colorEntry.button.bind("<Button-1>", partial(self._focusInSet, rowId)) colorLine.entries[entryName] = colorEntry return colorLine def _createStandardRows(self, parent, setLines, startRow): setDict = dict() # Find longest entry in settings maxLen = 0 for setLine in setLines: setLen = len(str(self._settings.get(setLine.setId))) if setLen > maxLen: maxLen = setLen row = startRow for setLine in setLines: setRow = self.SettingsLine(setLine.setGroup) entry = self.Entry(setLine.setType, self._settings.get(setLine.setId)) entryName = "entry" # TODO Add frame and highlight to colors (remember column widths and alignment) entry.label = tk.Label(parent, text=setLine.setDisplayName) entry.label.grid(row=row, column=0, sticky=tk.W) ######## # Entry variable if setLine.setType == self.ENTRY_TYPE_INT: entry.var = tk.IntVar(parent) else: entry.var = tk.StringVar(parent) # Init entry var entry.var.set(self._settings.get(setLine.setId)) # TODO use tkinter validateCommand entry.observer = entry.var.trace( "w", partial(self._validateInput, setLine.setId, entryName)) ######## # Input field if setLine.setType == self.ENTRY_TYPE_TOGGLE: # TODO create better toggle values (link to specific settings) toggleButtonFrame = tk.Frame(parent) toggleButtonFrame.grid(row=row, column=1, sticky=tk.E + tk.W) toggleButtonFrame.grid_columnconfigure(0, weight=1) toggleButtonFrame.grid_columnconfigure(1, weight=1) onButton = tk.Radiobutton(toggleButtonFrame, text="On", variable=entry.var, indicatoron=False, value="on") onButton.grid(row=0, column=0, sticky=tk.E + tk.W) offButton = tk.Radiobutton(toggleButtonFrame, text="Off", variable=entry.var, indicatoron=False, value="off") offButton.grid(row=0, column=1, sticky=tk.E + tk.W) else: # TODO Find better solution for entry width entry.input = tk.Entry(parent, textvariable=entry.var, width=int(maxLen * 1.5), takefocus=False) entry.input.grid(row=row, column=1) ######## # Color button if setLine.setType == self.ENTRY_TYPE_COLOR: entry.button = tk.Button(parent, bg=self._settings.get(setLine.setId), width=3, command=partial( self._getColor, setLine.setId, entryName)) entry.button.grid(row=row, column=2, padx=4) setRow.entries[entryName] = entry setDict[setLine.setId] = setRow row += 1 return setDict #################################### # View Interaction def _focusOut(self, rowId, event): self._lastFocusOutRowId = rowId def _focusInSet(self, rowId, event=0): self._setsDict[rowId].lineFrame.focus_set() self._focusInLog(rowId, event) def _focusInLog(self, rowId, event=0): self._lastFocusInRowId = rowId if self._lastFocusOutRowId == rowId: self._lastFocusOutRowId = "" def _getColor(self, rowId, entry, highlight=False): if highlight: hg = self._setsDict[rowId].lineFrame.cget("highlightbackground") self._setsDict[rowId].lineFrame.config( highlightbackground=self.ROW_HIGHLIGHT_COLOR) currentColor = self._setsDict[rowId].entries[entry].button.cget("bg") if not self._isValidColor(currentColor): currentColor = None color = askcolor(initialcolor=currentColor, parent=self._view) if color[1] != None: self._setsDict[rowId].entries[entry].var.set(color[1]) self._setsDict[rowId].entries[entry].button.config(bg=color[1]) if highlight: self._setsDict[rowId].lineFrame.config(highlightbackground=hg) self._focusInLog(rowId) # class WidgetSize: # def __init__(self,width,height,posx,posy): # self.width = width # self.height = height # self.posx = posx # self.posy = posy # def _getWidgetSize_(self,widget): # width = widget.winfo_width() # height = widget.winfo_height() # posx = widget.winfo_x() # posy = widget.winfo_y() # return self.WidgetSize(width,height,posx,posy) def _tabChanged(self, event): self._view.focus_set() self._exampleText.tag_remove("sel", 1.0, tk.END) self._updateExampleText( self._tabList[self._tabControl.index("current")]) def _updateExampleText(self, group): ##################### # Setup # Delete all search tags self._exampleText.tag_delete(Sets.SEARCH_SELECTED_LINE_COLOR) self._exampleText.tag_delete(Sets.SEARCH_MATCH_COLOR) self._exampleText.tag_delete(Sets.SEARCH_SELECTED_COLOR) # Delete all current line color tags tagNames = self._exampleText.tag_names() for tagName in tagNames: if Sets.LINE_COLOR_MAP in tagName: self._exampleText.tag_delete(tagName) entryName = "entry" if group == self.GROUP_TEXT_AREA: # General text area try: tFont = Font(family=self._setsDict[Sets.TEXTAREA_FONT_FAMILY].entries[entryName].var.get(),\ size=self._setsDict[Sets.TEXTAREA_FONT_SIZE].entries[entryName].var.get()) self._exampleText.config(background=self._setsDict[Sets.TEXTAREA_BACKGROUND_COLOR].entries[entryName].var.get(),\ selectbackground=self._setsDict[Sets.TEXTAREA_SELECT_BACKGROUND_COLOR].entries[entryName].var.get(),\ foreground=self._setsDict[Sets.TEXTAREA_COLOR].entries[entryName].var.get(),\ font=tFont) lineWrapString = self._setsDict[ Sets.TEXTAREA_LINE_WRAP].entries[entryName].var.get() if lineWrapString == "on": self._updateExampleTextLineWrap(Sets.LINE_WRAP_ON) elif lineWrapString == "off": self._updateExampleTextLineWrap(Sets.LINE_WRAP_OFF) except tk.TclError: pass elif group == self.GROUP_SEARCH: searchString = "Main" # Create search tags self._exampleText.tag_configure(Sets.SEARCH_SELECTED_LINE_COLOR, \ background=self._setsDict[Sets.SEARCH_SELECTED_LINE_COLOR].entries[entryName].var.get(),\ selectbackground=util.lightOrDarkenColor(self._setsDict[Sets.SEARCH_SELECTED_LINE_COLOR].entries[entryName].var.get(),Sets.SELECTED_LINE_DARKEN_COLOR)) self._exampleText.tag_configure(Sets.SEARCH_MATCH_COLOR, \ background=self._setsDict[Sets.SEARCH_MATCH_COLOR].entries[entryName].var.get(),\ selectbackground=util.lightOrDarkenColor(self._setsDict[Sets.SEARCH_MATCH_COLOR].entries[entryName].var.get(),Sets.SELECTED_LINE_DARKEN_COLOR)) self._exampleText.tag_configure(Sets.SEARCH_SELECTED_COLOR, \ background=self._setsDict[Sets.SEARCH_SELECTED_COLOR].entries[entryName].var.get(), \ selectbackground=util.lightOrDarkenColor(self._setsDict[Sets.SEARCH_SELECTED_COLOR].entries[entryName].var.get(),Sets.SELECTED_LINE_DARKEN_COLOR)) # Do search countVar = tk.StringVar() results = list() start = 1.0 while True: pos = self._exampleText.search(searchString, start, stopindex=tk.END, count=countVar, nocase=False, regexp=False) if not pos: break else: results.append((pos, pos + "+" + countVar.get() + "c")) start = pos + "+1c" # Add search tags first = True for result in results: self._exampleText.tag_add(Sets.SEARCH_MATCH_COLOR, result[0], result[1]) if first: first = False self._exampleText.tag_add(Sets.SEARCH_SELECTED_COLOR, result[0], result[1]) selectLine = result[0].split(".")[0] self._exampleText.tag_add(Sets.SEARCH_SELECTED_LINE_COLOR, selectLine + ".0", selectLine + ".0+1l") if group == self.GROUP_LINE_COLORING or group == self.GROUP_SEARCH: # Get line color map from view tempLineColorMap = list() for rowId in sorted(self._setsDict.keys()): if Sets.LINE_COLOR_MAP in rowId: lineInfo = dict() lineInfo["regex"] = self._setsDict[rowId].entries[ "regex"].var.get() lineInfo["color"] = self._setsDict[rowId].entries[ "color"].var.get() lineInfo["tagName"] = TF.createLineColorTagName( lineInfo["regex"]) tempLineColorMap.append(lineInfo) # Apply new line colors for lineInfo in tempLineColorMap: self._exampleText.tag_configure(lineInfo["tagName"], foreground=lineInfo["color"]) countVar = tk.StringVar() start = 1.0 while True: pos = self._exampleText.search(lineInfo["regex"], start, stopindex=tk.END, count=countVar, nocase=False, regexp=True) if not pos: break else: self._exampleText.tag_add( lineInfo["tagName"], pos, pos + "+" + countVar.get() + "c") start = pos + "+1c" def _updateExampleTextLineWrap(self, lineWrapState): if lineWrapState == Sets.LINE_WRAP_ON: self._exampleText.config(wrap=tk.CHAR) else: self._exampleText.config(wrap=tk.NONE) #################################### # Entry Validation def _validateInput(self, rowId, entryName, *args): # Get variable try: settingsLine: self.SettingsLine = self._setsDict[rowId] entry: self.Entry = settingsLine.entries[entryName] varIn = entry.var.get() validationStatus = self.ENTRY_VALIDATION_OK except tk.TclError: # print("Tcl Error") validationStatus = self.ENTRY_VALIDATION_FAILED if validationStatus == self.ENTRY_VALIDATION_OK: # Check Colors if entry.data.entryType == self.ENTRY_TYPE_COLOR: if self._isValidColor(varIn): # print("Color " + str(color)) entry.button.config(background=varIn) validationStatus = self.ENTRY_VALIDATION_OK else: validationStatus = self.ENTRY_VALIDATION_FAILED # Check regex if entry.data.entryType == self.ENTRY_TYPE_REGEX: # Validate regex if self._isValidRegex(varIn): entry.data.validation.status = self.ENTRY_VALIDATION_OK else: entry.data.validation.status = self.ENTRY_VALIDATION_FAILED self._updateAllRegexEntries() validationStatus = entry.data.validation.status # Check font family if rowId == Sets.TEXTAREA_FONT_FAMILY: if self._isValidFontFamily(varIn): validationStatus = self.ENTRY_VALIDATION_OK else: validationStatus = self.ENTRY_VALIDATION_FAILED # Check font size if rowId == Sets.TEXTAREA_FONT_SIZE: if self._isValidFontSize(varIn): validationStatus = self.ENTRY_VALIDATION_OK else: validationStatus = self.ENTRY_VALIDATION_FAILED ####### # Update validation info if validationStatus == self.ENTRY_VALIDATION_OK: entry.data.validation.status = self.ENTRY_VALIDATION_OK entry.data.validation.backgroundColor = "white" entry.data.validation.infoText = "" elif validationStatus == self.ENTRY_VALIDATION_FAILED: entry.data.validation.status = self.ENTRY_VALIDATION_FAILED entry.data.validation.backgroundColor = "red" entry.data.validation.infoText = "Non-valid input." if not entry.data.entryType == self.ENTRY_TYPE_TOGGLE: entry.input.config( background=entry.data.validation.backgroundColor) infoText = "" for key in self._setsDict.keys(): for (entryKey, entryItem) in self._setsDict[key].entries.items(): if entryItem.data.validation.status != self.ENTRY_VALIDATION_OK: entryId = key + "_" + entryKey if infoText: infoText += "\n" infoText += entryId + ": " + entryItem.data.validation.infoText if infoText: self._optionsInfoLabel.config(text=infoText) self._setSaveButtonState(tk.DISABLED) else: self._optionsInfoLabel.config(text="") self._setSaveButtonState(tk.NORMAL) self._updateExampleText(settingsLine.group) def _isValidColor(self, colorString): isValid = True try: tk.Label(None, background=colorString) except tk.TclError: # print("Color Error") isValid = False return isValid def _isValidFontFamily(self, family): fontList = tk.font.families() return family in fontList def _isValidFontSize(self, size): isValid = True try: Font(size=size) except tk.TclError: # print("Font Size Error") isValid = False if isValid: if int(size) < 1: isValid = False return isValid def _isValidRegex(self, regex): isValid = True try: # re.compile(regex) # Tkinter does not allow all regex, so this cannot be used self._exampleText.search(regex, 1.0, stopindex=tk.END, regexp=True) except: isValid = False return isValid def _updateAllRegexEntries(self): # Get all regex regexList = list() for key in self._setsDict.keys(): try: value = self._setsDict[key].entries["regex"].var.get() regexList.append(value) except KeyError: pass # Find any duplicate entries regexListCount = Counter(regexList) regexDuplicateList = [ regex for regex, count in regexListCount.items() if count > 1 ] # Update all duplicate regex entries for key in self._setsDict.keys(): try: regexEntry = self._setsDict[key].entries["regex"] # Only update status if entry validation status is not currently failed if regexEntry.data.validation.status != self.ENTRY_VALIDATION_FAILED: # Mark duplicates if regexEntry.var.get() in regexDuplicateList: # print("New duplicate: " + regexEntry.var.get()) regexEntry.data.validation.status = self.ENTRY_VALIDATION_DUPLICATE regexEntry.data.validation.backgroundColor = "yellow" regexEntry.data.validation.infoText = "Duplicate regex entry not allowed." else: # Clear previous duplicates that are now valid if regexEntry.data.validation.status == self.ENTRY_VALIDATION_DUPLICATE: # print("Clear duplicate: " + regexEntry.var.get()) regexEntry.data.validation.status = self.ENTRY_VALIDATION_OK regexEntry.data.validation.backgroundColor = "white" regexEntry.data.validation.infoText = "" regexEntry.input.config( background=regexEntry.data.validation.backgroundColor) except KeyError: pass #################################### # Misc def _getRowId(self, rowNum): return Sets.LINE_COLOR_MAP + "{:02d}".format(rowNum)
def __init__(self, *args, **kwargs): ''' node_name: The name of this node. Usually set by ModelNode.__setattr__ automatically. figure_meta: Meta information of figure. The rest parameters are passed to PanedWindow.__init__. ''' node_name = kwargs.pop('node_name', '') super().__init__(node_name=node_name) figure_meta = None if 'figure_meta' not in kwargs \ else kwargs.pop('figure_meta') kwargs['orient'] = 'horizontal' paned_window = PanedWindow(*args, **kwargs) paned_window.config(sashwidth=4, sashrelief='groove', bg='forestgreen') # figureTabsStyle = Style() # figureTabsStyle.configure('Figure.TNotebook', tabposition='sw') # figureTabs = Notebook(paned_window, style='Figure.TNotebook') figureTabs = Notebook(paned_window) self.figureTabs = figureTabs figureTabs.bind('<<NotebookTabChanged>>', self._on_tab_change) self.lock_attribute('figureTabs') if figure_meta: self.make_figures(figure_meta) self.lock_elements() paned_window.add(figureTabs, stretch='always') listPan = PanedWindow(paned_window, orient='vertical') listPan.config(sashwidth=4, sashrelief='groove', bg='forestgreen') paned_window.add(listPan, stretch='never') listFrm = Frame(listPan) listPan.add(listFrm, stretch='always') Label(listFrm, text='Curves', bg='#b5d6b0').pack(side='top', fill='x') self.__list = ScrolledList(listFrm, relief='groove') self.__list.list_config(width=20) self.__list.list_click_callback = self._on_list_click self.__list.pack(fill='both', expand='yes') listFrm = Frame(listPan) listPan.add(listFrm, stretch='never') Label(listFrm, text='Indicators', bg='#b5d6b0').pack(side='top', fill='x') self.__indicator_listbox = ScrolledList(listFrm, relief='groove') self.__indicator_listbox.list_config(width=20) self.__indicator_listbox.pack(fill='both', expand='yes') with self.attribute_lock: set_attributes(self, paned_window = paned_window, grid_group_observer = self.GridGroupObserver(self), axis_group_observer = self.AxisGroupObserver(self), clear_group_observer = self.ClearGroupObserver(self), label_group_observer = self.LabelGroupObserver(self), indicator_group_observer = self.IndicatorGroupObserver(self), data_figure_observer = self.DataFigureObserver(self), data_pool = [] )
root = Tk() root.wm_title("Arduino Tables") root.wm_iconbitmap('../_static/ben1.ico') root.geometry('+170+200') s = Style() s.theme_use('clam') #csvDelimiter = '$' fr = Frame(root) fr.pack(fill='both', expand=1) nb = Notebook(fr) nb.pack(fill='both', padx=2, pady=3, expand=1) nb.bind("<<NotebookTabChanged>>", on_tab_changed) nb.enable_traversal() page1 = Frame(nb) csvfiles = [] for file in glob("../csv_data/*.csv"): csvfiles.append(file) #csv_value = StringVar() #cb = Combobox(page1, values=csvfiles, state="readonly", #textvariable=csv_value, width=30) #cb.set(csvfiles[0]) #cb.grid(column=0, row=1) #cb.bind('<<ComboboxSelected>>', csvSel) nb.add( page1,
class TabsPanel(Frame): """All tabs in main screen""" def __init__(self, parent, app): Frame.__init__(self, parent) self.app = app self.initUI() def initUI(self): # self.tabs = [] # init tabs self.tab = Notebook(self) self.tab.bind('<<NotebookTabChanged>>', self.on_tab_changed) created_tab = [ self.make_code_tab(), self.make_triples_tab(), self.make_upload_tab(), self.make_download_tab(), ] for frame, name in created_tab: self.tab.add(frame, text=name) self.tab.grid(column=0, row=0) def updateUI(self): self.check_code_modified() self.check_triples_exist() def make_code_tab(self): f = Frame(self.tab) Label(f, text='Open .c file or paste code here').pack() self.code_edit = scrolledtext.ScrolledText(f, wrap="word", width=70, height=20) self.code_edit.pack() self.code_var = StringVar(self.code_edit) attach_StrVar_to_Text(self.code_var, self.code_edit) # listen code changes self.code_var.trace_add('write', self.check_code_modified) self.code_used_str = None self.code_modified = False self.code_modified_label = Label(f, text='no code yet...', justify='left') # self.code_modified_label.pack(expand=True, fill=X) self.code_modified_label.pack(side=LEFT) self.get_triples_button = Button(f, text="Convert code to triples ...", padx="15", bg='#bbddbb', command=self.on_get_triples_button) self.get_triples_button.pack(side=RIGHT) # self.code_modified_label["text"] = 'ABCDE!' self.load_file('default.c') return (f, 'Code') def load_file(self, filepath): try: with open(filepath) as f: t = f.read() self.code_var.set(t) self.code_modified_label["text"] = "loaded file: " + filepath except: err_msg = "file no found: " + filepath self.code_modified_label["text"] = err_msg print(err_msg) if hasattr(self, "triples_list"): # tabs not ready workaround self.tab.select(0) def check_code_modified(self, *_): if self.code_var.get() == self.code_used_str: text = 'code not modified' self.code_modified = False else: text = 'code was changed' self.code_modified = True button_state = NORMAL if self.code_modified else DISABLED self.get_triples_button["state"] = button_state if self.code_used_str is None: text = 'no code in use' self.code_modified = False self.code_modified_label["text"] = text def on_get_triples_button(self): self.code_used_str = self.code_var.get() self.code_modified = False # call app action ... error = self.app.parse_code(self.code_used_str) if error: messagebox.showinfo('Code error', error) # print(error) self.code_used_str = None return triples, error = self.app.get_code_triples() if error: messagebox.showinfo('Triples obtaining error', error) # print(error) self.code_used_str = None return self.triples_list = triples self.tab.select(1) self.set_upload_status("Ready to upload triples to server") def on_format_code(self): self.tab.select(0) # call app action ... error = self.app.parse_code(self.code_var.get()) if error: messagebox.showinfo('Code parse error', error) self.highlight_char_by_error(error) else: formatted_code = self.app.get_code_norm_format() self.code_var.set(formatted_code) def highlight_char_by_error(self, err_string): sep = ':' # print(err_string) dd = err_string.strip(sep).split(sep) # print(dd) try: r, c = dd[:2] r = int(r) c = int(c) except: return # f = "%d.%d" % (r,c) # t = "%d.%d" % (r,c+1) f = "%d.0" % (r, ) t = "%d.end" % (r, ) # self.code_edit.selection_set(f,t) # print(f,t) self.code_edit.tag_add(SEL, f, t) def make_triples_tab(self): f = Frame(self.tab) Label( f, text= 'Triples obtained from code. Changes to this text have no effect on stored triples.' ).pack() self.triples_edit = scrolledtext.ScrolledText(f, wrap="word", width=70, height=20) self.triples_edit.pack() self.triples_list = None self.triples_count_label = Label( f, text='Click "Code to Triples" button first', justify='left') self.triples_count_label.pack(side=LEFT) self.goto_upload_button = Button(f, text="Proceed to upload ...", padx="15", bg='#bbddbb', command=lambda *_: self.tab.select(2)) self.goto_upload_button.pack(side=RIGHT) return (f, 'Triples') def check_triples_exist(self): button_state = NORMAL if self.triples_list else DISABLED self.goto_upload_button["state"] = button_state self.run_upload_button["state"] = button_state if self.triples_list: count_text = 'Triples count: %d' % len(self.triples_list) else: count_text = 'No triples' self.triples_count_label["text"] = count_text self.show_triples() def show_triples(self): if self.triples_list: triples_str = '\n'.join(map(str, self.triples_list)) else: triples_str = 'No triples generated from code' self.triples_edit.delete(1.0, END) self.triples_edit.insert(1.0, triples_str) def make_upload_tab(self): f = Frame(self.tab) Label(f, text='Set up connection and click "Upload"').pack() # Remote configuration g = LabelFrame(f, text="Remote configuration") row = 0 Label(g, text='Stardog server location:').grid(row=row, column=0, rowspan=1, sticky=E, padx=20, pady=5) self.server_url_var = StringVar() serv_url = Entry(g, width=60, textvariable=self.server_url_var) self.server_url_var.set("http://localhost:5820") serv_url.grid(row=row, column=1, sticky=W) row += 1 Label(g, text='(Using default username & password: admin, admin)').grid( row=row, column=0, columnspan=2) row += 1 Label(g, text='Stardog database name:').grid(row=row, column=0, rowspan=1, sticky=E, padx=20, pady=5) self.server_dbname_var = StringVar() serv_dbname = Entry(g, width=60, textvariable=self.server_dbname_var) self.server_dbname_var.set("sem_alg_db") serv_dbname.grid(row=row, column=1, sticky=W) row += 1 Label(g, text='Ontology schema file:').grid(row=row, column=0, rowspan=1, sticky=E, padx=20, pady=5) self.schema_file_var = StringVar() serv_dbname = Entry(g, width=60, textvariable=self.schema_file_var) self.schema_file_var.set("c_schema_2020-01.rdf") serv_dbname.grid(row=row, column=1, sticky=W) row += 1 self.server_db_create_var = BooleanVar() self.server_db_create_var.set(1) chk = Checkbutton(g, text="Create a new DB on server", variable=self.server_db_create_var, onvalue=1, offvalue=0) chk.grid(row=row, column=1, sticky=W) row += 1 self.server_db_drop_var = BooleanVar() self.server_db_drop_var.set(0) chk = Checkbutton(g, text="Drop DB on closing connection", variable=self.server_db_drop_var, onvalue=1, offvalue=0) chk.grid(row=row, column=1, sticky=W) # text="Drop DB after whole data export" g.pack(expand=1, padx=20, fill=X) self.run_upload_button = Button(f, text="Upload !", bg='#ff99dd', command=self.on_upload_button) self.run_upload_button.pack(expand=1, fill=BOTH, padx=50, pady=25) self.upload_status_label = Label(f, text='No upload performed', justify='left') self.upload_status_label.pack(side=LEFT) return (f, 'Upload data') def make_download_tab(self): f = Frame(self.tab) Label(f, text='Click "Download" to export ontology and store locally' ).pack() # Export configuration g = LabelFrame(f, text="Export configuration") row = 0 Label(g, text='Source database name:').grid(row=row, column=0, rowspan=1, sticky=E, padx=20, pady=5) self.export_dbname_label = Label(g, width=60, text='~ run upload first ~') self.export_dbname_label.grid(row=row, column=1, sticky=W) row += 1 Label(g, text='Save .ttl file as:').grid(row=row, column=0, rowspan=1, sticky=E, padx=20, pady=5) self.save_filename_var = StringVar() save_filename = Entry(g, width=60, textvariable=self.save_filename_var) self.save_filename_var.set("exported_onto") save_filename.grid(row=row, column=1, sticky=W) g.pack(expand=1, padx=20, fill=X, side=TOP) self.run_download_button = Button(f, text="Download ontology", bg='#dd99ff', command=self.on_download_button) self.run_download_button.pack(expand=1, fill=BOTH, padx=50, pady=5) self.run_download_button["state"] = DISABLED self.download_status_label = Label(f, text='No download performed', justify='left') self.download_status_label.pack(side=LEFT) return (f, 'Export ontology') def get_conn_details(self): conn_details = { 'endpoint': self.server_url_var.get(), 'username': '******', 'password': '******', 'schemafile': self.schema_file_var.get(), 'dbname': self.server_dbname_var.get(), 'createdb': self.server_db_create_var.get(), 'dropdb': self.server_db_drop_var.get(), } return conn_details def on_upload_button(self): self.set_upload_status("Upload in progress ...") self.app.set_connection_details(self.get_conn_details()) error = self.app.upload_triples( self.triples_list, progress_callback=self.set_upload_status) if error: messagebox.showinfo('Upload error', error) self.set_upload_status("Upload error") else: self.set_upload_status("Upload success") self.run_download_button["state"] = NORMAL self.export_dbname_label["text"] = self.server_dbname_var.get() self.tab.select(3) def set_upload_status(self, text): self.upload_status_label["text"] = str(text) def set_download_status(self, text): self.download_status_label["text"] = str(text) def on_download_button(self): save_as_fnm = self.save_filename_var.get() if not save_as_fnm: messagebox.showinfo('Please specify a filename!', error) self.set_download_status('Incorrect fields') self.set_download_status("Download in progress ...") self.app.set_connection_details(self.get_conn_details()) error = self.app.download_ontology( save_as_fnm, progress_callback=self.set_download_status) if error: messagebox.showinfo('Download error', error) self.set_download_status("Download error") else: self.set_download_status("Download success") def on_tab_changed(self, ev): # print('on_tab_changed:') # print(ev) self.updateUI()
height=tc1.winfo_reqheight(), width=tc1.winfo_reqwidth()) def on_click(event): clicked_tab = nb1.tk.call(nb1._w, "identify", "tab", event.x, event.y) if clicked_tab == 0: clicked_tab = 'one' if clicked_tab == 1: clicked_tab = 'two' if clicked_tab == 2: clicked_tab = 'three' lbl1['text'] = 'Tab '+clicked_tab+' was clicked' nb1 = Notebook(root, style='green.TNotebook') nb1.bind("<<NotebookTabChanged>>", tab_changed) nb1.grid(row=0, column=0) nb1.enable_traversal() lbl1 = Label(root, text='ready') lbl1.grid(row=5, column=0) nb1.bind('<Button-1>', on_click) # first page page1 = Frame(root, background='red', height=70*mult) enabler = Button(page1, text='Enable Tab two\n Test it out', command=lambda: nb1.tab(1, state='normal')) enabler.pack(ipadx=5, ipady=5) nb1.add(page1, text='one', underline=0, padding=2)
class AppLauncher: def __init__(self): self.__root = Tk() self.__notebook = Notebook() if user32: self.__notebook.bind("<Map>", self._maximizeUnderWindows) @property def root(self): return self.__root def run(self, entry, baseTabLoader = BaseTabLoader()): self.__configurationFiles = self._createConfigurationInstances() self._loadConfigurationFiles() self._upgradeConfigurationFiles() Config["version"] = __version__ self._createStyles() self._createLayouts() self._configureRoot() CommonUIComponents.init(**self._getCommonUIComponentsInitParams()) SmartWidget.setFont() sys.path.append(path.dirname(path.dirname(path.abspath(entry)))) baseTabLoader.load(self.__notebook, Config.INSTANCE.json, Storage.INSTANCE.json) self.__notebook.place(relwidth = 1, relheight = 1) Global.appLauncher = self self.__root.mainloop() def _configureRoot(self): self.__root.geometry(f"{self.__root.winfo_screenwidth()}x{self.__root.winfo_screenheight()}") # # There's a bug under Linux: if height == False, window contents # aren't centered vertically. Moreover, the app must be maximized # under Windows, otherwise vertical scrollbars don't scroll content # to the end. # self.__root.resizable(False, True) self.__root.title(Config["title"]) self.__root.protocol("WM_DELETE_WINDOW", self._onDeleteWindow) def _createConfigurationInstances(self): _ = self return {"config": Config(), "storage": Storage()} def _createStyles(self): font = Config["widgetFont"] self.__root.style = Style() self.__root.style.configure(".", font = font) self.__root.style.configure("TButton", padding = [12, 7]) self.__root.style.configure("TNotebook.Tab", padding = [13, 7]) self.__root.style.configure("Horizontal.TScale", sliderthickness = 25) self.__root.style.configure("Horizontal.TScrollbar", arrowsize = 25) self.__root.style.configure("Vertical.TScrollbar", arrowsize = 25) self.__root.style.configure("TSpinbox", arrowsize = 30) self.__root.option_add('*TCombobox*Listbox.font', font) colors = { "Cyan": "cyan", "LGreen": "lightgreen", "Pink": "pink", "Yellow": "yellow" } styles = { "": "Frame", "Labeled": "Labelframe" } for style in styles.items(): for color in colors.items(): self.__root.style.configure(f"{color[0]}.T{style[0]}Container.TBaseContainer.T{style[1]}", background = color[1]) def _createLayouts(self): name = "Scrollbar" for orient in ("Horizontal", "Vertical"): self.__root.style.layout(f"{orient}.T{name}.T{name}", self.__root.style.layout(f"{orient}.T{name}")) def _getCommonUIComponentsInitParams(self): _ = self return dict() def _loadConfigurationFiles(self): for configurationFile in self.__configurationFiles.values(): configurationFile.load() def _maximizeUnderWindows(self, _): _ = self user32.ShowWindow(user32.GetForegroundWindow(), 3) def _onDeleteWindow(self): for name in self.__notebook.tabs(): self.__notebook.nametowidget(name).onDeleteWindow() for configurationFile in self.__configurationFiles.values(): configurationFile.dump() self.__root.destroy() def _upgradeConfigurationFiles(self): for configurationFile in self.__configurationFiles.values(): configurationFile.upgrade(Config.INSTANCE.json.get("version", "1.6.7"))
def __init__(self, *args, **kwargs): ''' node_name: The name of this node. Usually set by ModelNode.__setattr__ automatically. figure_meta: Meta information of figure. The rest parameters are passed to PanedWindow.__init__. ''' node_name = kwargs.pop('node_name', '') super().__init__(node_name=node_name) self.__selected_curve = (None, None) figure_meta = None if 'figure_meta' not in kwargs \ else kwargs.pop('figure_meta') kwargs['orient'] = 'horizontal' paned_window = PanedWindow(*args, **kwargs) paned_window.config(sashwidth=4, sashrelief='groove', bg='forestgreen') # figureTabsStyle = Style() # figureTabsStyle.configure('Figure.TNotebook', tabposition='sw') # figureTabs = Notebook(paned_window, style='Figure.TNotebook') figureTabs = Notebook(paned_window) self.figureTabs = figureTabs figureTabs.bind('<<NotebookTabChanged>>', self._on_tab_change) self.lock_attribute('figureTabs') if figure_meta: self.make_figures(figure_meta) self.lock_elements() paned_window.add(figureTabs, stretch='always') listPan = PanedWindow(paned_window, orient='vertical') listPan.config(sashwidth=4, sashrelief='groove', bg='forestgreen') paned_window.add(listPan, stretch='never') listFrm = Frame(listPan) listPan.add(listFrm, stretch='always') Label(listFrm, text='Curves', bg='#b5d6b0').pack(side='top', fill='x') self.__list = ScrolledList(listFrm, relief='groove') self.__list.list_config(width=20) self.__list.list_click_callback = self._on_list_click self.__list.pack(fill='both', expand='yes') listFrm = Frame(listPan) listPan.add(listFrm, stretch='never') Label(listFrm, text='Indicators', bg='#b5d6b0').pack(side='top', fill='x') self.__indicator_listbox = ScrolledList(listFrm, relief='groove') self.__indicator_listbox.list_config(width=20) self.__indicator_listbox.pack(fill='both', expand='yes') with self.attribute_lock: set_attributes( self, paned_window=paned_window, grid_group_observer=self.GridGroupObserver(self), axis_group_observer=self.AxisGroupObserver(self), clear_group_observer=self.ClearGroupObserver(self), label_group_observer=self.LabelGroupObserver(self), indicator_group_observer=self.IndicatorGroupObserver(self), data_figure_observer=self.DataFigureObserver(self), data_pool=[])
def __init__(self, *args, **kwargs): Tk.__init__(self, *args, **kwargs) self.activeTab = 0 self.geometry("775x550") self.title("Pedalbox") # self.iconbitmap("assets/pedal.ico") self.serial_data = '' self.filter_data = '' # Main Container container = Frame(self, bg='white') container.pack(fill="both") tablayout = Notebook(container) ################################################################ ## tab1 tab1 = Frame(tablayout, bg='white') tab1.pack(fill="both") clutch_cluster = ClutchCluster(tab1, self) brake_cluster = BrakeCluster(tab1, self) throttle_cluster = ThrottleCluster(tab1, self) clutch_cluster.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") brake_cluster.grid(row=0, column=1, padx=10, pady=10, sticky="nsew") throttle_cluster.grid(row=0, column=2, padx=10, pady=10, sticky="nsew") tab1.grid_columnconfigure(0, weight=1) tab1.grid_columnconfigure(1, weight=1) tab1.grid_columnconfigure(2, weight=1) tablayout.add(tab1, text="Clusters") ################################################################ # tab2 tab2 = Frame(tablayout, bg='white') tab2.pack(fill="both", expand=1) clutch = Clutch(tab2, self) brake = Brake(tab2, self) throttle = Throttle(tab2, self) clutch.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") brake.grid(row=0, column=1, padx=10, pady=10, sticky="nsew") throttle.grid(row=0, column=2, padx=10, pady=10, sticky="nsew") tab2.grid_columnconfigure(0, weight=1) tab2.grid_columnconfigure(1, weight=1) tab2.grid_columnconfigure(2, weight=1) tablayout.add(tab2, text="Settings") tablayout.pack(fill="both", expand=1) ################################################################ # tab3 tab3 = Frame(tablayout, bg='white') tab3.pack(fill="both", expand=1) serial_port_settings = SerialPort(tab3, self) serial_port_settings.grid(row=0, column=0, padx=10, pady=10, sticky="nsew") tablayout.add(tab3, text="config") tablayout.pack(fill="both", expand=1) tablayout.bind("<<NotebookTabChanged>>", lambda event: self.tab_changed(tablayout)) connect_button = Button( self, text="connect serial port", command=lambda: serial_connect(self, get_connection_info()[1], get_connection_info()[0])) connect_button.pack() disconect_button = Button(self, text="disconect serial port", command=serial_disconect) disconect_button.pack() pub.subscribe(get_map_update_clutch, 'clutch_map_update') pub.subscribe(get_map_update_brake, 'brake_map_update') pub.subscribe(get_map_update_throttle, 'throttle_map_update')
class App: # need it for generate reports __ast = None __sym_table = None __sym_table_3d = None def __init__(self, ide): # setting title ide.title("TenorC @danii_mor") # setting window size width=700 height=400 screenwidth = ide.winfo_screenwidth() screenheight = ide.winfo_screenheight() alignstr = '%dx%d+%d+%d' % (width, height, (screenwidth - width) / 2, (screenheight - height) / 2) ide.geometry(alignstr) ide.resizable(width=True, height=True) # create menubar menubar = Menu(ide) # file menu filemenu = Menu(menubar, tearoff=0) filemenu.add_command(label="New", command=self.newFile) filemenu.add_command(label="Open", command=self.file_open) filemenu.add_command(label="Save", command=self.file_save) filemenu.add_command(label="Save as...", command=self.file_save_as) filemenu.add_command(label="Close", command=self.exitTab) filemenu.add_separator() filemenu.add_command(label="Exit", command=ide.quit) # edit menu editmenu = Menu(menubar, tearoff=0) editmenu.add_command(label="Cut", command=self.donothing) editmenu.add_command(label="Copy", command=self.copy_to_clipboard) editmenu.add_command(label="Paste", command=self.donothing) editmenu.add_separator() editmenu.add_command(label="Find", command=self.donothing) editmenu.add_command(label="Replace", command=self.donothing) # run menu runmenu = Menu(menubar, tearoff=0) runmenu.add_command(label="Execute Analysis", command=self.execute_current_tab_lef) runmenu.add_command(label="Show Intermediate Code", command=self.show3D) runmenu.add_separator() runmenu.add_command(label="Symbol Table", command=self.show_sym_table) runmenu.add_command(label="Error Report", command=self.show_error) runmenu.add_command(label="Abstract Syntax Tree", command=self.show_ast) runmenu.add_command(label="Grammar", command=self.show_grammar) runmenu.add_separator() runmenu.add_command(label="Debugging", command=self.execute_debug) # option menu #optionmenu = Menu(menubar, tearoff=0) #optionmenu.add_command(label="Theme...", command=self.donothing) #optionmenu.add_command(label="Line Numbers...", command=self.donothing) # help menu helpmenu = Menu(menubar, tearoff=0) helpmenu.add_command(label="Help", command=self.donothing) helpmenu.add_command(label="About...", command=self.show_info) # setting menu menubar.add_cascade(label="File", menu=filemenu) menubar.add_cascade(label="Edit", menu=editmenu) menubar.add_cascade(label="Run", menu=runmenu) menubar.add_cascade(label="Help", menu=helpmenu) ide.config(menu=menubar) # setting editor area self.tabs = Notebook(ide) f1 = Frame(self.tabs) self.tabs.add(f1, text="+") self.tabs.pack(side="top", fill="both", expand=True, padx=10, pady=0) self.tabs.bind("<<NotebookTabChanged>>", self.addTab) # setting terminal area self.terminal= Text(ide) ft = tkFont.Font(family="Lucinda Console", size=10) self.terminal["font"] = ft self.terminal["wrap"] = "word" self.terminal["fg"] = "white" self.terminal["bg"] = "black" self.terminal["insertbackground"] ="white" self.terminal["height"] = 5 self.terminal["width"] = 5 self.terminal.pack( side = "left", fill = "both", expand=True, padx=10, pady=10) terminal_scroll = Scrollbar(ide) terminal_scroll["orient"] = "vertical" terminal_scroll["command"] = self.terminal.yview terminal_scroll.pack(side="right", fill="y") self.terminal.configure(yscrollcommand=terminal_scroll.set) self.terminal.bind("<Return>", self.execute_command) def copy_to_clipboard(self): selectedTab = self.tabs.index("current") currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea try: selected_text= currentTextArea.get("sel.first", "sel.last") currentTextArea.clipboard_append(selected_text) except: pass def show_grammar(self): if self.__sym_table: window = Toplevel() window['bg'] = 'black' productions = self.__sym_table.getGrammar() keys = list(productions.keys()) keys.sort() grammar = Message(window) txt = '' for production in keys: txt += productions[production] + '\n' grammar['fg'] = 'white' grammar['bg'] = 'black' grammar['text'] = txt grammar.pack(side='left') def show_error(self): if self.__sym_table: if self.__sym_table.error != '': window = Toplevel() window['bg'] = 'black' grammar = Message(window) grammar['fg'] = 'white' grammar['bg'] = 'black' grammar['text'] = self.__sym_table.error grammar.pack(side='left') else: window = Toplevel() window['bg'] = 'black' grammar = Message(window) grammar['fg'] = 'white' grammar['bg'] = 'black' grammar['text'] = 'Not Errors Found' grammar.pack(side='left') # TODO fix it def show_sym_table(self): if self.__sym_table: showTable(self.__sym_table) def show_ast(self): self.__ast.graph() showAST() codeGenerated = None def show3D(self): if self.codeGenerated != None: window = Toplevel() window['bg'] = 'black' grammar = Text(window) grammar['fg'] = 'white' grammar['bg'] = 'black' grammar.insert(1.0, self.codeGenerated) grammar.pack(side='left') def show_info(self): window = Toplevel() window['bg'] = 'black' grammar = Message(window) grammar['fg'] = 'white' grammar['bg'] = 'black' grammar['text'] = 'Augus intermediate code by Engr. Espino\nTenorC 1.23.2a Developed by @danii_mor\n 201314810' grammar.pack(side='left') def update_line_debugg(self, event= None): self.count["text"] = "Line: %s" % str(self.c+1) lines = self.codeGenerated.split('\n') # start execute line by self.c counter ply_left_3d = titus.parse() if self.c < len(lines): if "main:" not in lines[self.c]: line = "main:" + lines[self.c] result = ply_left_3d(titus, line) if result: ast = result[0] ast.setType("LABEL") ast.setValue("S") ast.root = result[0] if self.__sym_table_3d != None: new_table = {**self.__sym_table_3d.printTable(), **result[1].printTable()} for sym_id in new_table: sym = new_table[sym_id] if sym != None: if type(sym) == dict: continue if sym.getValue() == None: try: new_table[sym_id] = self.__sym_table_3d.printTable()[sym_id] except: pass self.__sym_table_3d.setTable({**self.__sym_table_3d.printTable(), **new_table}) else: self.__sym_table_3d = result[1] # define mode for syntax-tree know how to autoexecute self.__sym_table_3d.setMode(1) compute = [None, None] # start execute self.__sym_table_3d.terminal = self.terminal compute = ast.start_execute(self.__sym_table_3d, "MAIN") # lookup the last line index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True) txt = self.terminal.get(str(index),'end-1c') if txt == "": index ="1.0" else: index = self.terminal.index("%s+1c" % index) if compute[0]: self.terminal.insert(str(float(index)+1), compute[0]) self.__sym_table_3d.cleanLog() if compute[1]: goto_line = 0 for l in lines: if (compute[1]+":") in l: break goto_line = goto_line + 1 self.c = goto_line - 1 if self.__sym_table != None: if self.__sym_table.error != '': # lookup the last line index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True) txt = self.terminal.get(str(index),'end-1c') if txt == "": index ="1.0" else: index = self.terminal.index("%s+1c" % index) self.terminal.insert(str(float(index)+1), "\nTenorC>> Error Report Generated\n") self.c = self.c + 1 self.label_last_line["text"] = "Line: %s" % str(self.c+1) c = 0 def execute_debug(self, event = None): self.__sym_table_3d = None self.c = 0 # create debug player window = Toplevel() window['bg'] = 'black' label_count = Label(window, text="Execute Now:", borderwidth=0, width=10, bg = "black", fg = "white") label_count.grid(row=0, column=0, sticky="nsew", padx=1, pady=1) label_last = Label(window, text="Executed Before:", borderwidth=0, width=10, bg = "black", fg = "white") label_last.grid(row=0, column=2, sticky="nsew", padx=1, pady=1) self.label_last_line = Label(window, text="Line: 1", borderwidth=0, width=10, bg = "black", fg = "white") self.label_last_line.grid(row=1, column=0, sticky="nsew", padx=1, pady=1) execute = Button(window, text='>', command=self.update_line_debugg) execute.grid(row=1, column=1, sticky="nsew", padx=1, pady=1) self.count = Label(window, text="Line: 0", borderwidth=0, width=10, bg = "black", fg = "white") self.count.grid(row=1, column=2, sticky="nsew", padx=1, pady=1) window.grid_columnconfigure(0, weight=1) window.grid_columnconfigure(1, weight=1) window.grid_columnconfigure(2, weight=1) window.resizable(width=True, height=False) # get all txt from current tab selectedTab = self.tabs.index("current") currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea input = currentTextArea.get('1.0','end-1c') # new singleton symbol table self.__sym_table = table() # define mode for syntax-tree know how to autoexecute self.__sym_table.setMode(0) # start lex and sintactic analysis ply_left = tenorC.parse() self.__ast = ply_left(tenorC, input, self.__sym_table) # TODO sintax error recover if self.__ast != None: self.__ast.execute(self.__sym_table) self.codeGenerated = self.__ast.get3D() def execute_current_tab_lef(self): # get all txt from current tab selectedTab = self.tabs.index("current") currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea input = currentTextArea.get('1.0','end-1c') # new singleton symbol table self.__sym_table = table() # define mode for syntax-tree know how to autoexecute self.__sym_table.setMode(0) # start lex and sintactic analysis ply_left = tenorC.parse() self.__ast = ply_left(tenorC, input, self.__sym_table) # TODO sintax error recover if self.__ast != None: self.__ast.execute(self.__sym_table) self.codeGenerated = self.__ast.get3D() ## start executing ply_left_3d = titus.parse() result = ply_left_3d(titus, self.codeGenerated) if result: ast_3D = result[0] ast_3D.setType("LABEL") ast_3D.setValue("S") ast_3D.root = True self.__sym_table_3d = result[1] # define mode for syntax-tree know how to autoexecute self.__sym_table_3d.setMode(1) goto_called = True start_from = "MAIN" compute = [None, None] while goto_called: goto_called = False self.__sym_table_3d.terminal = self.terminal compute = ast_3D.start_execute(self.__sym_table_3d, start_from) # lookup the last line index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True) txt = self.terminal.get(str(index),'end-1c') if txt == "": index ="1.0" else: index = self.terminal.index("%s+1c" % index) if compute[0]: self.terminal.insert(str(float(index)+1), compute[0]) self.__sym_table_3d.cleanLog() if compute[1]: goto_called = True start_from = compute[1] elif self.__sym_table.error != '': # lookup the last line index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True) txt = self.terminal.get(str(index),'end-1c') if txt == "": index ="1.0" else: index = self.terminal.index("%s+1c" % index) self.terminal.insert(str(float(index)+1), "\nTenorC>> Error Report Generated\n") def execute_command(self, event): # lookup the last line index = self.terminal.search(r'\n', "insert", backwards=True, regexp=True) input = self.terminal.get(str(index),'end-1c') if input == "": index ="1.0" else: index = self.terminal.index("%s+1c" % index) input = self.terminal.get(index,'end-1c') # send the input to the calculate self.__sym_table_3d.read_input.set(input) def newFile(self): lastindex = self.tabs.index("end")-1 textarea = Editor(self.tabs) self.tabs.insert(lastindex, textarea, text="Tab" + str(lastindex+1)) self.tabs.select(lastindex) def exitTab(self): result = self.save_if_modified() if result != None: #None => Aborted or Save cancelled, False => Discarded, True = Saved or Not modified selectedTab = self.tabs.index("current") currentTab = self.tabs.winfo_children()[selectedTab+1] self.tabs.select(self.tabs.winfo_children()[selectedTab]) currentTab.destroy() def save_if_modified(self, event=None): selectedTab = self.tabs.index("current") currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea if currentTextArea.edit_modified(): #modified response = messagebox.askyesnocancel("Save?", "This document has been modified. Do you want to save changes?") #yes = True, no = False, cancel = None if response: #yes/save result = self.file_save() if result == "saved": #saved return True else: #save cancelled return None else: return response #None = cancel/abort, False = no/discard else: #not modified return True def file_open(self, event=None, filepath=None): if filepath == None: filepath = filedialog.askopenfilename() if filepath != None and filepath != '': with open(filepath, encoding="utf-8") as f: fileContents = f.read()# Get all the text from file. # Set current text to a new Tab file contents lastindex = self.tabs.index("end")-1 textarea = Editor(self.tabs) self.tabs.insert(lastindex, textarea, text="Tab" + str(lastindex+1)) self.tabs.select(lastindex) textarea.textarea.insert(1.0, fileContents) textarea.textarea.edit_modified(False) tab_tittle = os.path.basename(filepath) self.tabs.tab(lastindex, text = tab_tittle) def file_save(self, event=None): selectedTab = self.tabs.index("current") currentName = self.tabs.tab(selectedTab, "text") if 'Tab' in currentName: result = self.file_save_as() else: result = self.file_save_as(filepath='./' + currentName) return result def file_save_as(self, event=None, filepath=None): if filepath == None: filepath = filedialog.asksaveasfilename(filetypes=(('Text files', '*.txt'), ('C files', '*.mc'), ('All files', '*.*'))) #defaultextension='.txt' try: with open(filepath, 'wb') as f: selectedTab = self.tabs.index("current") currentTextArea = self.tabs.winfo_children()[selectedTab+1].textarea text = currentTextArea.get(1.0, "end-1c") f.write(bytes(text, 'UTF-8')) currentTextArea.edit_modified(False) tab_tittle = os.path.basename(filepath) self.tabs.tab(selectedTab, text = tab_tittle) return "saved" except FileNotFoundError: print('TenorC>> File Not Found Error') return "cancelled" def addTab(self, event): selectedTab = self.tabs.index("current") lastindex = self.tabs.index("end")-1 if selectedTab == lastindex : textarea = Editor(self.tabs) self.tabs.insert(lastindex, textarea, text="Tab" + str(lastindex+1)) self.tabs.select(lastindex) def donothing(self): print("clicked")
class ViewResults(Observer, View): """Takes care of the presentation of the Flow diagram.""" def __init__(self, parent, col=0, row=0, root=None): super().__init__(parent, col=col, row=row, sticky=NSEW, scrollbars=False, root=root) self._notebook = Notebook(self._frame, name="nb") self._notebook.columnconfigure(0, weight=1) self._notebook.rowconfigure(0, weight=1) self._notebook.config() self._notebook.grid(sticky=NSEW) self._notebook.grid(sticky=NSEW) self._tabs = [] # type: List[ImageTab] self._results = None self._parent = parent self.image_overlay = np.empty(shape=(0, 0, 0), dtype=np.uint8) # TODO: Work around below should be fixed; need to create a tab first and delete it, or background is old image in constant scale. name_init = "initialization_image" self.add_to_tab(np.zeros((1, 1, 3), dtype=np.uint8), name_init) self.RemoveTab(name_init) self.__temp_data_queue = Queue( ) # used for update function to store data in # add custom event handler to let updates be taken care of in tk main loop parent.root.bind("<<ViewResults.Update>>", self.__update) self._notebook.bind("<<NotebookTabChanged>>", self.__on_tabchange) self.__last_selected_tab = None def __on_tabchange(self, event): try: tab_index = self._notebook.index(self._notebook.select()) except TclError as ex: return # there are no tabs yet if self.__last_selected_tab is not None: self.__last_selected_tab.on_tab_deselect() self.__last_selected_tab = self._tabs[tab_index] self.__last_selected_tab.on_tab_selected() def RemoveTab(self, name): for tab in self._tabs: if name is tab.GetName(): tab.destroy() self._tabs.remove(tab) def add_to_tab(self, npimage, name): if npimage is None: return # check if one exists; if so use that for tab in self._tabs: if tab.GetName() == name: tab.SetImage(npimage=npimage) return #create new tab one tab = ImageTab(name=name, notebook=self._notebook, parent=self) self._tabs.append(tab) self.add_to_tab(npimage=npimage, name=name) def __findAllImagesAndShow(self, flowblock_name): if self._results is None: return imageVars = self._results.FindAllOfType(ImageVar().name) for key, var in imageVars.items(): name = key.split(".")[0] if name == flowblock_name: self.add_to_tab(var.value, name) def __draw_all_drawables_until(self, flowblock_name=None): ''' Draws al drawable results to image_overlay. Images is as large as to fit all drawables. :param flowblock_name: draw until this block. :return: ''' results = self.get_controller().results.get_result_dict( ) # type: Dict[str,Dict[str,Var]] self.image_overlay = np.empty(shape=(0, 0, 0), dtype=np.uint8) logging.debug("Starting drawing of drawables...") for key, value in results.items(): for key2, value2 in value.items(): if type(value2) == list: for value3 in value2: self.image_overlay = value3.draw(self.image_overlay) else: self.image_overlay = value2.draw(self.image_overlay) logging.debug("Finished drawing of drawables.") def __update(self, event): self._results = self.get_controller().results.get_results_for_block() try: flowblock_name = self.__temp_data_queue.get_nowait( )["flowblock_name"] except Empty: flowblock_name = None if not flowblock_name is None: # redraw al drawables self.__draw_all_drawables_until(flowblock_name) # a flowblock has just updated, go and show all containing images self.__findAllImagesAndShow(flowblock_name) def Update(self, *args, **kwargs): self.__temp_data_queue.put_nowait( {"flowblock_name": kwargs.get("flowblock_name", None)}) self._parent.root.event_generate("<<ViewResults.Update>>")