def main(): """Main function of the program.""" main = tk.Tk() # Add Title main.title("Space Craft Creator") # Disable Resizing main.resizable(False, False) data = Data() spacecraft = Spacecraft(data) notebook = Notebook(main) spacecraft_tab = spacecraft.make_tab(notebook) notebook.add(spacecraft_tab, text="Spacecraft") for key, subsystem in spacecraft.subsections.items(): notebook.add(subsystem.make_tab(notebook), text=key) notebook.add(spacecraft.sizes.make_tab(notebook), text="Sizes") notebook.add(spacecraft.velocities.make_tab(notebook), text="Velocity Profiles") notebook.grid(column=0, row=0) notebook.enable_traversal() button = Button(main, text="Caclulate", command=spacecraft.calculate) button.grid(column=0, row=1) main.mainloop()
class GUI(Frame): def __init__(self, master=None): super().__init__(master) self.master = master self.pack() self.create_frames() self.master.title("Tk with Pandas Plot test") def create_frames(self): self.tabs = Notebook(self) self.tabs.pack() self.home_frame = HomeFrame(self.tabs) self.tabs.add(self.home_frame, text='Home') self.tabs.select(self.home_frame) self.tabs.enable_traversal() def start(self): self.master.mainloop()
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) # second page
def initialize(self): self.master.title("NENR DZ5 - Miljenko Šuflaj") self.pack(fill="both", expand=True) notebook = Notebook(self) notebook.pack() record_gestures_frame = Frame(self) classify_gestures_frame = Frame(self) notebook.add(record_gestures_frame, text="Zabilježi geste") notebook.add(classify_gestures_frame, text="Klasificiraj geste") notebook.enable_traversal() notebook.select(record_gestures_frame) gesture_classification_frame = Frame(classify_gestures_frame) gesture_record_frame_2 = Frame(classify_gestures_frame) gesture_classification_frame.pack(side="top", fill="x", expand=True) gesture_record_frame_2.pack(fill="both") # region Record gesture tab gesture_info_frame = Frame(record_gestures_frame) gesture_record_frame = Frame(record_gestures_frame) gesture_end_frame = Frame(record_gestures_frame) gesture_info_frame.pack(side="top", fill="x") gesture_record_frame.pack(fill="both") gesture_end_frame.pack(side="bottom", fill="x") gesture_name_menu = Menubutton(gesture_info_frame, text="Odaberi gestu za bilježenje...") gesture_name_menu.menu = Menu(gesture_name_menu, tearoff=0) gesture_name_menu["menu"] = gesture_name_menu.menu for i, label in enumerate(GestureWindow.labels): gesture_name_menu.menu.add_command(label=label, command=self.switch_record(i)) self.__recorded_gesture_label = Label(gesture_info_frame) gesture_record_canvas = Canvas(gesture_record_frame, width=700, height=475, bg="white") gesture_record_canvas.current_coords = None gesture_record_canvas.records = list() gesture_record_save_button = Button(gesture_end_frame, text="Pohrani u .tsv", command=self.save_data) gesture_record_delete_button = Button(gesture_end_frame, text="Zaboravi učitane podatke", command=self.delete_internal) gesture_name_menu.pack(side="left", fill="x", padx=5, pady=5, expand=True) self.__recorded_gesture_label.pack(side="left", fill="x", padx=5, pady=5) gesture_record_canvas.pack(fill="both", padx=5, pady=5, expand=True) gesture_record_delete_button.pack(side="left", fill="x", padx=5, pady=5) gesture_record_save_button.pack(side="right", fill="x", padx=5, pady=5) self.switch_record(self.__recorded_gesture_index)() # endregion # region Classify gesture tab gesture_classification_frame = Frame(classify_gestures_frame) gesture_record_frame_2 = Frame(classify_gestures_frame) gesture_classification_frame.pack(side="top", fill="x", expand=True) gesture_record_frame_2.pack(fill="both") classification_labels = list() self.__classification_outputs = list() for category in GestureWindow.labels: classification_labels.append( Label(gesture_classification_frame, text=category)) self.__classification_outputs.append( Label(gesture_classification_frame, text=f"{0.:.01f}%", font=("helvetica", 8))) classification_blank = Label(gesture_classification_frame) classification_labels[-1].pack(side="left", fill="x", padx=5, pady=5) self.__classification_outputs[-1].pack(side="left", fill="x", padx=5, pady=5) classification_blank.pack(side="left", fill="x", padx=50, pady=5) gesture_record_canvas_2 = Canvas(gesture_record_frame_2, width=700, height=525, bg="white") gesture_record_canvas_2.current_coords = None gesture_record_canvas_2.records = list() gesture_record_canvas_2.pack(side="left", fill="both", padx=5, pady=5, expand=True) # endregion # region Functionality for record_canvas in [gesture_record_canvas, gesture_record_canvas_2]: draw_function = self.get_draw_on_canvas_function(record_canvas) record_canvas.bind("<B1-Motion>", draw_function) record_canvas.bind("<ButtonRelease-1>", draw_function) self.__root_window.bind( "<BackSpace>", self.get_delete_currently_drawn(gesture_record_canvas)) self.__root_window.bind( "<Return>", self.get_record_gesture_function(gesture_record_canvas)) gesture_record_canvas_2.bind( "<Leave>", self.get_evaluate_gesture_function(gesture_record_canvas_2)) self.__root_window.bind( "<Delete>", self.get_delete_currently_drawn(gesture_record_canvas_2))
class App(Frame): def __init__(self, parent, *args, **kwargs): Frame.__init__(self, parent, *args, **kwargs) self.winfo_toplevel().title("CS430 Final Project: Samuel Golden") self.parent = parent # init fonts FONT = 'Din' TEXT_FONT = 'Courier' self.titleFont = (FONT, 16) self.headerFont = (FONT, 14, 'bold') self.textFont = (TEXT_FONT, 12) self.statusFont = (FONT, 12, 'italic') # init widgets self.outputLabel = Label(self, text='Algorithmic output:', font=self.titleFont) self.outputNb = Notebook(self) self.mstTab = Frame(self.outputNb) self.inputLabel = Label(self, text='Matrix input (-1 = no link, separate weight with single space, no trailing newline):', font=self.titleFont) self.matrixLabel = Label(self, text='Given Matrix', font=self.titleFont) self.matrixText = Text(self, font=self.textFont, height=8, width=30) self.matrixFrame = Frame(self) self.runButton = Button(self, text='Run', font=self.headerFont, relief='raised', borderwidth=5, command=self.run) self.statusStr = StringVar() self.statusStr.set('IDLE: not running.') self.statusBar = Label(self, textvariable=self.statusStr, font=self.statusFont) self.grid_all() self.config_text() self.config_nb() def run(self): self.write_status("RUNNING: parsing input matrix...") matrixInput = self.matrixText.get("1.0", END) # 1.0 means line 1, char 0 matrix = matrixInput.split('\n') matrix = [row.split(' ') for row in matrix] if len(matrix[-1]) == 1: del matrix[-1] for r in range(len(matrix)): for v in range(len(matrix[r])): try: matrix[r][v] = int(matrix[r][v]) except ValueError: self.write_status(f"STOPPED: invalid entry in matrix '{matrix[r][v]}'.") return self.write_status("RUNNING: validating input matrix...") matrixSize = len(matrix) for row in matrix: if len(row) != matrixSize: self.write_status("STOPPED: matrix size invalid (must be square).") return for i in range(0, matrixSize): if matrix[i][i] != 0: self.write_status("STOPPED: matrix diagonal should all be zeros (node cannot have link to itself)") return self.write_status("RUNNING: drawing table for parsed matrix...") matrixTable = MatrixTable(self.matrixFrame, matrix) matrixTable.grid(row=0, column=0, sticky='nsew') self.matrixFrame.update() self.write_status("RUNNING: running MST algorithm...") unsortedEdges, sortedEdges, mstEdges = mst(matrix) self.write_status("RUNNING: drawing MST visualization...") mstView = MSTView(self.mstTab) mstView.populate(unsortedEdges, sortedEdges, mstEdges) mstView.grid(row=0, column=0, sticky='nsew') self.write_status("IDLE: Done. Last successful run: " + datetime.now().strftime("%H:%M:%S")) def write_status(self, string): self.statusStr.set(string) self.parent.update() def config_text(self): start_matrix = "0 200 500 10 -1\n200 0 80 70 90\n50 80 0 -1 40\n10 70 -1 0 20\n-1 90 40 20 0" self.matrixText.insert(END, start_matrix) def config_nb(self): self.outputNb.add(self.mstTab, text='Minimum Spanning Tree') self.outputNb.select(self.mstTab) self.outputNb.enable_traversal() def grid_all(self): to_grid = [ # r c rs cs stick widget (1, 0, 1, 2, 'nsw', self.outputLabel), (2, 0, 1, 2, 'nsew', self.outputNb), (3, 0, 1, 2, 'nsw', self.inputLabel), (4, 0, 1, 1, 'nsew', self.matrixText), (4, 1, 1, 1, 'nsew', self.matrixFrame), (5, 0, 1, 2, 'ns', self.runButton), (6, 0, 1, 2, 'nsew', self.statusBar) ] for w in to_grid: w[5].grid(row=w[0], column=w[1], sticky=w[4], columnspan=w[3], rowspan=w[2], padx=10, pady=10) self.columnconfigure(0, weight=1)
class Main(object): def __init__(self, title): root = Tk() root.title(title) root.focus_set() root.rowconfigure(0, weight=0) root.columnconfigure(0, weight=1) root.rowconfigure(1, weight=1) self._root = root self.menubar = Frame(root) self.menubar.grid(row=0, column=0, sticky=(W, E)) self.menubar['takefocus'] = False quit_button = Button(self.menubar, text='Quit', command=self.quit) quit_button.grid(row=0, column=0) self._menucolumn = 1 self.views = list() self.paned_win = PanedWindow(root, orient=HORIZONTAL) self.paned_win.grid(row=1, column=0, sticky=(N, S, W, E)) self._query = None self._accept_func = None self.sidebar_views = dict() self.sidebar_count = 0 self.sidebar = PanedWindow(self.paned_win) self.paned_win.add(self.sidebar, weight=1) self.tabs = Notebook(self.paned_win) self.tabs.enable_traversal() self.paned_win.add(self.tabs, weight=5) self.root = self.tabs def add_menubutton(self, label, action): button = Button(self.menubar, text=label, command=action) button.grid(row=0, column=self._menucolumn) self._menucolumn += 1 def add_sidebar(self, view, name): self.sidebar_views[name] = view self.sidebar.add(view.widget, weight=1) view.widget.focus_set() self.sidebar_count += 1 if self.sidebar_count == 1: self.sidebar_views['main'] = view def remove_sidebar_view(self, name): self.sidebar.forget(self.sidebar_views[name].widget) self.sidebar_count -= 1 del self.sidebar_views[name] if self.sidebar_count == 0: del self.sidebar_views['main'] def get_sidebar_view(self, name): return self.sidebar_views.get(name) def focus_sidebar(self): if 'main' in self.sidebar_views.keys(): self.sidebar_views['main'].widget.focus_set() def focus_main_view(self): self.get_current_view().widget.focus_set() def new_view(self, view): self.views.append(view) self.tabs.add(view.widget, text=" {}.".format(self.tabs.index('end'))) self.tabs.select(view.widget) view.widget.focus_set() self.view_changed() def remove_view(self, view): self.views.remove(view) self.tabs.forget(view.widget) if len(self.views) >= 1: widget = self.views[-1].widget self.tabs.select(widget) widget.focus_set() else: self.sidebar_views['main'].widget.focus_set() self.view_changed() def delete_current_view(self, event): if self.tabs.index('end') > 0: self.remove_view(self.get_current_view()) def close_query(self): if self._query is not None: self._query.event_generate('<<MainQueryClose>>') self._query.destroy() self._query = None self._accept_func = None self._menucolumn -= 1 def accept_query(self, event): if self._query is not None: if self._accept_func is not None: self._accept_func(event.widget.get(), event.widget.original_value) self.close_query() else: event.widget.event_generate('<<MainQueryAccept>>') def text_query(self, query_lable, original_text=None, accept_func=None): if self._query is not None: return frame = Frame(self.menubar) label = Label(frame, text=query_lable) label.grid(column=0, row=0, sticky=(N, S)) self._accept_func = accept_func entry = Entry(frame) if original_text is not None: entry.insert(0, original_text) entry.original_value = original_text entry.grid(column=1, row=0, sticky=(N, S, W, E)) kb.make_bindings(kb.text_query, { 'accept': self.accept_query, 'cancel': lambda e: self.close_query() }, entry.bind) frame.grid(column=self._menucolumn, row=0) self._menucolumn += 1 entry.focus_set() self._query = frame def get_current_view(self): if self.tabs.index('end') > 0: return self.views[self.tabs.index('current')] else: return self.sidebar_views['main'] def view_changed(self): self._root.event_generate('<<MainViewChanged>>') def display(self): self._root.mainloop() def quit(self): self._root.destroy()
class OpeningPage(): """@summary: Widget servant à lancer la simulation après avoir renseigné les persos """ def __init__(self, fenetre): self.notebk = Notebook(fenetre) self.fenetre = fenetre self.persoViews = [] self.caracsNotebk = [] self.framesPersos = [] def formSubmission(self, _): """@summary: Lance la simulation de combat avec les persos du notebook """ persos = [] for persoVw in self.persoViews: persoVw.inputsToPerso() persos.append(persoVw.perso) writeSaveFile("save.json", persos) launchSimu(self.persoViews) def addEmptyPage(self, _): """@summary: Ajoute un onglet avec un stub perso dans le notebook0 """ self.addPage(readSaveFile("./persos/empty.json")) def deleteActiveNotePage(self): """@summary: Supprime l'onglet actif et les valeurs de personnages associés. """ nomPanneau = self.notebk.tab(self.notebk.select())["text"] indPanneau = int(nomPanneau.split(" ")[1]) self.notebk.forget(self.notebk.select()) del self.persoViews[indPanneau - 1] def addPage(self, values): """@summary: Ajoute un onglet avec les valeurs de personnages données. """ self.framesPersos.append(Frame(self.notebk)) framePerso = self.framesPersos[-1] self.persoViews.append(PersoView(values)) persoVw = self.persoViews[-1] self.caracsNotebk.append(Notebook(framePerso)) caracNotebk = self.caracsNotebk[-1] caracNotebk.pack() for inputsCategory, inputValues in persoVw.perso.items(): frameCaracs = LabelFrame(framePerso, text=inputsCategory) if persoVw.inputs.get(inputsCategory, None) is None: persoVw.inputs[inputsCategory] = dict() j = 0 for inputName, inputValue in inputValues.items(): if inputName == "Classe": classesDisponibles = \ Combobox(frameCaracs, textvariable=StringVar(), values=["Cra", "Xelor", "Iop", "Sram", "Poutch", "Eniripsa", "Pandawa"], state='readonly') persoVw.inputs[inputsCategory][ inputName] = classesDisponibles persoVw.inputs[inputsCategory][inputName].set(inputValue) else: persoVw.inputs[inputsCategory][inputName] = \ Entry(frameCaracs, textvariable=StringVar(), width=10) persoVw.inputs[inputsCategory][inputName].insert( END, inputValue) lblCarac = Label(frameCaracs, text=inputName + ":") lblCarac.grid(row=j, column=0) persoVw.inputs[inputsCategory][inputName].grid(row=j, column=1) j += 1 caracNotebk.add(frameCaracs, text=inputsCategory) # Pack de la fenêtre, détermine la taille de la fenêtre selon la taille des composants. #framePerso.pack(fill="both", expand="yes") self.notebk.add(framePerso, text="Perso " + str(len(self.persoViews))) saveBtn = Button(framePerso, text='Sauvegarder ce perso', command=persoVw.save) loadBtn = Button(framePerso, text='Charger un perso', command=persoVw.load) deleteThisBtn = Button(framePerso, text="Supprimer ce perso", command=self.deleteActiveNotePage) # Mise du bouton sur la droite de la fenetre saveBtn.pack(side="left") # Mise du bouton sur la droite de la fenetre loadBtn.pack(side="left") deleteThisBtn.pack(side="left") def main(self): """@summary: Lance la création des personnages pour ensuite lancer la simulation """ # Créer la fenêtre Tkinter values = readSaveFile("save.json") self.notebk.pack() for inputPerso in values: self.addPage(inputPerso) self.notebk.enable_traversal() # Ajout du bouton pour lancer la simulation submit = Button(self.fenetre, text='Lancer la simulation') # Permet au gestionnaire d'événement d'ajouter des paramètres # Gestionnaire d'événement pour le clic du bouton submit.bind("<Button-1>", self.formSubmission) # Mise du bouton sur la droite de la fenetre submit.pack(side="right") addPersoBtn = Button(self.fenetre, text='Ajouter un perso') addPersoBtn.bind("<Button-1>", self.addEmptyPage) addPersoBtn.pack(side="right")
class Main(object): def __init__(self, title): root = Tk() root.title(title) root.focus_set() root.rowconfigure(0, weight=0) root.columnconfigure(0, weight=1) root.rowconfigure(1, weight=1) self._root = root self.menubar = Frame(root) self.menubar.grid(row=0, column=0, sticky=(W, E)) self.menubar['takefocus'] = False quit_button = Button(self.menubar, text='Quit', command=self.quit) quit_button.grid(row=0, column=0) self._menucolumn = 1 self.views = list() self.paned_win = PanedWindow(root, orient=HORIZONTAL) self.paned_win.grid(row=1, column=0, sticky=(N, S, W, E)) self._query = None self._accept_func = None self.sidebar_views = dict() self.sidebar_count = 0 self.sidebar = PanedWindow(self.paned_win) self.paned_win.add(self.sidebar, weight=1) self.tabs = Notebook(self.paned_win) self.tabs.enable_traversal() self.paned_win.add(self.tabs, weight=5) self.root = self.tabs def add_menubutton(self, label, action): button = Button(self.menubar, text=label, command=action) button.grid(row=0, column=self._menucolumn) self._menucolumn += 1 def add_sidebar(self, view, name): self.sidebar_views[name] = view self.sidebar.add(view.widget, weight=1) view.widget.focus_set() self.sidebar_count += 1 if self.sidebar_count == 1: self.sidebar_views['main'] = view def remove_sidebar_view(self, name): self.sidebar.forget(self.sidebar_views[name].widget) self.sidebar_count -= 1 del self.sidebar_views[name] if self.sidebar_count == 0: del self.sidebar_views['main'] def get_sidebar_view(self, name): return self.sidebar_views.get(name) def focus_sidebar(self): if 'main' in self.sidebar_views.keys(): self.sidebar_views['main'].widget.focus_set() def focus_main_view(self): self.get_current_view().widget.focus_set() def new_view(self, view): self.views.append(view) self.tabs.add(view.widget, text=" {}.".format(self.tabs.index('end'))) self.tabs.select(view.widget) view.widget.focus_set() self.view_changed() def remove_view(self, view): self.views.remove(view) self.tabs.forget(view.widget) if len(self.views) >= 1: widget = self.views[-1].widget self.tabs.select(widget) widget.focus_set() else: self.sidebar_views['main'].widget.focus_set() self.view_changed() def delete_current_view(self, event): if self.tabs.index('end') > 0: self.remove_view(self.get_current_view()) def close_query(self): if self._query is not None: self._query.event_generate('<<MainQueryClose>>') self._query.destroy() self._query = None self._accept_func = None self._menucolumn -= 1 def accept_query(self, event): if self._query is not None: if self._accept_func is not None: self._accept_func(event.widget.get(), event.widget.original_value) self.close_query() else: event.widget.event_generate('<<MainQueryAccept>>') def text_query(self, query_lable, original_text=None, accept_func=None): if self._query is not None: return frame = Frame(self.menubar) label = Label(frame, text=query_lable) label.grid(column=0, row=0, sticky=(N, S)) self._accept_func = accept_func entry = Entry(frame) if original_text is not None: entry.insert(0, original_text) entry.original_value = original_text entry.grid(column=1, row=0, sticky=(N,S,W,E)) kb.make_bindings(kb.text_query, {'accept': self.accept_query, 'cancel': lambda e: self.close_query()}, entry.bind) frame.grid(column=self._menucolumn, row=0) self._menucolumn += 1 entry.focus_set() self._query = frame def get_current_view(self): if self.tabs.index('end') > 0: return self.views[self.tabs.index('current')] else: return self.sidebar_views['main'] def view_changed(self): self._root.event_generate('<<MainViewChanged>>') def display(self): self._root.mainloop() def quit(self): self._root.destroy()
def __init__(self, title="window controller", width=800, height=600): # ############################## # ## SERIAL SETUP # ############################## # self.ser = serial.Serial('COM3', 9600, timeout=1) all_ports = serial.tools.list_ports.comports() self.ports = {} self.port_states = {} for port in all_ports: name = port.device print(port) # self.ser = serial.Serial(name, 9600, timeout=1) self.ser = serial.Serial(name, 9600, timeout=1) self.show_loading_bar(2) response = self.handshake(name, self.ser) print(response) if response == "Temperatuurmeetsensor v0.1": self.ports[name] = self.ser self.port_states[name] = True else: self.ser.close() # print(self.ports) # ############################## # ## VARS INIT # ############################## self.title = title self.width = width self.height = height # ############################## # STYLING # ############################## # ############################## # ## TKINTER INIT # ############################## self.root = Tk() self.root.geometry(str(self.width) + "x" + str(self.height)) self.root.title(title) self.root.protocol("WM_DELETE_WINDOW", self.on_closing) # ############################## # ## TITLE AREA # ############################## self.title_area = Frame(self.root) self.title = Label(self.title_area, text="Rolluiken Bedieningspaneel", **title_config) self.title.pack() self.title_area.pack() # ############################## # ## CREATE TABS # ############################## # setup self.tabs = {} tab_area = Frame(self.root, name='demo') nb = Notebook(tab_area, name='notebook') nb.enable_traversal() nb.pack(fill=BOTH, expand=Y, padx=2, pady=3) # fill tabs nr_of_ports = 4 frames = dict([(name, Frame(tab_area)) for name, value in self.ports.items()]) print(frames) if not frames: self.show_message( "Er zijn geen rolluikbedieningsmodules gevonden.") else: self.populate_with_tabs(frames, tab_area, nb) # inputs # ############################## # ## BUTTONS # ############################## self.button_area = Frame(self.root) # area left self.button_area_left = Frame(self.button_area) # self.open_shutter_button = Button(self.button_area_left, command=lambda: self.send("shutter_status", "open"), text="open rolluiken", **button_config) # self.close_shutter_button = Button(self.button_area_left, command=lambda: self.send("shutter_status", "closed"), text="sluit rolluiken", **button_config) # self.automatic_shutter_button = Button(self.button_area_left, command=lambda: self.send("shutter_status", "auto"), text="automatisch", **button_config) # # self.open_shutter_button.pack(**button_area_config) # self.close_shutter_button.pack(**button_area_config) # self.automatic_shutter_button.pack(**button_area_config) self.button_area_left.pack(side=LEFT) # area right self.button_area_right = Frame(self.button_area) self.open_graph = Button(self.button_area_right, text="Grafieken", **button_config) self.open_graph.pack(**button_area_config) self.button_area_right.pack(side=RIGHT) # finalizing self.button_area.pack(fill="x") # ############################## # ## START LOOP # ############################## self.root.mainloop()
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)
def __init__(self): Tk.__init__(self) pwd = os.path.dirname(__file__) # ico = PhotoImage(file=os.path.join(pwd, "icon.png")) # self.call('wm', 'iconphoto', self._w, ico) self.title("Spectacuplot!") left_frame = Frame(self) control_frame = Frame(left_frame) left_frame.pack(side=LEFT, fill=Y) control_frame.pack(anchor=N,fill=BOTH,expand=1) # Menu bar mb = Menu(self) file_menu = Menu(mb) file_menu.add_command(label='Open...', command=self.open_dialog, accelerator='Ctrl-O') file_menu.add_command(label='Close All Files', command=self.close_files) # Get recent files self.recent = [] self.recent_commands = [] try: recent_files = open(os.path.expanduser("~/spectacuplot_recent"), "r") for f in recent_files: self.recent.append(f.strip()) self.recent_commands.append(functools.partial(self.open, f.strip())) recent_files.close() except: print("no recent files") self.recent_cascade = Menu(file_menu) for (f, c) in zip(self.recent, self.recent_commands): self.recent_cascade.add_command(label=f, command=c) file_menu.add_cascade(label="Recent Files", menu=self.recent_cascade) # Set up stuff for quitting Spectacuplot file_menu.add_command(label='Exit', command=self.quit) self.protocol("WM_DELETE_WINDOW", self.quit) self.bind_all("<Control-o>", self.open_dialog) self.config(menu=mb) mb.add_cascade(label="File", menu=file_menu) # Notebook nb = Notebook(control_frame, name="controls") nb.enable_traversal() nb.pack(expand=1, fill=BOTH) # Plot Area self.plot_frame = PlotArea(self) self.plot_frame.pack(side=LEFT, fill=BOTH, expand=1) # This will be used as the notbook tab for plotting individual datasets self.plot_set_tab = OpSetPlot(nb, self.opened_files, self.plot_frame) # This will be used as the notebook tab for plotting dataset diffs self.diff_tab = OpDiffPlot(nb, self.opened_files, self.plot_frame) nb.add(self.plot_set_tab, text="Plot Set") nb.add(self.diff_tab, text="Diff Sets")
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, text="Commands",
class OpeningPage(): """@summary: Widget servant à lancer la simulation après avoir renseigné les persos """ def __init__(self, fenetre): self.notebk = Notebook(fenetre) self.fenetre = fenetre self.persoViews = [] self.caracsNotebk = [] self.framesPersos = [] def formSubmission(self, _): """@summary: Lance la simulation de combat avec les persos du notebook """ persos = [] for persoVw in self.persoViews: persoVw.inputsToPerso() persos.append(persoVw.perso) writeSaveFile("save.json", persos) launchSimu(self.persoViews) def addEmptyPage(self, _): """@summary: Ajoute un onglet avec un stub perso dans le notebook0 """ self.addPage(readSaveFile("./persos/empty.json")) def deleteActiveNotePage(self): """@summary: Supprime l'onglet actif et les valeurs de personnages associés. """ nomPanneau = self.notebk.tab(self.notebk.select())["text"] indPanneau = int(nomPanneau.split(" ")[1]) self.notebk.forget(self.notebk.select()) del self.persoViews[indPanneau-1] def addPageSorts(self, persoVw, sortsSuppl=[], sortsDebtCombatSuppl=[]): tab_names = [persoVw.caracsNotebk.tab(i, option="text") for i in persoVw.caracsNotebk.tabs()] if "Sorts" in tab_names: persoVw.caracsNotebk.forget(tab_names.index("Sorts")) classe = persoVw.perso["Perso"]["Classe"] lvl = persoVw.perso["Perso"]["Level"] frameSorts = LabelFrame(persoVw.framePerso, text="Sorts") sorts, sortsDebtCombat = Personnages.Personnage.chargerSorts(classe, lvl, {}, True) sorts += sortsSuppl sortsDebtCombat += sortsDebtCombatSuppl for extSort in [x for x in persoVw.perso["Sorts"] if "::" in x]: classe, nom_sort = extSort.split("::") sortsSuppl, sortsDebtCombatSuppl = Personnages.Personnage.chargerSorts(classe, lvl, {nom_sort:1}, False, 1) for sortSuppl in sortsSuppl: sortSuppl.nom = classe+"::"+nom_sort for sortDebtCombatSuppl in sortsDebtCombatSuppl: sortDebtCombatSuppl.nom = classe+"::"+nom_sort sorts += sortsSuppl sortsDebtCombat += sortsDebtCombatSuppl self.variantesFrame = ScrolledWindow(frameSorts, width=400, height=400) persoVw.sortsLignes = 0 persoVw.images = [] if "Sorts" not in persoVw.inputs: persoVw.inputs["Sorts"] = dict() addedSpells = {} for sort in sorts+sortsDebtCombat: if not sort.lancableParJoueur: continue isVariante = sort.nom_variante != "" and sort.nom_variante in addedSpells root_pic1 = Image.open(sort.image) # Open the image like this first persoVw.images.append(ImageTk.PhotoImage(root_pic1)) if not isVariante: persoVw.sortsLignes += 1 ind = persoVw.sortsLignes imgLbl = Label(self.variantesFrame.scrollwindow, image=persoVw.images[-1], anchor="nw") imgLbl.grid(row=ind, column=2 if isVariante else 0, sticky="e") varSort = IntVar() varSort.set(persoVw.perso["Sorts"].get(sort.nom, 0)) persoVw.inputs["Sorts"][sort.nom] = varSort cbSort = Checkbutton(self.variantesFrame.scrollwindow, text=sort.nom, variable=varSort, onvalue=1, offvalue=0, anchor="w") cbSort.grid(row=ind, column=3 if isVariante else 1, sticky="w") addedSpells[sort.nom] = ind addSortButton = Button(frameSorts, text="Ajout Sort/Item", command=self.ajoutSort) addSortButton.grid() persoVw.caracsNotebk.add(frameSorts, text="Sorts") def ajoutSort(self): nomPanneau = self.notebk.tab(self.notebk.select())["text"] indPanneau = int(nomPanneau.split(" ")[1]) persoVw = self.persoViews[indPanneau-1] dialog = ChildDialogChooseSpell(self.fenetre, persoVw) self.fenetre.wait_window(dialog.app) filename, sort_name = tuple(dialog.rvalue.split("::")) perso = persoVw.perso classename = os.path.splitext(filename)[0] sorts, sortsDebtCombat = Personnages.Personnage.chargerSorts(classename, int(perso["Perso"]["Level"]), {sort_name:1}, False, 0) current = persoVw.caracsNotebk.index("current") for sort in sorts: sort.nom = filename+"::"+sort_name for sort in sortsDebtCombat: sort.nom = filename+"::"+sort_name self.addPageSorts(persoVw, sorts, sortsDebtCombat) persoVw.caracsNotebk.select(current) def onClassChange(self, event): nomPanneau = self.notebk.tab(self.notebk.select())["text"] indPanneau = int(nomPanneau.split(" ")[1]) persoVw = self.persoViews[indPanneau-1] self.addPageSorts(persoVw) def addPage(self, values): """@summary: Ajoute un onglet avec les valeurs de personnages données. """ self.persoViews.append(PersoView(values)) persoVw = self.persoViews[-1] self.framesPersos.append(Frame(self.notebk)) framePerso = self.framesPersos[-1] persoVw.framePerso = framePerso self.caracsNotebk.append(Notebook(framePerso)) caracNotebk = self.caracsNotebk[-1] caracNotebk.pack() persoVw.caracsNotebk = caracNotebk for inputsCategory, inputValues in persoVw.perso.items(): frameCaracs = LabelFrame(framePerso, text=inputsCategory) if persoVw.inputs.get(inputsCategory, None) is None: persoVw.inputs[inputsCategory] = dict() j = 0 if inputsCategory == "Sorts": self.addPageSorts(persoVw) continue for inputName, inputValue in inputValues.items(): if inputName == "Classe": classesDisponibles = \ Combobox(frameCaracs, textvariable=StringVar(), values=["Cra", "Xelor", "Iop", "Sacrieur", "Sram", "Poutch", "Eniripsa", "Pandawa"], state='readonly') classesDisponibles.bind('<<ComboboxSelected>>', self.onClassChange) persoVw.inputs[inputsCategory][inputName] = classesDisponibles persoVw.inputs[inputsCategory][inputName].set(inputValue) else: persoVw.inputs[inputsCategory][inputName] = \ Entry(frameCaracs, textvariable=StringVar(), width=10) persoVw.inputs[inputsCategory][inputName].insert(END, inputValue) lblCarac = Label(frameCaracs, text=inputName+":") lblCarac.grid(row=j, column=0) persoVw.inputs[inputsCategory][inputName].grid(row=j, column=1) j += 1 caracNotebk.add(frameCaracs, text=inputsCategory) # Pack de la fenêtre, détermine la taille de la fenêtre selon la taille des composants. #framePerso.pack(fill="both", expand="yes") self.notebk.add(framePerso, text="Perso "+str(len(self.persoViews))) saveBtn = Button(framePerso, text='Sauvegarder ce perso', command=persoVw.save) loadBtn = Button(framePerso, text='Charger un perso', command=persoVw.load) deleteThisBtn = Button(framePerso, text="Supprimer ce perso", command=self.deleteActiveNotePage) # Mise du bouton sur la droite de la fenetre saveBtn.pack(side="left") # Mise du bouton sur la droite de la fenetre loadBtn.pack(side="left") deleteThisBtn.pack(side="left") def main(self): """@summary: Lance la création des personnages pour ensuite lancer la simulation """ # Créer la fenêtre Tkinter values = readSaveFile("save.json") self.notebk.pack() for inputPerso in values: self.addPage(inputPerso) self.notebk.enable_traversal() # Ajout du bouton pour lancer la simulation submit = Button(self.fenetre, text='Lancer la simulation') # Permet au gestionnaire d'événement d'ajouter des paramètres # Gestionnaire d'événement pour le clic du bouton submit.bind("<Button-1>", self.formSubmission) # Mise du bouton sur la droite de la fenetre submit.pack(side="right") addPersoBtn = Button(self.fenetre, text='Ajouter un perso') addPersoBtn.bind("<Button-1>", self.addEmptyPage) addPersoBtn.pack(side="right")
class Application(Frame): class TextFrameTab: def __init__(self, obj): self.text_frm = Frame(obj.notebook) self.text_frm.pack(side=TOP, expand=YES, fill=BOTH) self.text = Text(self.text_frm) self.text.config(fg='#111111', bg='#f2f2f2', bd=0, wrap=WORD, undo=True, maxundo=100, autoseparators=True, selectbackground='#bbbbcf') self.text.focus() self.yscroll = Scrollbar(self.text_frm, orient=VERTICAL) self.yscroll.config(cursor='arrow', command=self.text.yview, bg='#777777', activebackground='#6d6d6d', troughcolor='#c2c2c2') self.text['yscrollcommand'] = self.yscroll.set self.yscroll.pack(side=RIGHT, fill=Y) self.text.pack(side=LEFT, expand=YES, fill=BOTH) self.text.edit_modified(arg=False) obj.textwidgets.append(self.text) obj.notebook.add(self.text_frm, padding=1, text=obj.filenames[-1]) obj.notebook.select(self.text_frm) self.file_menu = obj.file_menu self.notebook = obj.notebook self.filenames = obj.filenames self.save_btn = obj.save_btn self.statusbar_line_lbl = obj.statusbar_line_lbl self.statusbar_col_lbl = obj.statusbar_col_lbl # Disable 'Save' menu item self.file_menu.entryconfigure(4, state=DISABLED) self.text.bind('<<StateChecking>>', self.check_state) self.text.bind('<<StateChecking>>', self.mark_line, add='+') def mark_line(self, event): if 'currline' in self.text.tag_names(): self.text.tag_delete('currline') self.text.tag_add('currline', 'insert linestart', 'insert linestart + 1 lines') # Highlight the current line self.text.tag_config('currline', background='#dadada') self.text.tag_lower('currline') def check_state(self, event): line_number = self.text.index(INSERT).split('.')[0] # Display the line number of the current cursor position # on the status bar self.statusbar_line_lbl.config(text='ln: ' + line_number) col_number = str(int(self.text.index(INSERT).split('.')[1]) + 1) # Display the column number of the current cursor position # on the status bar self.statusbar_col_lbl.config(text='col: ' + col_number) try: current_index = self.notebook.index('current') modified = self.text.edit_modified() if modified: # Enable 'Save' menu item self.file_menu.entryconfigure(4, state=NORMAL) # Add asterisk to the header of the tab self.notebook.tab(current_index, text='*' + self.filenames[current_index]) self.save_btn.config(state=NORMAL) else: # Disable 'Save' menu item self.file_menu.entryconfigure(4, state=DISABLED) # If there is asterisk at the header of the tab, # remove it self.notebook.tab(current_index, text=self.filenames[current_index]) self.save_btn.config(state=DISABLED) except TclError: pass def __init__(self, parent=None): Frame.__init__(self, parent) # A dictionary with paths to opened and/or saved files self.filepaths = {} # A list with names of files opened in separate tabs self.filenames = ['Untitled'] # A list with existing text widgets self.textwidgets = [] self.menubar = Frame(self) self.menubar.config(bg='#444444', bd=0, relief=FLAT, padx=2) self.menubar.pack(side=TOP, fill=X) self.toolbar = Frame(self) self.toolbar.config(bg='#444444', bd=1, relief=GROOVE, pady=6, padx=2) self.toolbar.pack(side=TOP, fill=X) self.statusbar = Frame(self) self.statusbar.config(bg='#222222', bd=0, relief=FLAT, padx=10) self.statusbar.pack(side=BOTTOM, fill=X) self.style = Style() self.style.configure('TNotebook', background='#606060') self.notebook = Notebook(self) self.notebook.enable_traversal() self.notebook.pack(side=TOP, expand=YES, fill=BOTH) self.file_menu_btn = Menubutton(self.menubar) self.file_menu_btn.config(text='File', bg='#444444', fg='#eeeeee', activeforeground='#eeeeee', activebackground='#647899', underline=0) self.file_menu_btn.pack(side=LEFT) self.file_menu = Menu(self.file_menu_btn, tearoff=0) self.file_menu_btn['menu'] = self.file_menu self.file_menu.config(fg='#eeeeee', activeforeground='#eeeeee', bg='#444444', activebackground='#647899') self.file_menu.add_command(label='New', command=self.create_new_doc, accelerator=' ' * 14 + 'Ctrl+N') self.file_menu.add_command(label='Open', command=self.open_file, accelerator=' ' * 14 + 'Ctrl+O') self.file_menu.add_command(label='Close', command=self.close_tab, accelerator=' ' * 14 + 'Ctrl+W') self.file_menu.add_separator() self.file_menu.add_command(label='Save', command=self.save_file, accelerator=' ' * 14 + 'Ctrl+S') self.file_menu.add_command(label='Save As', command=self.save_as_file, accelerator=' Ctrl+Shift+S') self.file_menu.add_separator() self.file_menu.add_command(label='Exit', command=self.quit_from_app, accelerator=' ' * 14 + 'Ctrl+Q') self.edit_menu_btn = Menubutton(self.menubar) self.edit_menu_btn.config(text='Edit', fg='#eeeeee', bg='#444444', activebackground='#647899', activeforeground='#eeeeee', underline=0) self.edit_menu_btn.pack(side=LEFT) self.edit_menu = Menu(self.edit_menu_btn, tearoff=0) self.edit_menu_btn['menu'] = self.edit_menu self.edit_menu.config(fg='#eeeeee', activeforeground='#eeeeee', bg='#444444', activebackground='#647899') self.edit_menu.add_command(label='Undo', command=self.undo, accelerator=' ' * 10 + 'Ctrl+Z') self.edit_menu.add_command(label='Redo', command=self.redo, accelerator='Ctrl+Shift+Z') self.edit_menu.add_separator() self.edit_menu.add_command(label='Cut', command=self.cut_text, accelerator=' ' * 10 + 'Ctrl+X') self.edit_menu.add_command(label='Copy', command=self.copy_text, accelerator=' ' * 10 + 'Ctrl+C') self.edit_menu.add_command(label='Paste', command=self.paste_text, accelerator=' ' * 10 + 'Ctrl+V') self.edit_menu.add_command(label='Delete', command=self.del_text) self.edit_menu.add_separator() self.edit_menu.add_command(label='Select All', command=self.select_all, accelerator=' ' * 10 + 'Ctrl+A') self.help_menu_btn = Menubutton(self.menubar) self.help_menu_btn.config(text='Help', fg='#eeeeee', bg='#444444', activeforeground='#eeeeee', activebackground='#647899', underline=0) self.help_menu_btn.pack(side=LEFT) self.help_menu = Menu(self.help_menu_btn, tearoff=0) self.help_menu_btn['menu'] = self.help_menu self.help_menu.config(fg='#eeeeee', activeforeground='#eeeeee', bg='#444444', activebackground='#647899') self.help_menu.add_command(label='About', command=self.show_about) self.file_tool_frm = Frame(self.toolbar) self.file_tool_frm.config(bg='#444444', bd=0, relief=FLAT, padx=4) self.file_tool_frm.pack(side=LEFT) self.edit_tool_frm = Frame(self.toolbar) self.edit_tool_frm.config(bg='#444444', bd=0, relief=FLAT, padx=12) self.edit_tool_frm.pack(side=LEFT) self.hint_lbl = Label(self.toolbar) self.hint_lbl.config(bg='#444444', fg='#eeeeee', font=('Sans', '10', 'italic'), bd=0, relief=FLAT, padx=12) self.hint_lbl.pack(side=LEFT) self.new_btn = Button(self.file_tool_frm) self.new_btn.config(text='\u2795', font=('Sans', '12'), fg='#eeeeee', bg='#333333', bd=0, activebackground='#555555', activeforeground='#ffffff', padx=4, pady=0, command=self.create_new_doc) self.new_btn.grid(row=0, column=0) self.new_btn.bind('<Enter>', lambda x: self.hint_lbl.config(text='New')) self.new_btn.bind('<Leave>', lambda x: self.hint_lbl.config(text='')) self.open_btn = Button(self.file_tool_frm) self.open_btn.config(text='\u21e9', font=('Sans', '12', 'bold'), fg='#eeeeee', bg='#333333', bd=0, activebackground='#555555', activeforeground='#ffffff', padx=4, pady=0, command=self.open_file) self.open_btn.grid(row=0, column=1, padx=20) self.open_btn.bind('<Enter>', lambda x: self.hint_lbl.config(text='Open')) self.open_btn.bind('<Leave>', lambda x: self.hint_lbl.config(text='')) self.save_btn = Button(self.file_tool_frm) self.save_btn.config(text='\u21e7', font=('Sans', '12', 'bold'), fg='#eeeeee', bg='#333333', bd=0, activebackground='#555555', activeforeground='#ffffff', padx=4, pady=0, state=DISABLED, command=self.save_file) self.save_btn.grid(row=0, column=2, padx=0) self.save_btn.bind('<Enter>', lambda x: self.hint_lbl.config(text='Save')) self.save_btn.bind('<Leave>', lambda x: self.hint_lbl.config(text='')) self.save_btn.bind('<Motion>', self.save_btn_handler) self.close_btn = Button(self.file_tool_frm) self.close_btn.config(text='\u2717', font=('Sans', '12', 'bold'), fg='#eeeeee', bg='#333333', bd=0, activebackground='#555555', activeforeground='#ffffff', padx=4, pady=0, command=self.close_tab) self.close_btn.grid(row=0, column=3, padx=20) self.close_btn.bind('<Enter>', lambda x: self.hint_lbl.config(text='Close')) self.close_btn.bind('<Leave>', lambda x: self.hint_lbl.config(text='')) self.undo_btn = Button(self.edit_tool_frm) self.undo_btn.config(text='\u21b6', font=('Sans', '12'), fg='#eeeeee', bg='#333333', bd=0, activebackground='#555555', activeforeground='#ffffff', padx=4, pady=0, command=self.undo) self.undo_btn.grid(row=0, column=0) self.undo_btn.bind('<Enter>', lambda x: self.hint_lbl.config(text='Undo')) self.undo_btn.bind('<Leave>', lambda x: self.hint_lbl.config(text='')) self.redo_btn = Button(self.edit_tool_frm) self.redo_btn.config(text='\u21b7', font=('Sans', '12'), fg='#eeeeee', bg='#333333', bd=0, activebackground='#555555', activeforeground='#ffffff', padx=4, pady=0, command=self.redo) self.redo_btn.grid(row=0, column=1, padx=20) self.redo_btn.bind('<Enter>', lambda x: self.hint_lbl.config(text='Redo')) self.redo_btn.bind('<Leave>', lambda x: self.hint_lbl.config(text='')) self.quit_btn = Button(self.toolbar) self.quit_btn.config(text='Quit', font=('Sans', '10'), fg='#eeeeee', bg='#333333', activebackground='#647899', activeforeground='#ffffff', bd=0, padx=4, pady=2, command=self.quit_from_app) self.quit_btn.pack(side=RIGHT) self.statusbar_col_lbl = Label(self.statusbar) self.statusbar_col_lbl.config(text='col: 1', fg='#ffffff', bg='#222222', activeforeground='#ffffff', activebackground='#222222', bd=0, font=('Sans', '11', 'italic'), padx=10) self.statusbar_col_lbl.pack(side=RIGHT) self.statusbar_line_lbl = Label(self.statusbar) self.statusbar_line_lbl.config(text='ln: 1', fg='#ffffff', bg='#222222', bd=0, padx=10, activeforeground='#ffffff', activebackground='#222222', font=('Sans', '11', 'italic')) self.statusbar_line_lbl.pack(side=RIGHT) self.tab = self.TextFrameTab(self) # Create the '<<StateChecking>>' virtual event self.event_add('<<StateChecking>>', '<Any-KeyPress>', '<Any-KeyRelease>', '<Any-ButtonRelease>', '<FocusIn>', '<FocusOut>') # Create event bindings for keyboard shortcuts self.bind_all('<Control-n>', self.create_new_doc) self.bind_all('<Control-o>', self.open_file) self.bind_all('<Control-w>', self.close_tab) self.bind_all('<Control-s>', self.save_file) self.bind_all('<Control-Shift-S>', self.save_as_file) self.bind_all('<Control-q>', self.quit_from_app) self.bind_all('<Control-a>', self.select_all) if sys.platform.startswith('win32'): self.bind_all('<Control-Shift-Z>', self.redo) def save_btn_handler(self, event): try: textwidget = self.focus_lastfor() current_index = self.notebook.index('current') if textwidget.edit_modified(): self.save_btn.config(state=NORMAL) # Add an asterisk to the header of the tab self.notebook.tab(current_index, text='*' + self.filenames[current_index]) else: self.save_btn.config(state=DISABLED) # If there is an asterisk at the header of the tab, # remove it self.notebook.tab(current_index, text=self.filenames[current_index]) except TclError: pass def show_progress(self, proc, fpath): """ Shows a message on the status bar about saving or downloading process """ label = Label(self.statusbar) msg = "{} {}... ".format(proc, fpath) label.config(text=msg, fg='#ffffff', bg='#222222', bd=0, font=('Sans', '9', 'italic')) label.pack(side=LEFT) timer = threading.Timer(3.0, label.destroy) timer.start() def create_new_doc(self, event=None): # 'event' is the '<Control-n>' probable event self.filenames.append('Untitled') self.TextFrameTab(self) def open_file(self, event=None): # If there is the '<Control-o>' event if event: textwidget = self.focus_lastfor() textwidget.edit_modified(arg=False) filepath = askopenfilename(filetypes=(('All files', '*'), )) if filepath: p = Path(filepath) filename = p.parts[-1] try: with open(filepath) as file: if self.notebook.index('end') > 0: textwidget = self.focus_lastfor() modified = textwidget.edit_modified() current_index = self.notebook.index('current') if (self.filenames[current_index] == 'Untitled' and not modified): self.filepaths[current_index] = filepath self.filenames[current_index] = filename textwidget.insert(1.0, file.read()) textwidget.edit_modified(arg=False) self.notebook.tab('current', text=filename) else: self.filepaths[current_index + 1] = filepath self.filenames.append(filename) tab = self.TextFrameTab(self) tab.text.insert(1.0, file.read()) tab.text.edit_modified(arg=False) self.notebook.tab('current', text=filename) else: self.filenames.append(filename) tab = self.TextFrameTab(self) tab.text.insert(1.0, file.read()) tab.text.edit_modified(arg=False) self.notebook.tab(0, text=filename) self.filepaths[0] = filepath except UnicodeDecodeError: msg = "Unknown encoding!".format(filename) showerror(message=msg) self.close_tab() self.create_new_doc() thread = threading.Thread(target=self.show_progress, args=('Downloading', filepath)) thread.start() def close_tab(self, event=None): # 'event' is the '<Control-w>' probable event def close(obj): try: current_index = self.notebook.index('current') del obj.filenames[current_index] del obj.textwidgets[current_index] if current_index in obj.filepaths: del obj.filepaths[current_index] obj.notebook.forget(current_index) except TclError: pass if self.notebook.index('end') > 0: textwidget = self.focus_lastfor() modified = textwidget.edit_modified() if modified: curr_index = self.notebook.index('current') msg = "'{}' has been modified. Do you want " \ "to save changes?".format(self.filenames[curr_index]) msgbox = Message(type=YESNOCANCEL, message=msg, icon=QUESTION) answer = msgbox.show() if answer == YES: self.save_file() close(self) elif answer == NO: close(self) else: close(self) def save_file(self, event=None): # 'event' is the '<Control-s>' probable event if self.notebook.index('end') > 0: current_index = self.notebook.index('current') if current_index in self.filepaths: filepath = self.filepaths[current_index] textwidget = self.focus_lastfor() text = textwidget.get(1.0, END) with open(filepath, 'w') as file: file.write(text) self.file_menu.entryconfigure(4, state=DISABLED) textwidget.edit_modified(arg=False) thread = threading.Thread(target=self.show_progress, args=('Saving', filepath)) thread.start() else: self.save_as_file() def save_as_file(self, event=None): # 'event' is the '<Control-Shift-S>' probable event if self.notebook.index('end') > 0: filepath = asksaveasfilename() if filepath: p = Path(filepath) filename = p.parts[-1] current_index = self.notebook.index('current') self.filepaths[current_index] = filepath self.notebook.tab('current', text=filename) self.filenames[current_index] = filename textwidget = self.focus_lastfor() text = textwidget.get(1.0, END) with open(filepath, 'w') as file: file.write(text) self.file_menu.entryconfigure(4, state=DISABLED) textwidget.edit_modified(arg=False) thread = threading.Thread(target=self.show_progress, args=('Saving', filepath)) thread.start() def undo(self): try: textwidget = self.focus_lastfor() textwidget.edit_undo() except TclError: pass def redo(self, event=None): # 'event' is the '<Control-Shift-Z>' probable event for Windows try: textwidget = self.focus_lastfor() textwidget.edit_redo() except TclError: pass def cut_text(self): try: textwidget = self.focus_lastfor() text = textwidget.get(SEL_FIRST, SEL_LAST) textwidget.delete(SEL_FIRST, SEL_LAST) textwidget.clipboard_clear() textwidget.clipboard_append(text) except TclError: pass def copy_text(self): try: textwidget = self.focus_lastfor() text = textwidget.get(SEL_FIRST, SEL_LAST) textwidget.clipboard_clear() textwidget.clipboard_append(text) except TclError: pass def paste_text(self): try: textwidget = self.focus_lastfor() text = textwidget.selection_get(selection='CLIPBOARD') textwidget.insert(INSERT, text) except TclError: pass def del_text(self): try: textwidget = self.focus_lastfor() textwidget.delete(SEL_FIRST, SEL_LAST) except TclError: pass def select_all(self, event=None): # 'event' is the '<Control-a>' probable event textwidget = self.focus_lastfor() textwidget.tag_add(SEL, 1.0, END) def show_about(self): txt_0 = "PyTEd 0.1.0" txt_1 = "PyTEd is a simple text editor based\n" \ "on the tkinter interface" txt_2 = "Copyright " + '\u00a9' + " 2019 Eugene Kapshuk" txt_3 = "Source code: " txt_4 = "https://github.com/eukap/pyted" txt_5 = "License: MIT" window = Toplevel() window.title('About PyTEd') window.geometry('350x280') window.transient(self) window.resizable(width=False, height=False) label_0 = Label(window) label_0.config(fg='#000000', bg='#ddddd8', text=txt_0, font=('Sans', '12', 'bold'), justify=CENTER, pady=10) label_0.pack(side=TOP, fill=X) label_1 = Label(window) label_1.config(fg='#000000', bg='#ddddd8', text=txt_1, font=('Sans', '11', 'normal'), justify=CENTER, pady=10) label_1.pack(side=TOP, fill=X) label_2 = Label(window) label_2.config(fg='#000000', bg='#ddddd8', text=txt_2, font=('Sans', '11', 'normal'), justify=CENTER, pady=10) label_2.pack(side=TOP, fill=X) frame_0 = Frame(window) frame_0.config(bg='#ddddd8', bd=0, relief=FLAT, padx=2, pady=2) frame_0.pack(side=TOP, fill=X) label_3 = Label(frame_0) label_3.config(fg='#000000', bg='#ddddd8', text=txt_3, font=('Sans', '11', 'normal'), justify=CENTER, padx=2, pady=10) label_3.pack(side=LEFT, fill=X) label_4 = Label(frame_0) label_4.config(fg='#1111cc', bg='#ddddd8', text=txt_4, font=('Sans', '11', 'normal'), cursor='hand1', justify=CENTER, padx=4, pady=0) label_4.pack(side=LEFT, fill=X) label_4.bind( '<Button-1>', lambda x: webbrowser.open_new_tab( 'https://github.com/eukap/pyted')) label_5 = Label(window) label_5.config(fg='#000000', bg='#ddddd8', text=txt_5, font=('Sans', '11', 'normal'), justify=CENTER, pady=8) label_5.pack(side=TOP, fill=X) frame_1 = Frame(window) frame_1.config(bg='#ddddd8', bd=0, relief=FLAT, padx=0, pady=12) frame_1.pack(side=BOTTOM, fill=BOTH, expand=YES) btn = Button(frame_1) btn.config(text='Close', fg='#000000', bg='#efefef', activeforeground='#000000', activebackground='#e9e9e9', font=('Sans', '10', 'normal'), command=window.destroy) btn.pack(side=TOP) def quit_from_app(self, event=None): # 'event' is the '<Control-q>' probable event modified = False for widget in self.textwidgets: if widget.edit_modified(): modified = True break if modified: msg = "Some changes haven't been saved. " \ "Do you really want to exit?" msgbox = Message(type=YESNO, message=msg, icon=QUESTION) answer = msgbox.show() if answer == YES: self.quit() else: self.quit()
class App(Tk): def __init__(self, args): Tk.__init__(self) self.height = '720' self.width = '1280' self.Editors = [] self.Filenames = {} self.lexer_selector = self.createLexers() self.Lexers = dict() self._icon = Image("photo", file='img/notebook/icon.png') self.code_font = Font(family="Latin Modern Mono", size=15) self.title_font = Font(family="Ubuntu Mono", size=15) self.underline_font = Font(underline=True) self.MainWindow = Frame(self, background='#282c34') self.notebook = Notebook(self) self.configureUI() self.args = args self.awk_img = PhotoImage(file='img/fext/awk.png') self.bash_img = PhotoImage(file='img/fext/bash.png') self.c_img = PhotoImage(file='img/fext/c.png') self.cs_img = PhotoImage(file='img/fext/c#.png') self.cmake_img = PhotoImage(file='img/fext/cmake.png') self.coffee_img = PhotoImage(file='img/fext/coffee.png') self.cpp_img = PhotoImage(file='img/fext/cpp.png') self.css_img = PhotoImage(file='img/fext/css.png') self.delphi_img = PhotoImage(file='img/fext/delphi.png') self.eiffel_img = PhotoImage(file='img/fext/eiffel.png') self.erlang_img = PhotoImage(file='img/fext/erlang.png') self.fs_img = PhotoImage(file='img/fext/f#.png') self.fortran_img = PhotoImage(file='img/fext/fortran.png') self.go_img = PhotoImage(file='img/fext/golang.png') self.haskell_img = PhotoImage(file='img/fext/haskell.png') self.html_img = PhotoImage(file='img/fext/html.png') self.java_img = PhotoImage(file='img/fext/java.png') self.js_img = PhotoImage(file='img/fext/js.png') self.json_img = PhotoImage(file='img/fext/json.png') self.kotlin_img = PhotoImage(file='img/fext/kotlin.png') self.lisp_img = PhotoImage(file='img/fext/lisp.png') self.makefile_img = PhotoImage(file='img/fext/makefile.png') self.matlab_img = PhotoImage(file='img/fext/matlab.png') self.mysql_img = PhotoImage(file='img/fext/mysql.png') self.perl_img = PhotoImage(file='img/fext/perl.png') self.php_img = PhotoImage(file='img/fext/php.png') self.prolog_img = PhotoImage(file='img/fext/prolog.png') self.python_img = PhotoImage(file='img/fext/python.png') self.ruby_img = PhotoImage(file='img/fext/ruby.png') self.sass_img = PhotoImage(file='img/fext/sass.png') self.scala_img = PhotoImage(file='img/fext/scala.png') self.swift_img = PhotoImage(file='img/fext/swift.png') self.tcl_img = PhotoImage(file='img/fext/tcl.png') self.ts_img = PhotoImage(file='img/fext/ts.png') self.txt_img = PhotoImage(file='img/fext/txt.png') self.verilog_img = PhotoImage(file='img/fext/verilog.png') self.vhdl_img = PhotoImage(file='img/fext/vhdl.png') self.xml_img = PhotoImage(file='img/fext/xml.png') self.yaml_img = PhotoImage(file='img/fext/yaml.png') for file_name in self.args: self.openFileByName(file_name) self.mainloop() def configureUI(self): self.configureWindow() self.configureMenu() self.configureNotebook() self.contextualMenu() self.bindWindowEvents() self.configureStatusBar() def configureWindow(self): self.geometry(self.width+'x'+self.height+'+0+0') self.title("Quode-IDE") self.wm_iconphoto(False, self._icon) self.MainWindow.pack() def configureMenu(self): self.menu_bar = Menu(self, background='#21252b', foreground='#ffffff') self.file_menu = Menu(self.menu_bar, tearoff=0) self.file_menu.add_command(label='New Tab', font=self.title_font, command=self.createNewEditor, activebackground='#123456', activeforeground='#ffffff', accelerator='Ctrl + N') self.file_menu.add_command(label="Open", font=self.title_font, command=self.openFile, activebackground='#123456', activeforeground='#ffffff', accelerator='Ctrl + O') self.file_menu.add_command(label="Save", font=self.title_font, command=self.saveFile, activebackground='#123456', activeforeground='#ffffff', accelerator='Ctrl + S') self.file_menu.add_command(label='Remove Tab', font=self.title_font, command=self.removeCurrentEditor, activebackground='#123456', activeforeground='#ffffff', accelerator='Ctrl + R') self.file_menu.add_separator() self.file_menu.add_command(label="Exit", font=self.title_font, command=self.askQuit, activebackground='#123456', activeforeground='#ffffff', accelerator='Ctrl + Q') self.menu_bar.add_cascade(label="File", font=self.title_font, activebackground='#123456', activeforeground='#ffffff', menu=self.file_menu) self.edit_menu = Menu(self.menu_bar, tearoff=0, activebackground='#123456') self.edit_menu.add_command(label="Cut", font=self.title_font, command=self.cutSelection, activebackground='#123456', activeforeground='#ffffff', accelerator="Ctrl + X") self.edit_menu.add_command(label="Copy", font=self.title_font, command=self.copySelection, activebackground='#123456', activeforeground='#ffffff', accelerator="Ctrl + C") self.edit_menu.add_command(label="Paste", font=self.title_font, command=self.pasteSelection, activebackground='#123456', activeforeground='#ffffff', accelerator="Ctrl + V") self.edit_menu.add_command(label="Replace (All)", font=self.title_font, activebackground='#123456', activeforeground='#ffffff', command=self.replaceAllWindow) self.menu_bar.add_cascade(label="Edit", font=self.title_font, activebackground='#123456', activeforeground='#ffffff', menu=self.edit_menu) self.view_menu = Menu(self.menu_bar, tearoff=0) self.view_menu.add_command(label="Increase Font Size", font=self.title_font, command=self.increaseFontSize, activebackground='#123456', activeforeground='#ffffff', accelerator="Ctrl + +/=") self.view_menu.add_command(label="Decrease Font Size", font=self.title_font, command=self.decreaseFontSize, activebackground='#123456', activeforeground='#ffffff', accelerator="Ctrl + -/_") self.view_menu.add_command(label="Find", font=self.title_font, command=self.searchWindow, activebackground='#123456', activeforeground='#ffffff', accelerator="Ctrl + f") self.view_menu.add_command(label="File tree", font=self.title_font, command=self.showFileTree, activebackground='#123456', activeforeground='#ffffff', accelerator="Ctrl + t") self.menu_bar.add_cascade(label="View", font=self.title_font, activebackground='#123456', activeforeground='#ffffff', menu=self.view_menu) self.run_menu = Menu(self.menu_bar, tearoff=0) self.run_menu.add_command(label='Run', activebackground='#123456', activeforeground='#ffffff', command=self.runCurrentEditor, font=self.title_font) self.menu_bar.add_cascade(label='Run', activebackground='#123456', activeforeground='#ffffff', font=self.title_font, menu=self.run_menu) self.help_menu = Menu(self.menu_bar, tearoff=0) self.help_menu.add_command(label="About", activebackground='#123456', activeforeground='#ffffff', font=self.title_font, command=self.printAbout) self.menu_bar.add_cascade(label="Help", font=self.title_font, activebackground='#123456', activeforeground='#ffffff', menu=self.help_menu) self.config(menu=self.menu_bar) def configureNotebook(self): self.notebook.place_configure(relx=0, rely=0, relheight=0.97, relwidth=1) self.notebook.enable_traversal() def configureStatusBar(self): self.status_bar_label = Label(self) self.status_bar_label.place_configure(relx=0, rely=0.97, relheight=0.03, relwidth=1) self.status_bar_label.config(text=self.getStatusText()) def langImg(self, ext): img = None if (ext == '.c'): img = self.c_img elif(ext == '.h'): img = self.c_img elif(ext == '.cpp'): img = self.cpp_img elif(ext == '.hpp'): img = self.cpp_img elif(ext == '.css'): img = self.css_img elif(ext == '.sass'): img = self.sass_img elif(ext == '.yaml'): img = self.yaml_img elif(ext == '.yml'): img = self.yaml_img elif(ext == '.json'): img = self.json_img elif(ext == '.cs'): img = self.cs_img elif(ext == '.fs'): img = self.fs_img elif(ext == '.e'): img = self.eiffel_img elif(ext == '.erl'): img = self.erlang_img elif(ext == '.hrl'): img = self.erlang_img elif(ext == '.es'): img = self.erlang_img elif(ext == '.f03'): img = self.fortran_img elif(ext == '.f90'): img = self.fortran_img elif(ext == '.F03'): img = self.fortran_img elif(ext == '.F90'): img = self.fortran_img elif(ext == '.go'): img = self.go_img elif(ext == '.hs'): img = self.haskell_img elif(ext == '.v'): img = self.verilog_img elif(ext == '.vhdl'): img = self.vhdl_img elif(ext == '.vhd'): img = self.vhdl_img elif(ext == '.html'): img = self.html_img elif(ext == '.htm'): img = self.html_img elif(ext == '.xhtml'): img = self.html_img elif(ext == '.xml'): img = self.xml_img elif(ext == '.js'): img = self.js_img elif(ext == '.tex'): img = self.ts_img elif(ext == '.coffee'): img = self.coffee_img elif(ext == '.java'): img = self.java_img elif(ext == '.scala'): img = self.scala_img elif(ext == '.kt'): img = self.kotlin_img elif(ext == '.ktm'): img = self.kotlin_img elif(ext == '.kts'): img = self.kotlin_img elif(ext == '.lisp'): img = self.lisp_img elif(ext == 'make'): img = self.makefile_img elif(ext == 'Make'): img = self.makefile_img elif(ext == 'cmake'): img = self.cmake_img elif(ext == 'CMake'): img = self.cmake_img elif(ext == '.m'): img = self.matlab_img elif(ext == '.mat'): img = self.matlab_img elif(ext == '.dpr'): img = self.delphi_img elif(ext == '.perl'): img = self.perl_img elif(ext == '.php'): img = self.php_img elif(ext == '.pr'): img = self.prolog_img elif(ext == '.py'): img = self.python_img elif(ext == '.rb'): img = self.ruby_img elif(ext == '.sh'): img = self.bash_img elif(ext == '.sql'): img = self.mysql_img elif(ext == '.mysql'): img = self.mysql_img elif(ext == '.tcl'): img = self.tcl_img elif(ext == '.awk'): img = self.awk_img else: img = self.txt_img return img def _get_current_editor(self): try: index = self.notebook.index('current') curr_editor = self.Editors[index] return curr_editor except _tkinter.TclError: messagebox.showerror('Error', 'No Editors Opened!!') return None def createNewEditor(self): new_tab_name = askstring('New Tab', 'Enter name of new tab') if new_tab_name: f_name, ext = os.path.splitext(new_tab_name) scrolled_text = ScrolledText(font=self.code_font, undo=True, tabs=('2c'), background='#282c34', insertbackground='#ffffff', foreground='#abb2a4') self.Editors.append(scrolled_text) self.Filenames[scrolled_text] = None try : lexer = self.lexer_selector[ext] except KeyError: lexer = None self.Lexers[scrolled_text] = lexer self.notebook.add(scrolled_text, image=self.langImg(ext), text=os.path.split(new_tab_name)[1], compound='left') self.notebook.select(scrolled_text) self.createTags() self.recolorize(None) self.setStatusText(self.getStatusText()) self.miscBindings(scrolled_text) scrolled_text.focus_set() scrolled_text.edit_reset() def openFile(self): opened_file_name = fd.askopenfilename(initialdir=".", title="Select file", filetypes=(('all files', '*.*'),)) if not isinstance(opened_file_name, tuple): ext = os.path.splitext(opened_file_name)[1] scrolled_text = ScrolledText(font=self.code_font, undo=True, tabs=('2c'), background='#282c34', insertbackground='#ffffff', foreground='#abb2a4') self.Editors.append(scrolled_text) self.Filenames[scrolled_text] = opened_file_name self.notebook.add(scrolled_text, image=self.langImg(ext), text=os.path.split(opened_file_name)[1], compound='left') with open(opened_file_name) as f: file_text = f.read() f.close() scrolled_text.insert('end', file_text) self.notebook.select(scrolled_text) try : lexer = self.lexer_selector[ext] except KeyError: lexer = None self.Lexers[scrolled_text] = lexer self.createTags() self.recolorize(None) scrolled_text.focus_set() scrolled_text.edit_reset() self.miscBindings(scrolled_text) self.setStatusText(self.getStatusText()) def openFileByName(self, path): opened_file_name = path if opened_file_name[0] != '/': opened_file_name = os.path.dirname(os.path.abspath(__file__)) + '/' + path if not os.path.isdir(opened_file_name): ext = os.path.splitext(opened_file_name)[1] scrolled_text = ScrolledText(font=self.code_font, undo=True, tabs=('1.28c'), background='#282c34', insertbackground='#ffffff', foreground='#abb2a4') self.Editors.append(scrolled_text) self.Filenames[scrolled_text] = opened_file_name print(opened_file_name) self.notebook.add(scrolled_text, image=self.langImg(ext), text=os.path.split(opened_file_name)[1], compound='left') with open(opened_file_name) as f: file_text = f.read() f.close() scrolled_text.insert('end', file_text) self.notebook.select(scrolled_text) try: lexer = self.lexer_selector[ext] except KeyError: lexer = None self.Lexers[scrolled_text] = lexer self.createTags() self.recolorize(None) scrolled_text.focus_set() scrolled_text.edit_reset() self.miscBindings(scrolled_text) self.setStatusText(self.getStatusText()) def saveFile(self): try: editor_index = self.notebook.index('current') curr_editor = self.Editors[editor_index] curr_text = curr_editor.get("1.0", "end") if self.Filenames[curr_editor] is not None: with open(self.Filenames[curr_editor], 'r+') as f: f.write(curr_text) messagebox.showinfo('Save', 'File Saved!!!') curr_editor.edit_reset() else: new_file_path = fd.asksaveasfilename(initialdir='.', filetypes=[("All files", "*")]) if not isinstance(new_file_path, tuple): self.Filenames[curr_editor] = new_file_path new_file = open(new_file_path, 'w+') new_file.close() new_file = open(new_file_path, 'r+') new_file.write(curr_text) messagebox.showinfo('Save', 'File Saved!!!') self.Filenames[curr_editor] = new_file_path curr_editor.edit_reset() except _tkinter.TclError: messagebox.showerror("Save File", "No file to save") def removeCurrentEditor(self): try: curr_editor = self._get_current_editor() if messagebox.askyesno('Remove Current Tab', 'Are you sure you want to remove this Editor?', icon='warning'): index = self.notebook.select('current') self.notebook.forget(index) self.Editors.remove(curr_editor) self.Filenames.pop(curr_editor, None) self.Lexers.pop(curr_editor, None) except _tkinter.TclError: messagebox.showerror('Remove Tab', 'Oops!! No tabs to remove!!') def askQuit(self): if messagebox.askyesno('Remove Current Tab', 'Do you really wanna Exit?', icon='warning'): self.destroy() def bindWindowEvents(self): self.bind('<Control-n>', func=lambda e:self.createNewEditor()) self.bind('<Control-o>', func=lambda e:self.openFile()) self.bind('<Control-s>', func=lambda e:self.saveFile()) self.bind('<Control-r>', func=lambda e:self.removeCurrentEditor()) self.bind('<Control-q>', func=lambda e:self.askQuit()) self.bind('<Control-x>', func=lambda e:self.cutSelection()) self.bind('<Control-c>', func=lambda e:self.copySelection()) self.bind('<Control-v>', func=lambda e:self.pasteSelection()) self.bind('<Control-a>', func=lambda e:self.selectAll()) self.bind('<Control-f>', func=lambda e:self.searchWindow()) self.bind('<Control-z>', func=lambda e:self.undoChange()) self.bind('<Control-y>', func=lambda e:self.redoChange()) self.bind('<Control-t>', func=lambda e:self.showFileTree()) self.bind('<Control-N>', func=lambda e:self.createNewEditor()) self.bind('<Control-O>', func=lambda e:self.openFile()) self.bind('<Control-S>', func=lambda e:self.saveFile()) self.bind('<Control-R>', func=lambda e:self.removeCurrentEditor()) self.bind('<Control-Q>', func=lambda e:self.askQuit()) self.bind('<Control-X>', func=lambda e:self.cutSelection()) self.bind('<Control-C>', func=lambda e:self.copySelection()) self.bind('<Control-V>', func=lambda e:self.pasteSelection()) self.bind('<Control-A>', func=lambda e:self.selectAll()) self.bind('<Control-F>', func=lambda e:self.searchWindow()) self.bind('<Control-Z>', func=lambda e:self.undoChange()) self.bind('<Control-Y>', func=lambda e:self.redoChange()) self.bind('<Control-T>', func=lambda e:self.showFileTree()) self.bind('<Control-plus>', func=lambda e:self.increaseFontSize()) self.bind('<Control-minus>', func=lambda e:self.decreaseFontSize()) self.bind('<Control-KP_Add>', func=lambda e:self.increaseFontSize()) self.bind('<Control-KP_Subtract>', func=lambda e:self.decreaseFontSize()) self.bind("<Key>", func=lambda e:self.anyKeyBindings(e)) # self.bind("<Key>", func=lambda e:self.setStatusText(self.getStatusText())) self.bind('<Button>', func=lambda e: self.anyButtonBindings(e)) self.bind('<Button-3>', func=lambda e: self.contextual_menu.post(e.x_root, e.y_root)) def anyKeyBindings(self, event): self.recolorize(None) self.setStatusText(self.getStatusText()) def anyButtonBindings(self, event): self.contextual_menu.unpost() self.setStatusText(self.getStatusText()) def cutSelection(self): curr_editor = self._get_current_editor() curr_editor.event_generate('<<Cut>>') def copySelection(self): curr_editor = self._get_current_editor() curr_editor.event_generate('<<Copy>>') def pasteSelection(self): curr_editor = self._get_current_editor() curr_editor.event_generate('<<Paste>>') def contextualMenu(self): self.contextual_menu = Menu(self, tearoff=False) self.contextual_menu.add_command(label='New Editor', command=self.createNewEditor) self.contextual_menu.add_command(label='Open File', command=self.openFile) self.contextual_menu.add_command(label='Save Editor', command=self.saveFile) self.contextual_menu.add_separator() self.contextual_menu.add_command(label='Remove Editor', command=self.removeCurrentEditor) self.contextual_menu.add_command(label='Change title', command=self.changeEditorTitle) def unpostContextMenu(self): self.contextual_menu.unpost() def changeEditorTitle(self): curr_editor = self._get_current_editor() new_title = askstring('New Editor', "Enter new title") new_ext = os.path.splitext(new_title)[1] self.notebook.tab(curr_editor, text=new_title, image=self.langImg(new_ext)) try : new_lexer = self.lexer_selector[new_ext] except KeyError: new_lexer = None self.Lexers[curr_editor] = new_lexer self.recolorize(None) def increaseFontSize(self): curr_editor = self._get_current_editor() # FIXME curr_font = Font(curr_editor, curr_editor.cget("font")) curr_size = curr_font.cget('size') new_size = curr_size+1 curr_font.configure(size=new_size) new_font = curr_font curr_editor.configure(font=new_font) # print(Font(curr_editor, curr_editor.cget("font")).cget("size")) def decreaseFontSize(self): curr_editor = self._get_current_editor() # FIXME curr_font = Font(curr_editor, curr_editor.cget("font")) curr_size = curr_font.cget('size') if curr_size > 1: new_size = curr_size-1 curr_font.configure(size=new_size) def undoChange(self): try: curr_editor = self._get_current_editor() curr_editor.edit_undo() self.createTags() self.recolorize(None) except _tkinter.TclError: pass def redoChange(self): try: curr_editor = self._get_current_editor() curr_editor.edit_redo() except _tkinter.TclError: pass def selectAll(self): curr_editor = self._get_current_editor() curr_editor.tag_add('sel', '1.0', 'end') return "break" def searchWindow(self): self.search_window = SearchWindow(self, 0) def removeAllTags(self): curr_editor = self._get_current_editor() for tag in curr_editor.tag_names(): curr_editor.tag_delete(tag) def replaceAllWindow(self): self.replace_window = ReplaceTextWindow(self) def replaceAll(self, a, b): curr_editor = self._get_current_editor() start = "1.0" text = curr_editor.get(start, "end") if curr_editor: pos = curr_editor.search(a, start, stopindex="end") while pos: length = len(text) row, col = pos.split('.') end = int(col) + length end = row + '.' + str(end) curr_editor.tag_add('found', pos, end) start = end pos = curr_editor.search(a, start, stopindex="end") replaced = 0 if a: coordinates = [] index_list = list(curr_editor.tag_ranges("found")) index_list.reverse() while index_list: coordinates.append([index_list.pop(), index_list.pop()]) for start, end in coordinates: curr_editor.delete(start, end) curr_editor.insert(start, b) replaced += 1 curr_editor.tag_delete("found") return replaced def createTags(self): curr_editor = self._get_current_editor() bold_font = Font(curr_editor, curr_editor.cget("font")) bold_font.configure(weight='bold') italic_font = Font(curr_editor, curr_editor.cget("font")) italic_font.configure(slant='italic') bold_italic_font = Font(curr_editor, curr_editor.cget("font")) bold_italic_font.configure(weight='bold', slant='italic') style = get_style_by_name('default') for ttype, ndef in style: tag_font = None if ndef['bold'] and ndef['italic']: tag_font = bold_italic_font elif ndef['bold']: tag_font = bold_font elif ndef['italic']: tag_font = italic_font if ndef['color']: foreground = "#%s" % ndef['color'] else: foreground = None curr_editor.tag_configure(str(ttype), foreground=foreground, font=tag_font) def recolorize(self, event): if len(self.Editors) != 0: curr_editor = self._get_current_editor() code = curr_editor.get("1.0", "end-1c") lexer = self.Lexers[curr_editor] if lexer is not None: tokensource = lexer.get_tokens(text=code) start_line = 1 start_index = 0 end_line = 1 end_index = 0 for ttype, value in tokensource: if "\n" in value: end_line += value.count("\n") end_index = len(value.rsplit("\n", 1)[1]) else: end_index += len(value) if value not in (" ", "\n"): index1 = "%s.%s" % (start_line, start_index) index2 = "%s.%s" % (end_line, end_index) for tagname in curr_editor.tag_names(index1): curr_editor.tag_remove(tagname, index1, index2) curr_editor.tag_add(str(ttype), index1, index2) start_line = end_line start_index = end_index # self.underlineComplement() def createLexers(self): lex = {} lex['.c'] = CFamilyLexer() lex['.h'] = CFamilyLexer() lex['.cpp'] = CppLexer() lex['.hpp'] = CppLexer() lex['.css'] = CssLexer() lex['.sass'] = SassLexer() lex['.yaml'] = YamlLexer() lex['.yml'] = YamlLexer() lex['.json'] = JsonLexer() lex['.cs'] = CSharpLexer() lex['.fs'] = FSharpLexer() lex['.e'] = EiffelLexer() lex['.erl'] = ErlangLexer() lex['.hrl'] = ErlangLexer() lex['.es'] = ErlangLexer() lex['.f03'] = FortranLexer() lex['.f90'] = FortranLexer() lex['.F03'] = FortranLexer() lex['.F90'] = FortranLexer() lex['.go'] = GoLexer() lex['.hs'] = HaskellLexer() lex['.v'] = VerilogLexer() lex['.vhdl'] = VhdlLexer() lex['.vhd'] = VhdlLexer() lex['.html'] = HtmlLexer() lex['.htm'] = HtmlLexer() lex['.xhtml'] = HtmlLexer() lex['.xml'] = XmlLexer() lex['.js'] = JavascriptLexer() lex['.tex'] = TypeScriptLexer() lex['.coffee'] = CoffeeScriptLexer() lex['.java'] = JavaLexer() lex['.scala'] = ScalaLexer() lex['.kt'] = KotlinLexer() lex['.ktm'] = KotlinLexer() lex['.kts'] = KotlinLexer() lex['.lisp'] = CommonLispLexer() lex['make'] = MakefileLexer() lex['Make'] = MakefileLexer() lex['CMake'] = CMakeLexer() lex['cmake'] = CMakeLexer() lex['.m'] = MatlabLexer() lex['.mat'] = MatlabLexer() lex['.dpr'] = DelphiLexer() lex['.perl'] = PerlLexer() lex['.php'] = PhpLexer() lex['.pr'] = PrologLexer() lex['.py'] = Python3Lexer() lex['.rb'] = RubyLexer() lex['.sh'] = BashLexer() lex['.sql'] = MySqlLexer() lex['.mysql'] = MySqlLexer() lex['.tcl'] = TclLexer() lex['.awk'] = AwkLexer() return lex def getStatusText(self): if len(self.Editors): curr_editor = self._get_current_editor() cursor_position = curr_editor.index('insert') if cursor_position is not None: row, col = cursor_position.split('.') return "Row: %s Col: %s"%(row, col) else: return "Quode-IDE" else: return "Quode-IDE" def setStatusText(self, text): if len(self.Editors): self.status_bar_label.config(text=text) else: self.status_bar_label.config(text="Quode-IDE") def miscBindings(self, scrolled_text): scrolled_text.bind('<Control-z>', func=self.undoChange) scrolled_text.bind('<Control-y>', func=self.redoChange) scrolled_text.bind('<KeyRelease-quoteright>', func=lambda e: self.completeQuoteright(scrolled_text)) scrolled_text.bind('<KeyRelease-quotedbl>', func=lambda e: self.completeQuotedbl(scrolled_text)) scrolled_text.bind('<KeyRelease-parenleft>', func=lambda e: self.completeParen(scrolled_text)) scrolled_text.bind('<KeyRelease-bracketleft>', func=lambda e: self.completeBracket(scrolled_text)) scrolled_text.bind('<KeyRelease-braceleft>', func=lambda e: self.completeBrace(scrolled_text)) scrolled_text.bind('<KeyRelease-less>', func=lambda e: self.completeAngles(scrolled_text)) scrolled_text.bind('<KeyRelease-Return>', func=lambda e: self.returnNewLine(scrolled_text)) scrolled_text.bind('<parenright>', func=lambda e: self.skipRParen(scrolled_text)) scrolled_text.bind('<bracketright>', func=lambda e: self.skipRBracket(scrolled_text)) scrolled_text.bind('<braceright>', func=lambda e: self.skipRBrace(scrolled_text)) scrolled_text.bind('<greater>', func=lambda e: self.skipRAngle(scrolled_text)) scrolled_text.bind('<BackSpace>', func=lambda e: self.erasePair(scrolled_text)) def completeParen(self, scrolled_text): scrolled_text.mark_gravity('insert', 'left') scrolled_text.insert('insert', ')') scrolled_text.mark_gravity('insert', 'right') self.recolorize(None) def completeBracket(self, scrolled_text): scrolled_text.mark_gravity('insert', 'left') scrolled_text.insert('insert', ']') scrolled_text.mark_gravity('insert', 'right') self.recolorize(None) def completeBrace(self, scrolled_text): scrolled_text.mark_gravity('insert', 'left') scrolled_text.insert('insert', '}') scrolled_text.mark_gravity('insert', 'right') self.recolorize(None) def completeQuoteright(self, scrolled_text): scrolled_text.mark_gravity('insert', 'left') scrolled_text.insert('insert', '\'') scrolled_text.mark_gravity('insert', 'right') self.recolorize(None) def completeQuotedbl(self, scrolled_text): scrolled_text.mark_gravity('insert', 'left') scrolled_text.insert('insert', '"') scrolled_text.mark_gravity('insert', 'right') self.recolorize(None) def completeAngles(self, scrolled_text): scrolled_text.mark_gravity('insert', 'left') scrolled_text.insert('insert', '>') scrolled_text.mark_gravity('insert', 'right') self.recolorize(None) def returnNewLine(self, scrolled_text): curr_editor = self._get_current_editor() cursor_position = curr_editor.index('insert') row_index = int(cursor_position.split('.')[0]) prev_row_index = str(row_index - 1) + '.0' prev_line = curr_editor.get(prev_row_index, prev_row_index + ' lineend') this_line = curr_editor.get(cursor_position + ' linestart', cursor_position + ' lineend') if(len(prev_line) > 1): left_char = prev_line[-1] new_line = ''.join(self.notAlphaLine(prev_line)) if len(this_line) > 0: right_char = this_line[0] if self._are_braces_paired(left_char, right_char): curr_editor.insert('insert', new_line + '\t') curr_editor.mark_gravity('insert', 'left') curr_editor.insert('insert', '\n\t') curr_editor.mark_gravity('insert', 'right') else: curr_editor.insert('insert', new_line) elif(len(prev_line) == 1): if(len(this_line) == 0): if (prev_line == '\t'): curr_editor.insert('insert', '\t') if(len(this_line) > 0): left_char = prev_line[0] right_char = this_line[0] if self._are_braces_paired(left_char, right_char): curr_editor.insert('insert', '\t') curr_editor.mark_gravity('insert', 'left') curr_editor.insert('insert', '\n') curr_editor.mark_gravity('insert', 'right') def _are_braces_paired(self, lchar, rchar): if(lchar == '(' and rchar == ')'): return True if(lchar == '[' and rchar == ']'): return True if(lchar == '{' and rchar == '}'): return True return False def notAlphaLine(self, line): new_line = [] line = ''.join(line) for char in line: if (char == ' ' or char == '\t'): new_line.append(char) else: return new_line return new_line def skipRParen(self, scrolled_text): try: cursor_position = scrolled_text.index('insert') row, col = map(int, cursor_position.split('.')) next_position = str(row) + '.' + str(col+1) if scrolled_text.get(cursor_position, next_position) == ')': scrolled_text.delete(cursor_position, next_position) except: pass def skipRBracket(self, scrolled_text): try: cursor_position = scrolled_text.index('insert') row, col = map(int, cursor_position.split('.')) next_position = str(row) + '.' + str(col+1) if scrolled_text.get(cursor_position, next_position) == ']': scrolled_text.delete(cursor_position, next_position) except: pass def skipRBrace(self, scrolled_text): try: cursor_position = scrolled_text.index('insert') row, col = map(int, cursor_position.split('.')) next_position = str(row) + '.' + str(col+1) if scrolled_text.get(cursor_position, next_position) == '}': scrolled_text.delete(cursor_position, next_position) except: pass def skipRAngle(self, scrolled_text): try: cursor_position = scrolled_text.index('insert') row, col = map(int, cursor_position.split('.')) next_position = str(row) + '.' + str(col+1) if scrolled_text.get(cursor_position, next_position) == '>': scrolled_text.delete(cursor_position, next_position) except: pass def erasePair(self, scrolled_text): try: cursor_position = scrolled_text.index('insert') row, col = map(int, cursor_position.split('.')) prev_position = str(row) + '.' + str(col-1) next_position = str(row) + '.' + str(col+1) curr_char = scrolled_text.get(cursor_position, next_position) prev_char = scrolled_text.get(prev_position, cursor_position) if curr_char == ')' and prev_char == '(': scrolled_text.delete(cursor_position, next_position) if curr_char == ']' and prev_char == '[': scrolled_text.delete(cursor_position, next_position) if curr_char == '}' and prev_char == '{': scrolled_text.delete(cursor_position, next_position) if curr_char == '>' and prev_char == '<': scrolled_text.delete(cursor_position, next_position) except: pass def runCurrentEditor(self): if len(self.Editors): curr_editor = self._get_current_editor() if self.Filenames[curr_editor] is not None: os.system('gnome-terminal --working-directory=%s' % os.path.dirname(self.Filenames[curr_editor])) else: messagebox.showerror(title="Could Not Open Terminal", message="Please save the File to run it") def showFileTree(self): if len(self.Editors): curr_editor = self._get_current_editor() directory = os.path.dirname(self.Filenames[curr_editor]) FileTree(curr_editor, directory) def printAbout(self): about = """ qqqqq dd ii ddddddd eeeeeee qqq qqq dd ii dd dd ee qqq qqq dd ii dd dd ee qqq qqq dd ii dd dd ee qqq qqq uu uu oo ddddd eeeee ii dd dd eeeeeee qqq qqq uu uu oo oo dd dd ee ee ii dd dd ee qqq qqq uu uu oo oo dd dd ee ee zzzzz ii dd dd ee qqq qqq uu uu oo oo dd dd eeeeeeeee ii dd dd ee qqq qqq uu uu oo oo dd dd ee ii dd dd ee qqqqq uuuu oo ddddd eeeeee ii dddddd eeeeeee qqqqqq Quode-IDE(Integrated Development Environment) Author : Yash Khasbage DISCLAIMER: Identifiers used in this software are purely fictious and bear no resembalance to any person living or dead. Any resembalace is purely co-incidental. No animals were harmed in coding of this software. """ print(about) messagebox.showinfo(title="About", message="Check terminal") def _get_int_row_col(self): curr_editor = self._get_current_editor() return list(map(int, curr_editor.index('insert').split('.'))) def _get_str_row_col(self): curr_editor = self._get_current_editor() return curr_editor.index('insert') def _str_to_int(self, pos): return list(map(int, pos.split('.'))) def _get_current_char(self): row, col = self._get_int_row_col() curr_pos = str(row)+'.'+str(col) next_pos = str(row)+'.'+str(col+1) curr_editor = self._get_current_editor() return curr_editor.get(curr_pos, next_pos) def _next_position(self, pos): row, col = list(map(int, pos.split('.'))) return '%d.%d'%(row, col+1) def underlineComplement(self): if len(self.Editors): pos = self._get_str_row_col() curr_char = self._get_current_char() if(curr_char == '('): self.underlineRParen(pos) elif(curr_char == ')'): self.underlineLParen(pos) elif(curr_char == '['): self.underlineRBracket(pos) elif(curr_char == ']'): self.underlineLBracket(pos) elif(curr_char == '{'): self.underlineRBrace(pos) elif(curr_char == '}'): self.underlineLBrace(pos) elif(curr_char == '<'): self.underlineRAngle(pos) elif(curr_char == '>'): self.underlineLAngle(pos) def underlineRParen(self, l_pos): return curr_editor = self._get_current_editor() text = curr_editor.get(l_pos, 'end') count = 0 index = 0 for i in range(len(text)): if(text[i] == ')' and count == 0): index = i elif(text[i] == '('): count += 1 elif(text[i] == ')'): count -= 1 j = 0 line = self._str_to_int(l_pos)[0] line_number = 0 start = l_pos end = '%d.end' % line j_prev = 0 while(index > j): j_prev = j j += len(curr_editor.get(start, end)) - 1 line_number += 1 start = "%d.0" % (line+line_number) r_paren_index = '%d.%d' % (line+line_number, index-j_prev) print("index", index) print("j", j) print("linenumber", line_number) print("r_paren_index", r_paren_index) curr_editor.tag_add('underline', l_pos, self._next_position(l_pos)) curr_editor.tag_add('underline', r_paren_index, self._next_position(r_paren_index)) curr_editor.tag_configure('underline', underline=True) def underlineLParen(self, r_pos): pass def underlineRBracket(self, l_pos): pass def underlineLBracket(self, r_pos): pass def underlineRbrace(self, l_pos): pass def underlineLBrace(self, r_pos): pass def underlineRAngle(self, l_pos): pass def underlineLAngle(self, r_pos): pass