def __init__(self): super().__init__() self.text_area = TextArea(self, bg="white", fg="black", undo=True) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.scrollbar.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1) self.highlighter = Highlighter(self.text_area, 'languages/python.yaml') # first_100_numbers = [str(n+1) for n in range(100)] # self.line_numbers.insert(1.0, "\n".join(first_100_numbers)) # self.line_numbers.configure(state="disabled", width=3) self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events()
def __init__(self): super().__init__() self.title('Python Text Editor v3') self.geometry('800x600') self.foreground = 'black' self.background = 'lightgrey' self.text_foreground = 'black' self.text_background = 'white' self.load_scheme_file('schemes/default.yaml') self.configure_ttk_elements() self.font_size = 15 self.font_family = "Ubuntu Mono" self.load_font_file('schemes/font.yaml') self.text_area = TextArea(self, bg=self.text_background, fg=self.text_foreground, undo=True, font=(self.font_family, self.font_size)) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1) self.highlighter = Highlighter(self.text_area, 'languages/python.yaml') self.menu = tk.Menu(self, bg=self.background, fg=self.foreground) self.all_menus = [self.menu] sub_menu_items = ["file", "edit", "tools", "help"] self.generate_sub_menus(sub_menu_items) self.configure(menu=self.menu) self.right_click_menu = tk.Menu(self, bg=self.background, fg=self.foreground, tearoff=0) self.right_click_menu.add_command(label='Cut', command=self.edit_cut) self.right_click_menu.add_command(label='Copy', command=self.edit_copy) self.right_click_menu.add_command(label='Paste', command=self.edit_paste) self.all_menus.append(self.right_click_menu) self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() self.open_file = ''
def init_input(self, label, text=None): self.input_label = label self.input = TextArea( self.window, self.font, TextBuffer(text), window_border=(self.window.size[1] - self.height + self.border[0], self.border[1], self.border[2], (self.font.size[0] * len(label)) + (2 * self.border[3])), line_spacing=0)
def create_objects(configdir): smgr = SettingsManager(configdir) mw = MainWindow(smgr) txta = TextArea(mw, smgr) chsb = ChapterSidebar(smgr, txta.toPlainText, txta.textCursor) term = Terminal(mw, smgr, lambda: txta.file_path) # Ugly shit mw.set_is_modified_callback(txta.document().isModified) return OrderedDict((('chaptersidebar', chsb), ('mainwindow', mw), ('settingsmanager', smgr), ('terminal', term), ('textarea', txta)))
def main(): window = Gtk.Window(title="Hello") widget = TextArea() window.add(widget) window.connect("destroy", Gtk.main_quit) window.show_all() Gtk.main()
def __init__(self): super().__init__() self.text_area = TextArea(self, bg="white", fg="black", undo=True) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1) self.highlighter = Highlighter(self.text_area, 'languages/python.yaml') self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events()
def create_widget(self): self.text_area = TextArea(self.frame1, bg=self.text_background, fg=self.text_foreground, undo=True, relief=tk.FLAT, font=(self.text_font_family, self.text_font_size), insertbackground=self.insertbackground) self.text_area.config(highlightthickness=0) self.text_area.grid(row=0, column=1, sticky='wens') self.text_area.focus_set() self.welcome(event=None) self.status_bar1 = StatusBar(self.frame2, bg="pink", width=30, height=10) self.status_bar2 = StatusBar(self.frame2, bg="orange", width=30, height=10) self.status_bar3 = StatusBar(self.frame2, bg="blue", width=30, height=10) self.status_bar4 = StatusBar(self.frame2, bg="green", width=30, height=10) self.status_bar5 = StatusBar(self.frame2, bg="purple", width=30, height=10) self.status_bar1.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.status_bar2.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.status_bar3.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.status_bar4.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.status_bar5.pack(side=tk.LEFT, fill=tk.BOTH, expand=True)
def run(): (window_size, f) = get_args() tb = TextBuffer() if f: tb.load(f) sdl2.ext.init() window = sdl2.ext.Window(WINDOW_TITLE, size=window_size) window.show() factory = sdl2.ext.SpriteFactory(sdl2.ext.SOFTWARE) font_img = factory.from_image(FONT_IMG_PATH) sdl2.SDL_SetColorKey( font_img.surface, sdl2.SDL_TRUE, sdl2.SDL_MapRGB(font_img.surface.format, COLOR_KEY_R, COLOR_KEY_G, COLOR_KEY_B)) font = sdl2.ext.BitmapFont(font_img, FONT_SIZE, mapping=FONT_MAPPING) sb = StatusBar(window, tb, font, STATUS_BAR_COLOR, (STATUS_BAR_BORDER_TOP, STATUS_BAR_BORDER_RIGHT, STATUS_BAR_BORDER_BOTTOM, STATUS_BAR_BORDER_LEFT)) ta = TextArea(window, font, tb, (TEXT_AREA_BORDER_TOP, TEXT_AREA_BORDER_RIGHT, sb.height + TEXT_AREA_BORDER_BOTTOM, TEXT_AREA_BORDER_LEFT), TEXT_AREA_LINE_SPACING) state = EditState(Editor(None, window, ta, sb)) sdl2.SDL_StartTextInput() while True: start = sdl2.SDL_GetTicks() state = state.update(sdl2.ext.get_events()) if state is None: break ticks = sdl2.SDL_GetTicks() - start if ticks < 1000 / FRAMES_PER_SECOND: sdl2.SDL_Delay((1000 / FRAMES_PER_SECOND) - ticks) sdl2.SDL_StopTextInput() sdl2.ext.quit() return 0
class MainWindow(tk.Tk): ''' @param tk.TK: Windows、Mac、Unix下TK GUI套件的标准Python接口,可实现GUI界面 ''' #窗口设置 def __init__(self): ''' @update 1.添加横向滚动条 2.修正行号与滚动条和窗口的关联 3.修正行号显示 ''' super().__init__() self.title('Python Text Editor v3') self.geometry('800x600') self.foreground = 'black' self.background = 'lightgrey' self.text_foreground = 'black' self.text_background = 'white' self.config_dir = os.path.join(str(Path.home()), '.tkedit') self.default_scheme_path = os.path.join(self.config_dir, 'schemes/default.yaml') self.python_language_path = os.path.join(self.config_dir, 'languages/python.yaml') self.none_language_path = os.path.join(self.config_dir, 'languages/None.yaml') self.font_scheme_path = os.path.join(self.config_dir, 'fonts/font.yaml') self.create_config_directory_if_needed() self.load_scheme_file(self.default_scheme_path) self.configure_ttk_elements() self.font_size = 15 self.font_family = "Ubuntu Mono" self.load_font_file(self.font_scheme_path) self.text_area = TextArea(self, bg=self.text_background, fg=self.text_foreground, undo=True, font=(self.font_family, self.font_size)) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.text_area.yview) self.scrollbar2 = ttk.Scrollbar(orient="horizontal", command=self.text_area.xview) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1, font=(self.font_family, self.font_size)) self.scrollbar.config(command=self.text_area.yview) self.text_area.config(yscrollcommand=self.scrollbar.set, xscrollcommand=self.scrollbar2.set) self.highlighter = Highlighter(self.text_area, self.none_language_path) self.menu = tk.Menu(self, bg=self.background, fg=self.foreground) self.all_menus = [self.menu] sub_menu_items = ["file", "edit", "tools", "help"] self.generate_sub_menus(sub_menu_items) self.configure(menu=self.menu) self.right_click_menu = tk.Menu(self, bg=self.background, fg=self.foreground, tearoff=0) self.right_click_menu.add_command(label='Cut', command=self.edit_cut) self.right_click_menu.add_command(label='Copy', command=self.edit_copy) self.right_click_menu.add_command(label='Paste', command=self.edit_paste) self.all_menus.append(self.right_click_menu) self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.scrollbar2.pack(side=tk.BOTTOM, fill=tk.X) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() self.open_file = '' #绑定事件 def bind_events(self): self.text_area.bind("<MouseWheel>", self.scroll_text) self.text_area.bind("<Button-4>", self.scroll_text) self.text_area.bind("<Button-5>", self.scroll_text) self.text_area.bind("<Button-3>", self.show_right_click_menu) self.bind('<Control-f>', self.show_find_window) self.bind('<Control-n>', self.file_new) self.bind('<Control-o>', self.file_open) self.bind('<Control-s>', self.file_save) self.bind('<Control-h>', self.help_about) self.bind('<Control-m>', self.tools_change_syntax_highlighting) self.bind('<Control-g>', self.tools_change_colour_scheme) self.bind('<Control-l>', self.tools_change_font) self.line_numbers.bind("<MouseWheel>", lambda e: "break") self.line_numbers.bind("<Button-4>", lambda e: "break") self.line_numbers.bind("<Button-5>", lambda e: "break") #滚动事件 def scroll_text(self, *args): if len(args) > 1: self.text_area.yview_moveto(args[1]) self.line_numbers.yview_moveto(args[1]) else: event = args[0] if event.delta: move = -1 * (event.delta / 120) else: if event.num == 5: move = 1 else: move = -1 self.text_area.yview_scroll(int(move), "units") self.line_numbers.yview_scroll(int(move) * 3, "units") #内容查找、替换窗口 def show_find_window(self, event=None): FindWindow(self.text_area) #显示右键菜单 def show_right_click_menu(self, event): x = self.winfo_x() + self.text_area.winfo_x() + event.x y = self.winfo_y() + self.text_area.winfo_y() + event.y self.right_click_menu.post(x, y) #设置子菜单 def generate_sub_menus(self, sub_menu_items): ''' @param sub_menu_items: 子菜单项目 ''' window_methods = [ method_name for method_name in dir(self) if callable(getattr(self, method_name)) ] tkinter_methods = [ method_name for method_name in dir(tk.Tk) if callable(getattr(tk.Tk, method_name)) ] my_methods = [ method for method in set(window_methods) - set(tkinter_methods) ] my_methods = sorted(my_methods) for item in sub_menu_items: sub_menu = tk.Menu(self.menu, tearoff=0, bg=self.background, fg=self.foreground) matching_methods = [] for method in my_methods: if method.startswith(item): matching_methods.append(method) for match in matching_methods: actual_method = getattr(self, match) method_shortcut = actual_method.__doc__.strip() friendly_name = ' '.join(match.split('_')[1:]) sub_menu.add_command(label=friendly_name.title(), command=actual_method, accelerator=method_shortcut) self.menu.add_cascade(label=item.title(), menu=sub_menu) self.all_menus.append(sub_menu) #显示关于 def show_about_page(self): msg.showinfo( "About", "My text editor, version 2, written in Python3.6 using tkinter!") #加载文字高亮配色方案 def load_syntax_highlighting_file(self): syntax_file = filedialog.askopenfilename(filetypes=[("YAML file", ("*.yaml", "*.yml"))]) if syntax_file: self.highlighter.clear_highlight() self.highlighter = Highlighter(self.text_area, syntax_file) self.highlighter.force_highlight() #加载窗体配色方案 def load_scheme_file(self, scheme): ''' @param scheme: 目标配置文件 @update GSC 预检测 ''' with open(scheme, 'r') as stream: try: config = yaml.load(stream) except yaml.YAMLError as error: print(error) return if 'foreground' in config: self.foreground = config['foreground'] if 'background' in config: self.background = config['background'] if 'text_foreground' in config: self.text_foreground = config['text_foreground'] if 'text_background' in config: self.text_background = config['text_background'] #加载字体及字号方案 def load_font_file(self, file_path): ''' @param file_path: 方案存放路径及文件名 ''' with open(file_path, 'r') as stream: try: config = yaml.load(stream) except yaml.YAMLError as error: print(error) return if 'family' in config: self.font_family = config['family'] if 'size' in config: self.font_size = config['size'] #修改窗体配色方案 def change_colour_scheme(self): ColourChooser(self) #应用窗体配色方案 def apply_colour_scheme(self, foreground, background, text_foreground, text_background): ''' @param foreground: 新窗体前景色 @param background: 新窗体背景色 @param text_foreground: 新字体前景色 @param text_background: 新字体背景色 ''' self.text_area.configure(fg=text_foreground, bg=text_background) self.background = background self.foreground = foreground for menu in self.all_menus: menu.configure(bg=self.background, fg=self.foreground) self.configure_ttk_elements() #应用按钮、标签配色方案 def configure_ttk_elements(self): style = ttk.Style() style.configure('editor.TLabel', foreground=self.foreground, background=self.background) style.configure('editor.TButton', foreground=self.foreground, background=self.background) #字体选择窗口 def change_font(self): FontChooser(self) #更新字体 def update_font(self): ''' @update 1.添加行号字体更新 ''' self.load_font_file(self.font_scheme_path) self.text_area.configure(font=(self.font_family, self.font_size)) self.line_numbers.configure(font=(self.font_family, self.font_size)) #运行环境检测 def create_config_directory_if_needed(self): if not os.path.exists(self.config_dir): os.mkdir(self.config_dir) if not os.path.exists(os.path.join(self.config_dir, 'schemes')): os.mkdir(os.path.join(self.config_dir, 'schemes')) if not os.path.exists(os.path.join(self.config_dir, 'languages')): os.mkdir(os.path.join(self.config_dir, 'languages')) if not os.path.exists(os.path.join(self.config_dir, 'fonts')): os.mkdir(os.path.join(self.config_dir, 'fonts')) self.create_default_scheme_if_needed() self.create_font_scheme_if_needed() self.create_python_language_if_needed() #运行环境创建 -- 窗体默认配置方案 def create_default_scheme_if_needed(self): if not os.path.exists(self.default_scheme_path): yaml_file_contents = f"background: 'lightgrey'\n" \ + f"foreground: 'black'\n" \ + f"text_background: 'white'\n" \ + f"text_foreground: 'black'\n" with open(self.default_scheme_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) #运行环境创建 -- 字体默认配置方案 def create_font_scheme_if_needed(self): if not os.path.exists(self.font_scheme_path): yaml_file_contents = f"family: Ubuntu Mono\n" \ + f"size: 15" with open(self.font_scheme_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) #运行环境创建 -- 语言文字高亮默认配置方案 def create_python_language_if_needed(self): if not os.path.exists(self.python_language_path): yaml_file_contents = """ categories: keywords: colour: orange matches: [for, def, while, from, import, as, with, self] variables: colour: red4 matches: ['True', 'False', None] conditionals: colour: green matches: [try, except, if, else, elif] functions: colour: blue4 matches: [int, str, dict, list, set, float] numbers: colour: purple strings: colour: '#e1218b' """ with open(self.python_language_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) if not os.path.exists(self.none_language_path): yaml_file_contents = """ categories: keywords: colour: black matches: [for, def, while, from, import, as, with, self] variables: colour: black matches: ['True', 'False', None] conditionals: colour: black matches: [try, except, if, else, elif] functions: colour: black matches: [int, str, dict, list, set, float] numbers: colour: black strings: colour: black """ with open(self.none_language_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) # =========== Menu Functions ============== #新建文件 def file_new(self, event=None): """ Ctrl+N """ self.text_area.delete(1.0, tk.END) self.open_file = "" self.line_numbers.force_update() #打开文件 def file_open(self, event=None): """ Ctrl+O """ file_to_open = filedialog.askopenfilename() if file_to_open: self.open_file = file_to_open self.text_area.display_file_contents(file_to_open) self.highlighter.force_highlight() self.line_numbers.force_update() #保存文件 def file_save(self, event=None): """ Ctrl+S """ current_file = self.open_file if self.open_file else None if not current_file: current_file = filedialog.asksaveasfilename() if current_file: contents = self.text_area.get(1.0, tk.END) with open(current_file, 'w') as file: file.write(contents) #剪切 def edit_cut(self, event=None): """ Ctrl+X """ self.text_area.event_generate("<Control-x>") self.line_numbers.force_update() #粘贴 def edit_paste(self, event=None): """ Ctrl+V """ self.text_area.event_generate("<Control-v>") self.line_numbers.force_update() self.highlighter.force_highlight() #复制 def edit_copy(self, event=None): """ Ctrl+C """ self.text_area.event_generate("<Control-c>") #全选 def edit_select_all(self, event=None): """ Ctrl+A """ self.text_area.event_generate("<Control-a>") #查找和替换 def edit_find_and_replace(self, event=None): """ Ctrl+F """ self.show_find_window() #帮助与关于 def help_about(self, event=None): """ Ctrl+H """ self.show_about_page() #选择语言(文字高亮) def tools_change_syntax_highlighting(self, event=None): """ Ctrl+M """ self.load_syntax_highlighting_file() #选择窗体配色 def tools_change_colour_scheme(self, event=None): """ Ctrl+G """ self.change_colour_scheme() #选择字体字号 def tools_change_font(self, event=None): """ Ctrl+L """ self.change_font()
class MainWindow(tk.Tk): def __init__(self): super().__init__() self.title('Text Editor') self.text_area = TextArea(self, bg="white", fg="black", undo=True) self.background = 'lightgrey' self.foreground = 'black' self.text_foreground = 'black' self.text_background = 'white' self.config_dir = os.path.join(str(Path.home()), '.tkedit') self.default_scheme_path = os.path.join(self.config_dir, 'schemes/default.yaml') self.python_language_path = os.path.join(self.config_dir, 'languages/python.yaml') self.font_scheme_path = os.path.join(self.config_dir, 'schemes/font.yaml') self.create_config_directory_if_needed() self.load_scheme_file(self.default_scheme_path) self.configure_ttk_elements() self.font_size = 15 self.font_family = "Ubuntu Mono" self.load_font_file(self.font_scheme_path) self.highlighter = Highlighter(self.text_area, self.python_language_path) self.menu = tk.Menu(self, bg=self.background, fg=self.foreground) self.all_menus = [self.menu] sub_menu_items = ['file', 'edit', 'tools', 'help'] self.generate_sub_menus(sub_menu_items) self.configure(menu=self.menu) self.right_click_menu = tk.Menu(self, bg='lightgrey', fg='black', tearoff=0) self.right_click_menu.add_command(label='Cut', command=self.edit_cut) self.right_click_menu.add_command(label='Copy', command=self.edit_copy) self.right_click_menu.add_command(label='Paste', command=self.edit_paste) self.all_menus.append(self.right_click_menu) self.open_file = None self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = LineNumbers(self, self.text_area, bg='grey', fg='white', width=1) ''' self.line_numbers = tk.Text(self, bg="grey", fg="yellow") first_100_numbers = [str(n+1) for n in range(100)] self.line_numbers.insert(1.0, "\n".join(first_100_numbers)) self.line_numbers.configure(state="disabled", width=3) ''' self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() def create_config_directory_if_needed(self): if not os.path.exists(self.config_dir): os.mkdir(self.config_dir) os.mkdir(os.path.join(self.config_dir, 'schemes')) os.mkdir(os.path.join(self.config_dir, 'languages')) self.create_default_scheme_if_needed() self.create_font_scheme_if_needed() self.create_python_language_if_needed() def create_default_scheme_if_needed(self): if not os.path.exists(self.default_scheme_path): yaml_file_contents = """ background: 'lightgrey' foreground: 'black' text_background: 'white' text_foreground: 'black' """ with open(self.default_scheme_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) def create_font_scheme_if_needed(self): if not os.path.exists(self.font_scheme_path): yaml_file_contents = """ family: Ubuntu Mono size: 14 """ with open(self.font_scheme_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) def create_python_language_if_needed(self): if not os.path.exists(self.python_language_path): yaml_file_contents = """ categories: keywords: color: orange matches: [for, def, while, from, import, as, with, self] variables: color: red matches: ['True', 'False', None] conditionals: color: green matches: [try, except, if, else, elif] functions: color: blue matches: [int, str, dict, list, set, float] numbers: color: purple strings: color: '#e1218b' """ with open(self.python_language_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) def bind_events(self): self.text_area.bind("<MouseWheel>", self.scroll_text) self.text_area.bind("<Button-4>", self.scroll_text) self.text_area.bind("<Button-5>", self.scroll_text) self.text_area.bind('<Button-3>', self.show_right_click_menu) self.bind('<Control-f>', self.show_find_window) self.line_numbers.bind("<MouseWheel>", lambda e: "break") self.line_numbers.bind("<Button-4>", lambda e: "break") self.line_numbers.bind("<Button-5>", lambda e: "break") self.bind('<Control-n>', self.file_new) self.bind('<Control-o>', self.file_open) self.bind('<Control-s>', self.file_save) self.bind('<Control-h>', self.help_about) self.bind('<Control-m>', self.tools_change_syntax_highlight) self.bind('<Control-g>', self.tools_Change_color_scheme) self.bind('<Control-l>', self.tools_change_font) def show_find_window(self, event=None): FindWindow(self.text_area) def scroll_text(self, *args): if len(args) > 1: self.text_area.yview_moveto(args[1]) self.line_numbers.yview_moveto(args[1]) else: event = args[0] if event.delta: move = -1 * (event.delta / 120) else: if event.num == 5: move = 1 else: move = -1 self.text_area.yview_scroll(int(move), "units") self.line_numbers.yview_scroll(int(move) * 3, "units") def generate_sub_menus(self, sub_menu_items): window_methods = [ method_name for method_name in dir(self) if callable(getattr(self, method_name)) ] tkinter_methods = [ method_name for method_name in dir(tk.Tk) if callable(getattr(tk.Tk, method_name)) ] my_methods = [ method for method in set(window_methods) - set(tkinter_methods) ] my_methods = sorted(my_methods) for item in sub_menu_items: sub_menu = tk.Menu(self.menu, tearoff=0, bg=self.background, fg=self.foreground) matching_methods = [] for method in my_methods: if method.startswith(item): matching_methods.append(method) for match in matching_methods: actual_method = getattr(self, match) method_shortcut = actual_method.__doc__.strip() friendly_name = ' '.join(match.split('_')[1:]) sub_menu.add_command(label=friendly_name.title(), command=actual_method, accelerator=method_shortcut) self.menu.add_cascade(label=item.title(), menu=sub_menu) self.all_menus.append(sub_menu) def show_right_click_menu(self, event): x = self.winfo_x() + self.text_area.winfo_x() + event.x y = self.winfo_y() + self.text_area.winfo_y() + event.y self.right_click_menu.post(x, y) def edit_cut(self, event=None): """ Ctrl+X """ self.text_area.event_generate('<Control-x>') self.line_numbers.force_update() def edit_paste(self, event=None): """ Ctrl+V """ self.text_area.event_generate('<Control-v>') self.line_numbers.force_update() self.highlighter.force_highlight() def edit_copy(self, event=None): """ Ctrl+C """ self.text_area.event_generate('<Control-c>') def file_open(self, event=None): """ Ctrl+O """ file_to_open = filedialog.askopenfilename() if file_to_open: self.open_file = file_to_open self.text_area.display_file_contents(file_to_open) self.highlighter.force_highlight() self.line_numbers.force_update() def file_save(self, event=None): """ Ctrl+S """ current_file = self.open_file if self.open_file else None if not current_file: current_file = filedialog.asksaveasfilename() if current_file: contents = self.text_area.get(1.0, tk.END) with open(current_file, 'w') as file: file.write(contents) def file_new(self, event=None): ''' Ctrl+N ''' self.text_area.delete(1.0, tk.END) self.open_file = None self.line_numbers.force_update() def edit_select_all(self, event=None): ''' Ctrl+A ''' self.text_area.event_generate('<Control-a>') def edit_find_and_replace(self, event=None): ''' Ctrl+F ''' self.show_find_window() def load_syntax_highlighting(self): syntax_file = filedialog.askopenfilename(filetypes=[('YAML file', ('*.yaml', '*.yml'))]) if syntax_file: self.highlighter.clear_highlight() self.highlighter = Highlighter(self.text_area, syntax_file) self.highlighter.force_highlight() def tools_change_syntax_highlight(self, event=None): ''' Ctrl+M ''' self.load_syntax_highlighting() def update_font(self): self.load_font_file(self.font_scheme_path) self.text_area.configure(font=(self.font_family, self.font_size)) def load_font_file(self, file_path): with open(file_path, 'r') as stream: try: config = yaml.load(stream) except yaml.YAMLError as e: print(e) return self.font_family = config['family'] self.font_size = config['size'] def load_scheme_file(self, scheme): with open(scheme, 'r') as stream: try: config = yaml.load(stream) except yaml.YAMLError as error: print(error) return self.foreground = config['foreground'] self.background = config['background'] self.text_foreground = config['text_foreground'] self.text_background = config['text_background'] def change_font(self): FontChooser(self) def tools_change_font(self, event=None): ''' Ctrl+L ''' self.change_font() def apply_color_scheme(self, foreground, background, text_foreground, text_background): self.background = background self.foreground = foreground self.text_area.configure(fg=text_foreground, bg=text_background) for menu in self.all_menus: menu.configure(bg=self.background, fg=self.foreground) self.configure_ttk_elements() def configure_ttk_elements(self): style = ttk.Style() style.configure('editor.TLabel', foreground=self.foreground, background=self.background) style.configure('editor.TButton', foreground=self.foreground, background=self.background) def change_color_scheme(self): ColorChooser(self) def tools_Change_color_scheme(self, event=None): ''' Ctrl+G ''' self.change_color_scheme() def show_about_page(self): msg.showinfo( 'About', 'My text editor , Version 3.0, written in python 3.7 using tkinter!' ) def help_about(self, event=None): ''' Ctrl+H ''' self.show_about_page()
class MainWindow(tk.Tk): def __init__(self): super().__init__() self.title('THEE') self.minsize(550, 40) # (width, height) self.winfo_screenwidth = self.winfo_screenwidth() self.winfo_screenheight = self.winfo_screenheight() self.grid_columnconfigure(0, weight=1) self.grid_rowconfigure(0, weight=1) self.width = int(self.winfo_screenwidth / 3) self.height = int(self.winfo_screenheight / 3) self.geometry(f'{self.width}x{self.height}') self.thee_mode = 0 # 0: welcome, 1: editor, 2: terminal, 3: help self.count_text_changed = 0 self.editor_mode_buffer = "" self.terminal_mode_buffer = "" self.key_buffer = [] self.file_name = "untitled" self.status = "unsaved" self.spaces = 4 self.line = 1 self.column = 1 self.foreground = config.color['foreground'] self.background = config.color['background'] self.text_foreground = config.color['text_foreground'] self.text_background = config.color['text_background'] self.insertbackground = config.color['insertbackground'] self.statusbar_background = config.color['statusbarbg'] self.frame1 = tk.Frame(self, bg=self.background, width=self.width, height=self.height - 15) self.frame2 = tk.Frame(self, bg=self.statusbar_background, width=self.width, height=10) self.frame1.grid(row=0, column=0, sticky='wens') self.frame2.grid(row=1, column=0, sticky='wens') self.frame1.grid_columnconfigure(1, weight=1) self.frame1.grid_rowconfigure(0, weight=1) self.config_dir = os.path.join(str(Path.home()), '.thee') self.text_font_size = config.font['text']['size'] self.text_font_family = config.font['text']['family'] self.statusbar_font_size = config.font['statusbar']['size'] self.statusbar_font_family = config.font['statusbar']['family'] self.create_widget() # Entry point ==========# self.terminal = Terminal(self, self.text_area) # run terminal self.bind_events() self.open_file = '' self.protocol("WM_DELETE_WINDOW", self.close_window) def create_widget(self): self.text_area = TextArea(self.frame1, bg=self.text_background, fg=self.text_foreground, undo=True, relief=tk.FLAT, font=(self.text_font_family, self.text_font_size), insertbackground=self.insertbackground) self.text_area.config(highlightthickness=0) self.text_area.grid(row=0, column=1, sticky='wens') self.text_area.focus_set() self.welcome(event=None) self.status_bar1 = StatusBar(self.frame2, bg="pink", width=30, height=10) self.status_bar2 = StatusBar(self.frame2, bg="orange", width=30, height=10) self.status_bar3 = StatusBar(self.frame2, bg="blue", width=30, height=10) self.status_bar4 = StatusBar(self.frame2, bg="green", width=30, height=10) self.status_bar5 = StatusBar(self.frame2, bg="purple", width=30, height=10) self.status_bar1.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.status_bar2.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.status_bar3.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.status_bar4.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) self.status_bar5.pack(side=tk.LEFT, fill=tk.BOTH, expand=True) def editor_mode(self, event=None): self.text_area.config(state=tk.NORMAL, tabs=4) self.text_area.delete('1.0', tk.END) self.text_area.insert(tk.END, self.editor_mode_buffer) self.highlighter = Highlighter(self.text_area) self.thee_mode = 1 self.line_numbers = LineNumbers(self.frame1, self.text_area) self.line_numbers.config(bg=self.text_background, width=len(self.line_numbers.line_number) * 10, highlightthickness=0) self.line_numbers.grid(row=0, column=0, sticky='ns') self.status_bar1.set("Line %d, Column %d" % (self.line, self.column)) self.status_bar3.set("%s" % self.file_name) self.status_bar4.set("Spaces: %d" % self.spaces) self.status_bar5.set("%s" % self.status) def terminal_mode(self, event=None): if self.thee_mode == 1: self.line_numbers.destroy() self.text_area.config(state=tk.NORMAL, tabs=4) self.text_area.delete('1.0', tk.END) self.text_area.insert(tk.END, self.terminal_mode_buffer) self.terminal.writeLoop() self.highlighter = Highlighter(self.text_area) self.thee_mode = 2 def text_been_modified(self, event=None): flag = self.text_area.edit_modified() if flag: # prevent from getting called twice if self.thee_mode == 1 and self.count_text_changed > 1: # editor mode self.editor_mode_buffer = self.text_area.get( 1.0, tk.END + "-1c") self.status = "unsaved" self.status_bar5.set("%s" % self.status) self.update_line_column() self.line_numbers.config( width=len(self.line_numbers.line_number) * 10) elif self.thee_mode == 2 and self.count_text_changed > 1: # terminal mode self.terminal_mode_buffer = self.text_area.get( 1.0, tk.END + "-1c") self.count_text_changed += 1 #reset so this will be called on the next change self.text_area.edit_modified(False) def retrieve_selected_line(self, event=None): if self.thee_mode == 1: self.current_line = self.text_area.get("1.0", 'end').rstrip() if event.keysym.isnumeric(): self.key_buffer.append(event.keysym) # check buffer after 500ms (0.5s) self.after(500, self.selected_line_action) def selected_line_action(self): if self.key_buffer: index = int(''.join(self.key_buffer)) - 1 self.key_buffer.clear() self.selected_line = self.current_line.split('\n')[index] selected_str = self.selected_line + "\n" # write selected code line(s) to the console in order to it running self.terminal.proc.stdin.write(selected_str.encode()) self.terminal.proc.stdin.flush() self.terminal_mode() def update_line_column(self, event=None): if self.thee_mode == 1: line, column = self.text_area.index(tk.INSERT).split('.') self.line = int(line) self.column = int(column) + 1 self.status_bar1.set("Line %d, Column %d" % (self.line, self.column)) def close_window(self): if self.editor_mode_buffer and self.status == "unsaved": #and self.status.get() == "unsaved": #SATUSBAR if msg.askokcancel("Quit", "Would you like to save the data?"): self.file_save() self.terminal.alive = False self.terminal.destroy() else: self.terminal.alive = False self.terminal.destroy() else: self.terminal.alive = False self.terminal.destroy() def bind_events(self): self.focus_set() self.text_area.bind_all('<<Modified>>', self.text_been_modified) self.text_area.bind('<Return>', self.enter) self.bind_all('<Button-1>', self.update_line_column) self.bind_all('<Control-e>', self.editor_mode) self.bind_all('<Control-t>', self.terminal_mode) self.bind_all('<Control-Key>', self.retrieve_selected_line) self.bind('<Control-f>', self.show_find_window) self.bind('<Control-n>', self.file_new) self.bind('<Control-o>', self.file_open) self.bind('<Control-s>', self.file_save) self.bind('<Control-S>', self.file_save_as) self.bind('<Control-w>', self.welcome) self.bind('<Control-h>', self.help_about) def enter(self, event=None): if self.thee_mode == 2: self.terminal.enter() def show_find_window(self, event=None): FindWindow(self.frame1, self.text_area) def show_welcome_page(self): if self.thee_mode == 1: self.line_numbers.destroy() self.text_area.config(state=tk.NORMAL) self.text_area.delete('1.0', tk.END) message = ''' \n\n THEE version 1.0 THE simple python key bindings Editor type Ctrl-h for help information by Fidel R. Monteiro <*****@*****.**> \n The Pynosso Project | Sat, Jun 26 2020 ''' self.text_area.insert(tk.END, message) self.text_area.config(state=tk.DISABLED) self.thee_mode = 0 def show_about_page(self): if self.thee_mode == 1: self.line_numbers.destroy() self.text_area.config(state=tk.NORMAL) self.text_area.delete('1.0', tk.END) message = ''' HELP Mode Commands Ctrl+e : Text mode Ctrl+t : Terminal mode Ctrl+<number> : Run selected line in python console Editing Commands Ctrl+a : Select all text Ctrl+x : Cut selected text Ctrl+c : Copy selected text Ctrl+v : Paste cut/copied text Ctrl+z : Undo Ctrl+y : Redo File Commands Ctrl+o : Open file Ctrl+s : Save current content Ctrl+S : Save current content as <filename> Ctrl+p : Print current content Ctrl+n : Open new file General Ctrl+m : Change syntax highlighting Ctrl+g : Change colour scheme Ctrl+l : Change font Ctrl+h : Display this help window AUTHOR Written by Fidel R. Monteiro (fm65) Sat, Jun 26 2020 thee version 1.0 "simple is better than complex" ''' self.text_area.insert(tk.END, message) self.text_area.config(state=tk.DISABLED) self.thee_mode = 3 def apply_colour_scheme(self, foreground, background, text_foreground, text_background): self.text_area.configure(fg=text_foreground, bg=text_background) self.background = background self.foreground = foreground for menu in self.all_menus: menu.configure(bg=self.background, fg=self.foreground) def update_font(self): #self.load_font_file(self.font_scheme_path) self.text_area.configure(font=(self.text_font_family, self.text_font_size)) def create_config_directory_if_needed(self): if not os.path.exists(self.config_dir): os.mkdir(self.config_dir) # =========== Menu Functions ============== def file_new(self, event=None): """ Ctrl+N """ self.text_area.delete(1.0, tk.END) self.open_file = None self.editor_mode() self.line_numbers.force_update() def file_open(self, event=None): """ Ctrl+O """ self.editor_mode() file_to_open = filedialog.askopenfilename(filetypes=[('Python files', '*.py')], defaultextension='.py') if file_to_open: self.open_file = file_to_open self.file_name = self.open_file.split('/')[-1] self.status_bar3.set("%s" % self.file_name) self.text_area.display_file_contents(file_to_open) self.highlighter.force_highlight() self.line_numbers.force_update() def file_save(self, event=None): """ Ctrl+s """ current_file = self.open_file if self.open_file else None if not current_file: current_file = filedialog.asksaveasfilename(filetypes=[ ('Python files', '*.py') ], defaultextension='.py') self.open_file = current_file self.file_name = current_file.split('/')[-1] self.status_bar3.set("%s" % self.file_name) if current_file: contents = self.text_area.get(1.0, tk.END) with open(current_file, 'w') as file: file.write(contents) self.status = "saved" self.status_bar5.set("%s" % self.status) def file_save_as(self, event=None): """ Ctrl+S """ new_file_name = filedialog.asksaveasfilename(filetypes=[ ('Python files', '*.py') ], defaultextension='.py', confirmoverwrite=False) f = open(self.new_file_name, 'w') f.write(self.get('1.0', 'end')) f.close() self.status = "saved" self.status_bar5.set("%s" % self.status) def edit_cut(self, event=None): """ Ctrl+X """ self.text_area.event_generate("<Control-x>") self.line_numbers.force_update() def edit_paste(self, event=None): """ Ctrl+V """ self.text_area.event_generate("<Control-v>") self.line_numbers.force_update() self.highlighter.force_highlight() def edit_copy(self, event=None): """ Ctrl+C """ self.text_area.event_generate("<Control-c>") def edit_select_all(self, event=None): """ Ctrl+A """ self.text_area.event_generate("<Control-a>") def edit_find_and_replace(self, event=None): """ Ctrl+F """ self.show_find_window() def welcome(self, event=None): """ Ctrl+W """ self.show_welcome_page() def help_about(self, event=None): """ Ctrl+H """ self.show_about_page()
def __init__(self): super().__init__() self.title('Text Editor') self.text_area = TextArea(self, bg="white", fg="black", undo=True) self.background = 'lightgrey' self.foreground = 'black' self.text_foreground = 'black' self.text_background = 'white' self.config_dir = os.path.join(str(Path.home()), '.tkedit') self.default_scheme_path = os.path.join(self.config_dir, 'schemes/default.yaml') self.python_language_path = os.path.join(self.config_dir, 'languages/python.yaml') self.font_scheme_path = os.path.join(self.config_dir, 'schemes/font.yaml') self.create_config_directory_if_needed() self.load_scheme_file(self.default_scheme_path) self.configure_ttk_elements() self.font_size = 15 self.font_family = "Ubuntu Mono" self.load_font_file(self.font_scheme_path) self.highlighter = Highlighter(self.text_area, self.python_language_path) self.menu = tk.Menu(self, bg=self.background, fg=self.foreground) self.all_menus = [self.menu] sub_menu_items = ['file', 'edit', 'tools', 'help'] self.generate_sub_menus(sub_menu_items) self.configure(menu=self.menu) self.right_click_menu = tk.Menu(self, bg='lightgrey', fg='black', tearoff=0) self.right_click_menu.add_command(label='Cut', command=self.edit_cut) self.right_click_menu.add_command(label='Copy', command=self.edit_copy) self.right_click_menu.add_command(label='Paste', command=self.edit_paste) self.all_menus.append(self.right_click_menu) self.open_file = None self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = LineNumbers(self, self.text_area, bg='grey', fg='white', width=1) ''' self.line_numbers = tk.Text(self, bg="grey", fg="yellow") first_100_numbers = [str(n+1) for n in range(100)] self.line_numbers.insert(1.0, "\n".join(first_100_numbers)) self.line_numbers.configure(state="disabled", width=3) ''' self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events()
class StatusBar: def __init__(self, window, text_buffer, font, color, border): self.window = window self.text_buffer = text_buffer self.font = font self.color = color self.border = border self.height = font.size[1] + border[0] + border[2] self.width = window.size[0] self.msg = None self.msg_start = None self.input = None self.input_label = None def get_line_pos_text(self): return "{}:{}".format(self.text_buffer.cursor_pos[0] + 1, self.text_buffer.cursor_pos[1] + 1) def draw(self): window_surface = self.window.get_surface() sb_y = self.window.size[1] - self.height sdl2.ext.fill(window_surface, self.color, area=(0, sb_y, self.width, self.height)) text = self.get_line_pos_text() self.font.render_on( window_surface, text, offset=(self.window.size[0] - ((self.font.size[0] * len(text)) + self.border[1]), sb_y + self.border[0])) if self.msg_start is not None and sdl2.SDL_GetTicks( ) - self.msg_start < STATUS_BAR_MSG_DURATION: self.font.render_on(window_surface, self.msg, offset=(self.border[1], self.window.size[1] - self.height + self.border[0])) elif self.msg_start is not None: self.msg_start = None def init_input(self, label, text=None): self.input_label = label self.input = TextArea( self.window, self.font, TextBuffer(text), window_border=(self.window.size[1] - self.height + self.border[0], self.border[1], self.border[2], (self.font.size[0] * len(label)) + (2 * self.border[3])), line_spacing=0) def draw_label(self): window_surface = self.window.get_surface() sdl2.ext.fill(window_surface, self.color, area=(0, self.window.size[1] - self.height, self.width, self.height)) self.font.render_on(window_surface, self.input_label, offset=(self.border[1], self.window.size[1] - self.height + self.border[0])) def draw_input(self): self.draw_label() self.input.draw() def handle_input(self, events): self.input.handle_input(events) def display_msg(self, msg): self.msg = msg self.msg_start = sdl2.SDL_GetTicks()
class MainWindow(tk.Tk): def __init__(self): super().__init__() self.title('Python Text Editor v3') self.geometry('800x600') self.foreground = 'black' self.background = 'lightgrey' self.text_foreground = '#313131' self.text_background = '#f0f0f0' self.terminal_background = 'darkcyan' self.terminal_foreground = 'white' self.config_dir = os.path.join(str(Path.home()), '.tkedit') self.default_scheme_path = os.path.join(self.config_dir, 'schemes/default.yaml') self.python_language_path = os.path.join(self.config_dir, 'languages/python.yaml') self.font_scheme_path = os.path.join(self.config_dir, 'schemes/font.yaml') self.create_config_directory_if_needed() self.load_scheme_file(self.default_scheme_path) self.configure_ttk_elements() # Change self.font_size = 14 self.font_family = "Droid Sana Mono" self.terminal_font_size = 12 self.terminal_font_family = "Consolas" # Change self.load_font_file(self.font_scheme_path) self.text_area = TextArea(self, bg=self.text_background, fg=self.text_foreground, undo=True, font=(self.font_family, self.font_size)) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1, font=(self.font_family, self.font_size)) self.highlighter = Highlighter(self.text_area, self.python_language_path) self.terminal = Terminal(self, height=8, bg=self.terminal_background, fg=self.terminal_foreground, undo=True, font=(self.terminal_font_family, self.terminal_font_size)) self.menu = tk.Menu(self, bg=self.background, fg=self.foreground) self.all_menus = [self.menu] self.text_area.__setattr__("update_line", self.line_numbers.force_update) self.text_area.__setattr__("update_highlight", self.highlighter.force_highlight) sub_menu_items = ["file", "edit", "tools", "help"] self.generate_sub_menus(sub_menu_items) self.configure(menu=self.menu) self.right_click_menu = tk.Menu(self, bg=self.background, fg=self.foreground, tearoff=0) self.right_click_menu.add_command(label='Cut', command=self.edit_cut) self.right_click_menu.add_command(label='Copy', command=self.edit_copy) self.right_click_menu.add_command(label='Paste', command=self.edit_paste) # Change self.right_click_menu.add_command(label='Undo', command=self.edit_undo) self.right_click_menu.add_command(label='Redo', command=self.edit_redo) # Change self.all_menus.append(self.right_click_menu) # change self.count_area = tk.Text(self, height=1) self.count_area.pack(side=tk.BOTTOM, fill=tk.X) # change # Change self.terminal.pack(side=tk.BOTTOM, fill=tk.X) # Change self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() self.open_file = '' def bind_events(self): self.text_area.bind("<MouseWheel>", self.scroll_text) self.text_area.bind("<Button-4>", self.scroll_text) self.text_area.bind("<Button-5>", self.scroll_text) self.text_area.bind("<Button-3>", self.show_right_click_menu) # Change self.count_area.bind(self.count_text()) # Change self.bind('<Control-f>', self.show_find_window) self.bind('<Control-n>', self.file_new) self.bind('<Control-o>', self.file_open) self.bind('<Control-s>', self.file_save) self.bind('<Control-h>', self.help_about) self.bind('<Control-m>', self.tools_change_syntax_highlighting) self.bind('<Control-g>', self.tools_change_colour_scheme) self.bind('<Control-l>', self.tools_change_font) self.line_numbers.bind("<MouseWheel>", lambda e: "break") self.line_numbers.bind("<Button-4>", lambda e: "break") self.line_numbers.bind("<Button-5>", lambda e: "break") # change def count_text(self): contents = self.text_area.get(1.0, tk.END).replace(" ", "").split("\n") self.count_area.delete(1.0, tk.END) self.count_area.insert( tk.END, "当前字数为:" + str(CountWord(contents).bind_event(contents)) + " 字") return self.after(50, self.count_text) # change def scroll_text(self, *args): if len(args) > 1: self.text_area.yview_moveto(args[1]) self.line_numbers.yview_moveto(args[1]) else: event = args[0] if event.delta: move = -1 * (event.delta / 120) else: if event.num == 5: move = 1 else: move = -1 self.text_area.yview_scroll(int(move), "units") self.line_numbers.yview_scroll(int(move) * 3, "units") def show_find_window(self, event=None): FindWindow(self.text_area) def show_right_click_menu(self, event): x = self.winfo_x() + self.text_area.winfo_x() + event.x y = self.winfo_y() + self.text_area.winfo_y() + event.y self.right_click_menu.post(x, y) def generate_sub_menus(self, sub_menu_items): window_methods = [ method_name for method_name in dir(self) if callable(getattr(self, method_name)) ] tkinter_methods = [ method_name for method_name in dir(tk.Tk) if callable(getattr(tk.Tk, method_name)) ] my_methods = [ method for method in set(window_methods) - set(tkinter_methods) ] my_methods = sorted(my_methods) for item in sub_menu_items: sub_menu = tk.Menu(self.menu, tearoff=0, bg=self.background, fg=self.foreground) matching_methods = [] for method in my_methods: if method.startswith(item): matching_methods.append(method) for match in matching_methods: actual_method = getattr(self, match) method_shortcut = actual_method.__doc__.strip() friendly_name = ' '.join(match.split('_')[1:]) sub_menu.add_command(label=friendly_name.title(), command=actual_method, accelerator=method_shortcut) self.menu.add_cascade(label=item.title(), menu=sub_menu) self.all_menus.append(sub_menu) def show_about_page(self): msg.showinfo( "About", "My text editor, version 2, written in Python3.6 using tkinter!") def load_syntax_highlighting_file(self): syntax_file = filedialog.askopenfilename(filetypes=[("YAML file", ("*.yaml", "*.yml"))]) if syntax_file: self.highlighter.clear_highlight() self.highlighter = Highlighter(self.text_area, syntax_file) self.highlighter.force_highlight() def load_scheme_file(self, scheme): with open(scheme, 'r') as stream: try: config = yaml.load(stream) except yaml.YAMLError as error: print(error) return self.foreground = config['foreground'] self.background = config['background'] self.text_foreground = config['text_foreground'] self.text_background = config['text_background'] def load_font_file(self, file_path): with open(file_path, 'r') as stream: try: config = yaml.load(stream) except yaml.YAMLError as error: print(error) return self.font_family = config['family'] self.font_size = config['size'] def change_colour_scheme(self): ColourChooser(self) def apply_colour_scheme(self, foreground, background, text_foreground, text_background): self.text_area.configure(fg=text_foreground, bg=text_background) self.background = background self.foreground = foreground for menu in self.all_menus: menu.configure(bg=self.background, fg=self.foreground) self.configure_ttk_elements() def configure_ttk_elements(self): style = ttk.Style() style.configure('editor.TLabel', foreground=self.foreground, background=self.background) style.configure('editor.TButton', foreground=self.foreground, background=self.background) def change_font(self): FontChooser(self) def update_font(self): self.load_font_file(self.font_scheme_path) self.text_area.configure(font=(self.font_family, self.font_size)) def create_config_directory_if_needed(self): if not os.path.exists(self.config_dir): os.mkdir(self.config_dir) os.mkdir(os.path.join(self.config_dir, 'schemes')) os.mkdir(os.path.join(self.config_dir, 'languages')) self.create_default_scheme_if_needed() self.create_font_scheme_if_needed() self.create_python_language_if_needed() def create_default_scheme_if_needed(self): if not os.path.exists(self.default_scheme_path): yaml_file_contents = f"background: 'lightgrey'\n" \ + f"foreground: 'black'\n" \ + f"text_background: 'white'\n" \ + f"text_foreground: 'black'\n" with open(self.default_scheme_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) def create_font_scheme_if_needed(self): if not os.path.exists(self.font_scheme_path): yaml_file_contents = f"family: Ubuntu Mono\n" \ + f"size: 14" with open(self.font_scheme_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) def create_python_language_if_needed(self): if not os.path.exists(self.python_language_path): yaml_file_contents = """ categories: keywords: colour: orange matches: [for, def, while, from, import, as, with, self] variables: colour: red4 matches: ['True', 'False', None] conditionals: colour: green matches: [try, except, if, else, elif] functions: colour: blue4 matches: [int, str, dict, list, set, float] numbers: colour: purple strings: colour: '#e1218b' """ with open(self.python_language_path, 'w') as yaml_file: yaml_file.write(yaml_file_contents) # =========== Menu Functions ============== def file_new(self, event=None): """ Ctrl+N """ self.text_area.delete(1.0, tk.END) self.open_file = None self.line_numbers.force_update() def file_open(self, event=None): """ Ctrl+O """ file_to_open = filedialog.askopenfilename() if file_to_open: self.open_file = file_to_open self.text_area.display_file_contents(file_to_open) self.highlighter.force_highlight() self.line_numbers.force_update() def file_save(self, event=None): """ Ctrl+S """ current_file = self.open_file if self.open_file else None if not current_file: current_file = filedialog.asksaveasfilename() if current_file: contents = self.text_area.get(1.0, tk.END) with open(current_file, 'w') as file: file.write(contents) def edit_cut(self, event=None): """ Ctrl+X """ self.text_area.event_generate("<Control-x>") self.line_numbers.force_update() self.highlighter.force_highlight() def edit_paste(self, event=None): """ Ctrl+V """ self.text_area.event_generate("<Control-v>") self.line_numbers.force_update() self.highlighter.force_highlight() def edit_copy(self, event=None): """ Ctrl+C """ self.text_area.event_generate("<Control-c>") def edit_select_all(self, event=None): """ Ctrl+A """ self.text_area.event_generate("<Control-a>") def edit_find_and_replace(self, event=None): """ Ctrl+F """ self.show_find_window() def edit_undo(self, event=None): """ Ctrl+Z """ self.text_area.event_generate("<Control-z>") self.line_numbers.force_update() self.highlighter.force_highlight() def edit_redo(self, event=None): """ Ctrl+Y """ self.text_area.event_generate("<Control-y>") self.line_numbers.force_update() self.highlighter.force_highlight() def help_about(self, event=None): """ Ctrl+H """ self.show_about_page() def tools_change_syntax_highlighting(self, event=None): """ Ctrl+M """ self.load_syntax_highlighting_file() def tools_change_colour_scheme(self, event=None): """ Ctrl+G """ self.change_colour_scheme() def tools_change_font(self, event=None): """ Ctrl+L """ self.change_font()
def __init__(self): super().__init__() self.title('Python Text Editor v3') self.geometry('800x600') self.foreground = 'black' self.background = 'lightgrey' self.text_foreground = '#313131' self.text_background = '#f0f0f0' self.terminal_background = 'darkcyan' self.terminal_foreground = 'white' self.config_dir = os.path.join(str(Path.home()), '.tkedit') self.default_scheme_path = os.path.join(self.config_dir, 'schemes/default.yaml') self.python_language_path = os.path.join(self.config_dir, 'languages/python.yaml') self.font_scheme_path = os.path.join(self.config_dir, 'schemes/font.yaml') self.create_config_directory_if_needed() self.load_scheme_file(self.default_scheme_path) self.configure_ttk_elements() # Change self.font_size = 14 self.font_family = "Droid Sana Mono" self.terminal_font_size = 12 self.terminal_font_family = "Consolas" # Change self.load_font_file(self.font_scheme_path) self.text_area = TextArea(self, bg=self.text_background, fg=self.text_foreground, undo=True, font=(self.font_family, self.font_size)) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1, font=(self.font_family, self.font_size)) self.highlighter = Highlighter(self.text_area, self.python_language_path) self.terminal = Terminal(self, height=8, bg=self.terminal_background, fg=self.terminal_foreground, undo=True, font=(self.terminal_font_family, self.terminal_font_size)) self.menu = tk.Menu(self, bg=self.background, fg=self.foreground) self.all_menus = [self.menu] self.text_area.__setattr__("update_line", self.line_numbers.force_update) self.text_area.__setattr__("update_highlight", self.highlighter.force_highlight) sub_menu_items = ["file", "edit", "tools", "help"] self.generate_sub_menus(sub_menu_items) self.configure(menu=self.menu) self.right_click_menu = tk.Menu(self, bg=self.background, fg=self.foreground, tearoff=0) self.right_click_menu.add_command(label='Cut', command=self.edit_cut) self.right_click_menu.add_command(label='Copy', command=self.edit_copy) self.right_click_menu.add_command(label='Paste', command=self.edit_paste) # Change self.right_click_menu.add_command(label='Undo', command=self.edit_undo) self.right_click_menu.add_command(label='Redo', command=self.edit_redo) # Change self.all_menus.append(self.right_click_menu) # change self.count_area = tk.Text(self, height=1) self.count_area.pack(side=tk.BOTTOM, fill=tk.X) # change # Change self.terminal.pack(side=tk.BOTTOM, fill=tk.X) # Change self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() self.open_file = ''
class MainWindow(tk.Tk): def __init__(self): super().__init__() self.text_area = TextArea(self, bg="white", fg="black", undo=True) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1) self.highlighter = Highlighter(self.text_area, 'languages/python.yaml') self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() def bind_events(self): self.text_area.bind("<MouseWheel>", self.scroll_text) self.text_area.bind("<Button-4>", self.scroll_text) self.text_area.bind("<Button-5>", self.scroll_text) self.bind('<Control-f>', self.show_find_window) self.line_numbers.bind("<MouseWheel>", lambda e: "break") self.line_numbers.bind("<Button-4>", lambda e: "break") self.line_numbers.bind("<Button-5>", lambda e: "break") def scroll_text(self, *args): if len(args) > 1: self.text_area.yview_moveto(args[1]) self.line_numbers.yview_moveto(args[1]) else: event = args[0] if event.delta: move = -1 * (event.delta / 120) else: if event.num == 5: move = 1 else: move = -1 self.text_area.yview_scroll(int(move), "units") self.line_numbers.yview_scroll(int(move) * 3, "units") def show_find_window(self, event=None): FindWindow(self.text_area)
class MainWindow(tk.Tk): def __init__(self): super().__init__() self.text_area = TextArea(self, bg="white", fg="black", undo=True) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = tk.Text(self, bg="grey", fg="white") first_100_numbers = [str(n + 1) for n in range(100)] self.line_numbers.insert(1.0, "\n".join(first_100_numbers)) self.line_numbers.configure(state="disabled", width=3) self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() def bind_events(self): self.text_area.bind("<MouseWheel>", self.scroll_text) self.text_area.bind("<Button-4>", self.scroll_text) self.text_area.bind("<Button-5>", self.scroll_text) self.line_numbers.bind("<MouseWheel>", lambda e: "break") self.line_numbers.bind("<Button-4>", lambda e: "break") self.line_numbers.bind("<Button-5>", lambda e: "break") def scroll_text(self, *args): if len(args) > 1: self.text_area.yview_moveto(args[1]) self.line_numbers.yview_moveto(args[1]) else: event = args[0] if event.delta: move = -1 * (event.delta / 120) else: if event.num == 5: move = 1 else: move = -1 self.text_area.yview_scroll(int(move), "units") self.line_numbers.yview_scroll(int(move) * 3, "units")
def __init__(self): ''' @update 1.添加横向滚动条 2.修正行号与滚动条和窗口的关联 3.修正行号显示 ''' super().__init__() self.title('Python Text Editor v3') self.geometry('800x600') self.foreground = 'black' self.background = 'lightgrey' self.text_foreground = 'black' self.text_background = 'white' self.config_dir = os.path.join(str(Path.home()), '.tkedit') self.default_scheme_path = os.path.join(self.config_dir, 'schemes/default.yaml') self.python_language_path = os.path.join(self.config_dir, 'languages/python.yaml') self.none_language_path = os.path.join(self.config_dir, 'languages/None.yaml') self.font_scheme_path = os.path.join(self.config_dir, 'fonts/font.yaml') self.create_config_directory_if_needed() self.load_scheme_file(self.default_scheme_path) self.configure_ttk_elements() self.font_size = 15 self.font_family = "Ubuntu Mono" self.load_font_file(self.font_scheme_path) self.text_area = TextArea(self, bg=self.text_background, fg=self.text_foreground, undo=True, font=(self.font_family, self.font_size)) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.text_area.yview) self.scrollbar2 = ttk.Scrollbar(orient="horizontal", command=self.text_area.xview) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1, font=(self.font_family, self.font_size)) self.scrollbar.config(command=self.text_area.yview) self.text_area.config(yscrollcommand=self.scrollbar.set, xscrollcommand=self.scrollbar2.set) self.highlighter = Highlighter(self.text_area, self.none_language_path) self.menu = tk.Menu(self, bg=self.background, fg=self.foreground) self.all_menus = [self.menu] sub_menu_items = ["file", "edit", "tools", "help"] self.generate_sub_menus(sub_menu_items) self.configure(menu=self.menu) self.right_click_menu = tk.Menu(self, bg=self.background, fg=self.foreground, tearoff=0) self.right_click_menu.add_command(label='Cut', command=self.edit_cut) self.right_click_menu.add_command(label='Copy', command=self.edit_copy) self.right_click_menu.add_command(label='Paste', command=self.edit_paste) self.all_menus.append(self.right_click_menu) self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.scrollbar2.pack(side=tk.BOTTOM, fill=tk.X) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() self.open_file = ''
class MinimalEdit(Tk): """The minimaledit application. Create, and then call the .mainloop() method. """ is_fullscreen = False saved_geometry = None textarea = None def __init__(self): Tk.__init__(self) self.makewidgets() self.mapkeys() self.style() # Catch the "click on close" event. self.protocol("WM_DELETE_WINDOW", self.onquit) def style(self): self.config(background="#000000", borderwidth=0, highlightbackground="#000000") if os_sniffer.is_mac: # Trying to get rid of the title bar on a mac. # This must be done before the window is actually created. # If we want to be able to have a title bar in windowed mode and # have no title bar in minimal editing mode, we'll need to rebuild # the window. self.tk.call("::tk::unsupported::MacWindowStyle", "style", self._w, "plain", "noTitleBar") # On Mac OS X, attempt to make the window appear on top vs. behind # other windows. # This is a total hack, but it seems to work quite well. # We set up a delayed callback that will ensure the application is # up and running, force the application to be topmost which will, # even on mac move the application above all other windows in the # desktop, but then allow the window to lose focus later if the user # chooses to switch to another application in the desktop. # I'm working around an apparent bug according to the interwebs, # but it seems to work. # NOTE: The best I can do with this so far is setting the window on # top. Having the window have focus is not happening when not running # this application as a py2app. # TODO: test running as a py2app to see if I can grab focus. def mac_osx_lift_callback(): self.tk.call('wm', 'attributes', '.', '-topmost', '1') self.tk.call('update') self.tk.call('wm', 'attributes', '.', '-topmost', '0') self.tk.call('update') self.after(100, mac_osx_lift_callback) def makewidgets(self): self.title("MinimalEdit") self.textarea = TextArea(self) def mapkeys(self): if os_sniffer.is_mac: command_key = "Command" else: command_key = "Control" self.bind("<"+command_key+"-n>", lambda a: self.onnew()) self.bind("<"+command_key+"-l>", lambda a: self.onload()) self.bind("<"+command_key+"-s>", lambda a: self.onsave()) self.bind("<"+command_key+"-f>", lambda a: self.onfind()) self.bind("<"+command_key+"-q>", lambda a: self.onquit()) self.bind("<Escape>", lambda a: self.toggleminimal()) def onquit(self): ans = askokcancel("Verify exit", "Really quit?") if ans: # NOTE: On Mac, there seems to be a bug with preventing the # program from quitting. We can intercept the event and do # what clean up we need to do here. However, once this function # exits, on mac os x (but not on windows) our program will close # no matter what. This is a tkinter version problem on mac. # TODO: Need to confirm that I'm using the non-Apple tkinter. self.quit() def onnew(self): ans = askokcancel("Verify new file", "Really start a new file?") if ans: self.textarea.settext(text='') def onload(self): filename = askopenfilename() if filename: f = open(filename, 'r') alltext = f.read() self.textarea.settext(alltext) f.close() def onsave(self): filename = asksaveasfilename() if filename: alltext = self.textarea.gettext() f = open(filename, 'w') f.write(alltext) f.close() def onfind(self): target = askstring('Search String', '') if target: self.textarea.findtext(target) def storegeometry(self): pg = re.split(r"x|\+", self.geometry()) self.saved_geometry = tuple(pg) def restoregeometry(self): if self.saved_geometry: self.geometry("{0[0]}x{0[1]}+{0[2]}+{0[3]}".format(self.saved_geometry)) def setfullscreenview(self): # Store the previous geometry self.storegeometry() if os_sniffer.is_mac: # Assuming this is TK 8.5 or higher self.wm_attributes('-fullscreen', 1) # Default for all systems self.overrideredirect(1) self.geometry("{0}x{1}+0+0".format(self.winfo_screenwidth(), self.winfo_screenheight())) def setwindowedview(self): if os_sniffer.is_mac: # Assuming this is TK 8.5 or higher self.wm_attributes('-fullscreen', 0) # Default for all systems self.overrideredirect(0) self.restoregeometry() def toggleminimal(self): if self.is_fullscreen == False: self.is_fullscreen = True self.setfullscreenview() self.textarea.toggleminimal() else: self.is_fullscreen = False self.setwindowedview() self.textarea.toggleminimal()
def makewidgets(self): self.title("MinimalEdit") self.textarea = TextArea(self)
class MainWindow(tk.Tk): def __init__(self): super().__init__() self.title('Python Text Editor v3') self.geometry('800x600') self.foreground = 'black' self.background = 'lightgrey' self.text_foreground = 'black' self.text_background = 'white' self.load_scheme_file('schemes/default.yaml') self.configure_ttk_elements() self.font_size = 15 self.font_family = "Ubuntu Mono" self.load_font_file('schemes/font.yaml') self.text_area = TextArea(self, bg=self.text_background, fg=self.text_foreground, undo=True, font=(self.font_family, self.font_size)) self.scrollbar = ttk.Scrollbar(orient="vertical", command=self.scroll_text) self.text_area.configure(yscrollcommand=self.scrollbar.set) self.line_numbers = LineNumbers(self, self.text_area, bg="grey", fg="white", width=1) self.highlighter = Highlighter(self.text_area, 'languages/python.yaml') self.menu = tk.Menu(self, bg=self.background, fg=self.foreground) self.all_menus = [self.menu] sub_menu_items = ["file", "edit", "tools", "help"] self.generate_sub_menus(sub_menu_items) self.configure(menu=self.menu) self.right_click_menu = tk.Menu(self, bg=self.background, fg=self.foreground, tearoff=0) self.right_click_menu.add_command(label='Cut', command=self.edit_cut) self.right_click_menu.add_command(label='Copy', command=self.edit_copy) self.right_click_menu.add_command(label='Paste', command=self.edit_paste) self.all_menus.append(self.right_click_menu) self.scrollbar.pack(side=tk.RIGHT, fill=tk.Y) self.line_numbers.pack(side=tk.LEFT, fill=tk.Y) self.text_area.pack(side=tk.LEFT, fill=tk.BOTH, expand=1) self.bind_events() self.open_file = '' def bind_events(self): self.text_area.bind("<MouseWheel>", self.scroll_text) self.text_area.bind("<Button-4>", self.scroll_text) self.text_area.bind("<Button-5>", self.scroll_text) self.text_area.bind("<Button-3>", self.show_right_click_menu) self.bind('<Control-f>', self.show_find_window) self.bind('<Control-n>', self.file_new) self.bind('<Control-o>', self.file_open) self.bind('<Control-s>', self.file_save) self.bind('<Control-h>', self.help_about) self.bind('<Control-m>', self.tools_change_syntax_highlighting) self.bind('<Control-g>', self.tools_change_color_scheme) self.bind('<Control-l>', self.tools_change_font) self.line_numbers.bind("<MouseWheel>", lambda e: "break") self.line_numbers.bind("<Button-4>", lambda e: "break") self.line_numbers.bind("<Button-5>", lambda e: "break") def scroll_text(self, *args): if len(args) > 1: self.text_area.yview_moveto(args[1]) self.line_numbers.yview_moveto(args[1]) else: event = args[0] if event.delta: move = -1 * (event.delta / 120) else: if event.num == 5: move = 1 else: move = -1 self.text_area.yview_scroll(int(move), "units") self.line_numbers.yview_scroll(int(move) * 3, "units") def show_find_window(self, event=None): FindWindow(self.text_area) def show_right_click_menu(self, event): x = self.winfo_x() + self.text_area.winfo_x() + event.x y = self.winfo_y() + self.text_area.winfo_y() + event.y self.right_click_menu.post(x, y) def generate_sub_menus(self, sub_menu_items): window_methods = [ method_name for method_name in dir(self) if callable(getattr(self, method_name)) ] tkinter_methods = [ method_name for method_name in dir(tk.Tk) if callable(getattr(tk.Tk, method_name)) ] my_methods = [ method for method in set(window_methods) - set(tkinter_methods) ] my_methods = sorted(my_methods) for item in sub_menu_items: sub_menu = tk.Menu(self.menu, tearoff=0, bg=self.background, fg=self.foreground) matching_methods = [] for method in my_methods: if method.startswith(item): matching_methods.append(method) for match in matching_methods: actual_method = getattr(self, match) method_shortcut = actual_method.__doc__.strip() friendly_name = ' '.join(match.split('_')[1:]) sub_menu.add_command(label=friendly_name.title(), command=actual_method, accelerator=method_shortcut) self.menu.add_cascade(label=item.title(), menu=sub_menu) self.all_menus.append(sub_menu) def show_about_page(self): msg.showinfo( "About", "My text editor, version 2, written in Python3.6 using tkinter!") def load_syntax_highlighting_file(self): syntax_file = filedialog.askopenfilename(filetypes=[("YAML file", ("*.yaml", "*.yml"))]) if syntax_file: self.highlighter.clear_highlight() self.highlighter = Highlighter(self.text_area, syntax_file) self.highlighter.force_highlight() def load_scheme_file(self, scheme): with open(scheme, 'r') as stream: try: config = yaml.load(stream) except yaml.YAMLError as error: print(error) return self.foreground = config['foreground'] self.background = config['background'] self.text_foreground = config['text_foreground'] self.text_background = config['text_background'] def load_font_file(self, file_path): with open(file_path, 'r') as stream: try: config = yaml.load(stream) except yaml.YAMLError as error: print(error) return self.font_family = config['family'] self.font_size = config['size'] def change_color_scheme(self): colorChooser(self) def apply_color_scheme(self, foreground, background, text_foreground, text_background): self.text_area.configure(fg=text_foreground, bg=text_background) self.background = background self.foreground = foreground for menu in self.all_menus: menu.configure(bg=self.background, fg=self.foreground) self.configure_ttk_elements() def configure_ttk_elements(self): style = ttk.Style() style.configure('editor.TLabel', foreground=self.foreground, background=self.background) style.configure('editor.TButton', foreground=self.foreground, background=self.background) def change_font(self): FontChooser(self) def update_font(self): self.load_font_file('schemes/font.yaml') self.text_area.configure(font=(self.font_family, self.font_size)) # =========== Menu Functions ============== def file_new(self, event=None): """ Ctrl+N """ self.text_area.delete(1.0, tk.END) self.open_file = None self.line_numbers.force_update() def file_open(self, event=None): """ Ctrl+O """ file_to_open = filedialog.askopenfilename() if file_to_open: self.open_file = file_to_open self.text_area.display_file_contents(file_to_open) self.highlighter.force_highlight() self.line_numbers.force_update() def file_save(self, event=None): """ Ctrl+S """ current_file = self.open_file if self.open_file else None if not current_file: current_file = filedialog.asksaveasfilename() if current_file: contents = self.text_area.get(1.0, tk.END) with open(current_file, 'w') as file: file.write(contents) def edit_cut(self, event=None): """ Ctrl+X """ self.text_area.event_generate("<Control-x>") self.line_numbers.force_update() def edit_paste(self, event=None): """ Ctrl+V """ self.text_area.event_generate("<Control-v>") self.line_numbers.force_update() self.highlighter.force_highlight() def edit_copy(self, event=None): """ Ctrl+C """ self.text_area.event_generate("<Control-c>") def edit_select_all(self, event=None): """ Ctrl+A """ self.text_area.event_generate("<Control-a>") def edit_find_and_replace(self, event=None): """ Ctrl+F """ self.show_find_window() def help_about(self, event=None): """ Ctrl+H """ self.show_about_page() def tools_change_syntax_highlighting(self, event=None): """ Ctrl+M """ self.load_syntax_highlighting_file() def tools_change_color_scheme(self, event=None): """ Ctrl+G """ self.change_color_scheme() def tools_change_font(self, event=None): """ Ctrl+L """ self.change_font()
"textarea", ) reoptions = [('s', 'dotall', 'Dot Match All'), ('i', 'ignorecase', 'Case Insensitive'), ('m', 'multiline', '^$ at line breaks'), ('x', 'verbose', 'Free-Spacing'), ('u', 'unicode', 'Unicode')] funcs = [ '', 'Import regex library', 'If/else branch whether the regex matches (part of) a string' ] langs = ('python', ) app = web.application(urls, globals()) flag = Option() text = TextArea() env = Environment(loader=PackageLoader('index', 'templates')) #the home page(the only page) class index: def GET(self): template = env.get_template('index.html') return template.render(reoptions=reoptions, functions=funcs, langs=langs) #when option changes in the front, class options: def POST(self):