= How to create a simple text editor (Phoenix) = '''Keywords :''' Editor, Text, TextCtrl, Stc, StyledTextCtrl. <<TableOfContents>> -------- = Demonstrating : = __'''''Tested''' py3.x, wx4.x and Win10. ''__ Are you ready to use some samples ? ;) Test, modify, correct, complete, improve and share your discoveries ! (!) -------- == Sample one == {{attachment:img_sample_one.png}} {{{#!python # sample_one.py import sys import os.path import wx # class MyFrame # class MyApp #------------------------------------------------------------------------------- # This is how you pre-establish a file filter so that the # dialog only shows the extension(s) you want it to. wildcard = "Text (*.txt)|*.txt|" \ "Executable (*.exe)|*.exe|" \ "Library (*.dll)|*.dll|" \ "Driver (*.sys)|*.sys|" \ "ActiveX (*.ocx)|*.ocx|" \ "Python (*.py)|*.py|" \ "Python (*.pyw)|*.pyw|" \ "All (*.*)|*.*" #------------------------------------------------------------------------------- class MyFrame(wx.Frame): def __init__(self, filename="noname.txt"): super(MyFrame, self).__init__(None, size=(400, 300)) #------------ # Return icons folder. self.icons_dir = wx.GetApp().GetIconsDir() #------------ self.filename = filename self.dirname = "." #------------ # Simplified init method. self.CreateInteriorWindowComponents() self.CreateExteriorWindowComponents() #------------ self.CenterOnScreen() #--------------------------------------------------------------------------- def SetTitle(self): """ ... """ # MyFrame.SetTitle overrides wx.Frame.SetTitle, # so we have to call it using super : super(MyFrame, self).SetTitle("Editor %s" % self.filename) def CreateInteriorWindowComponents(self): """ Create "interior" window components. In this case it is just a simple multiline text control. """ self.control = wx.TextCtrl(self, -1, value="", style=wx.TE_MULTILINE) def CreateExteriorWindowComponents(self): """ Create "exterior" window components, such as menu and status bar. """ # Simplified init method. self.SetTitle() #------------ frameIcon = wx.Icon(os.path.join(self.icons_dir, "icon_wxWidgets.ico"), type=wx.BITMAP_TYPE_ICO) self.SetIcon(frameIcon) #------------ self.CreateMenu() self.CreateStatusBar() self.BindEvents() def CreateMenu(self): """ Create menu and menu bar. """ menuBar = wx.MenuBar() #------------ fileMenu = wx.Menu() for id, label, helpText, handler in \ [(wx.ID_ABOUT, "&About", "Information about this program.", self.OnAbout), (None, None, None, None), (wx.ID_OPEN, "&Open", "Open a new file.", self.OnOpen), (wx.ID_SAVE, "&Save", "Save the current file.", self.OnSave), (wx.ID_SAVEAS, "Save &as", "Save the file under a different name.", self.OnSaveAs), (None, None, None, None), (wx.ID_EXIT, "E&xit", "Terminate the program.", self.OnCloseMe)]: if id == None: fileMenu.AppendSeparator() else: item = fileMenu.Append(id, label, helpText) #------------ # Bind some events to an events handler. self.Bind(wx.EVT_MENU, handler, item) #------------ # Add the fileMenu to the menuBar. menuBar.Append(fileMenu, "&File") #------------ # Add the menuBar to the frame. self.SetMenuBar(menuBar) def BindEvents(self): """ ... """ self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) def DefaultFileDialogOptions(self): """ Return a dictionary with file dialog options that can be used in both the save file dialog as well as in the open file dialog. """ return dict(message="Choose a file :", defaultDir=self.dirname, wildcard=wildcard) def AskUserForFilename(self, **dialogOptions): """ ... """ dialog = wx.FileDialog(self, **dialogOptions) if dialog.ShowModal() == wx.ID_OK: userProvidedFilename = True self.filename = dialog.GetFilename() self.dirname = dialog.GetDirectory() # Update the window title with the new filename. self.SetTitle() else: userProvidedFilename = False dialog.Destroy() return userProvidedFilename def OnOpen(self, event): """ Open file. """ if self.AskUserForFilename(style=wx.FD_OPEN, **self.DefaultFileDialogOptions()): file = open(os.path.join(self.dirname, self.filename), 'r', encoding='utf-8') self.control.SetValue(file.read()) file.close() def OnSave(self, event): """ Save file. """ with open(os.path.join(self.dirname, self.filename), 'w', encoding='utf-8') as file: file.write(self.control.GetValue()) def OnSaveAs(self, event): """ Save file as. """ if self.AskUserForFilename(defaultFile=self.filename, style=wx.FD_SAVE, **self.DefaultFileDialogOptions()): self.OnSave(event) def OnAbout(self, event): """ About dialog. """ dialog = wx.MessageDialog(self, "A sample editor in wxPython.", "About sample editor", wx.OK) dialog.ShowModal() dialog.Destroy() def OnCloseMe(self, event): """ Close the main window. """ self.Close(True) def OnCloseWindow(self, event): """ Quit and destroy application. """ self.Destroy() #------------------------------------------------------------------------------- class MyApp(wx.App): """ .... """ def OnInit(self): #------------ self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0] #------------ frame = MyFrame() self.SetTopWindow(frame) frame.Show(True) return True #--------------------------------------------------------------------------- def GetInstallDir(self): """ Returns the installation directory for my application. """ return self.installDir def GetIconsDir(self): """ Returns the icons directory for my application. """ icons_dir = os.path.join(self.installDir, "icons") return icons_dir #------------------------------------------------------------------------------- def main(): app = MyApp(False) app.MainLoop() #------------------------------------------------------------------------------- if __name__ == "__main__" : main() }}} -------- == Sample two == {{attachment:img_sample_two.png}} {{{#!python # sample_two.py import sys import os.path import wx import wx.stc as stc # StyledTextCtrl # class MyFrame # class MyApp #------------------------------------------------------------------------------- # This is how you pre-establish a file filter so that the # dialog only shows the extension(s) you want it to. wildcard = "Text (*.txt)|*.txt|" \ "Config (*.cfg)|*.cfg|" \ "Python (*.py)|*.py|" \ "Python (*.pyw)|*.pyw|" \ "All (*.*)|*.*" #------------------------------------------------------------------------------- class MyFrame(wx.Frame): def __init__(self, filename="noname.txt"): super(MyFrame, self).__init__(None, size=(400, 300)) #------------ # Return icons folder. self.icons_dir = wx.GetApp().GetIconsDir() #------------ self.filename = filename self.dirname = "." self.flagDirty = False #------------ # Simplified init method. self.SetProperties() self.CreateMenuBar() self.CreateStyledTextControl() self.CreateStatusBar() self.BindEvents() #--------------------------------------------------------------------------- def SetProperties(self): """ ... """ self.SetTitle() #------------ frameIcon = wx.Icon(os.path.join(self.icons_dir, "icon_wxWidgets.ico"), type=wx.BITMAP_TYPE_ICO) self.SetIcon(frameIcon) def SetTitle(self): """ ... """ # MyFrame.SetTitle overrides wx.Frame.SetTitle, # so we have to call it using super : super(MyFrame, self).SetTitle("Editor %s" % self.filename) def CreateMenuBar(self): """ Create menu and menu bar. """ menuBar = wx.MenuBar() #------------ menu_File = wx.Menu() menu_Edit = wx.Menu() menu_About = wx.Menu() #------------ #------------ self.menu_File_Open = menu_File.Append(wx.ID_OPEN, "&Open" + "\t" + "Ctrl+O", "Open a new file.") #------------ menu_File.AppendSeparator() #------------ self.menu_File_Save = menu_File.Append(wx.ID_SAVE, "&Save" + "\t" + "Ctrl+S", "Save the current file.") self.menu_File_SaveAs = menu_File.Append(wx.ID_SAVEAS, "&Save as" + "\t" + "Ctrl+Shift+S", "Save the file under a different name.") #------------ menu_File.AppendSeparator() #------------ self.menu_File_Close = menu_File.Append(wx.ID_EXIT, "&Exit" + "\t" + "Ctrl+X", "Exit the program.") #------------ self.menu_Edit_Cut = menu_Edit.Append(wx.ID_CUT, "&Cut" + "\t" + "Ctrl+X", "Cut") self.menu_Edit_Copy = menu_Edit.Append(wx.ID_COPY, "&Copy" + "\t" + "Ctrl+C", "Copy") self.menu_Edit_Paste = menu_Edit.Append(wx.ID_PASTE, "&Paste" + "\t" + "Ctrl+V", "Paste") #------------ menu_Edit.AppendSeparator() #------------ self.menu_Edit_Undo = menu_Edit.Append(wx.ID_UNDO, "&Undo" + "\t" + "Ctrl+Z", "Undo") self.menu_Edit_Redo = menu_Edit.Append(wx.ID_REDO, "&Redo" + "\t" + "Ctrl+Shift+Z", "Redo") #------------ self.menu_About_Info = menu_About.Append(wx.ID_ABOUT, "&About" + "\t" + "Ctrl+I", "Information about this program.") #------------ #------------ menuBar.Append(menu_File, "File") menuBar.Append(menu_Edit, "Edit") menuBar.Append(menu_About, "About") #------------ self.SetMenuBar(menuBar) def CreateStyledTextControl(self): """ ... """ self.St_TextCtrl = stc.StyledTextCtrl(self) self.St_TextCtrl.SetWindowStyle(self.St_TextCtrl.GetWindowStyle() | wx.DOUBLE_BORDER) self.St_TextCtrl.StyleSetSpec(stc.STC_STYLE_DEFAULT, "size:10,face:Courier New") self.St_TextCtrl.SetWrapMode(stc.STC_WRAP_WORD) #------------ layout = wx.BoxSizer(wx.HORIZONTAL) layout.Add(self.St_TextCtrl, proportion=1, border=0, flag=wx.ALL|wx.EXPAND) self.SetSizer(layout) #------------ self.St_TextCtrl.Bind(stc.EVT_STC_CHANGE, self.OnChangeTxtCtrl) def BindEvents(self): """ ... """ self.Bind(wx.EVT_MENU, self.OnOpen, self.menu_File_Open) self.Bind(wx.EVT_MENU, self.OnSave, self.menu_File_Save) self.Bind(wx.EVT_MENU, self.OnSaveAs, self.menu_File_SaveAs) self.Bind(wx.EVT_MENU, self.OnCloseMe, self.menu_File_Close) self.Bind(wx.EVT_MENU, self.OnCut, self.menu_Edit_Cut) self.Bind(wx.EVT_MENU, self.OnCopy, self.menu_Edit_Copy) self.Bind(wx.EVT_MENU, self.OnPaste, self.menu_Edit_Paste) self.Bind(wx.EVT_MENU, self.OnUndo, self.menu_Edit_Undo) self.Bind(wx.EVT_MENU, self.OnRedo, self.menu_Edit_Redo) self.Bind(wx.EVT_MENU, self.OnAbout, self.menu_About_Info) self.Bind(wx.EVT_CLOSE, self.OnCloseWindow) def OnChangeTxtCtrl(self, event): """ ... """ lines = self.St_TextCtrl.GetLineCount() width = self.St_TextCtrl.TextWidth(stc.STC_STYLE_LINENUMBER, str(lines) + " ") self.St_TextCtrl.SetMarginWidth(0, width) self.flagDirty = True def DefaultFileDialogOptions(self): """ Return a dictionary with file dialog options that can be used in both the save file dialog as well as in the open file dialog. """ return dict(message="Choose a file :", defaultDir=self.dirname, wildcard=wildcard) def AskUserForFilename(self, **dialogOptions): """ ... """ dialog = wx.FileDialog(self, **dialogOptions) if dialog.ShowModal() == wx.ID_OK: userProvidedFilename = True self.filename = dialog.GetFilename() self.dirname = dialog.GetDirectory() # Update the window title with the new filename. self.SetTitle() else: userProvidedFilename = False dialog.Destroy() return userProvidedFilename def OnOpen(self, event): """ Open file. """ if self.AskUserForFilename(style=wx.FD_OPEN, **self.DefaultFileDialogOptions()): file = open(os.path.join(self.dirname, self.filename), 'r', encoding='utf-8') self.St_TextCtrl.SetValue(file.read()) file.close() def OnSave(self, event): """ Save file. """ with open(os.path.join(self.dirname, self.filename), 'w', encoding='utf-8') as file: file.write(self.St_TextCtrl.GetValue()) def OnSaveAs(self, event): """ Save file as. """ if self.AskUserForFilename(defaultFile=self.filename, style=wx.FD_SAVE, **self.DefaultFileDialogOptions()): self.OnSave(event) def OnCut(self, event): """ ... """ self.St_TextCtrl.Cut() def OnCopy(self, event): """ ... """ self.St_TextCtrl.Copy() def OnPaste(self, event): """ ... """ self.St_TextCtrl.Paste() def OnUndo(self, event): """ ... """ self.St_TextCtrl.Undo() def OnRedo(self, event): """ ... """ self.St_TextCtrl.Redo() def OnAbout(self, event): """ About dialog. """ dialog = wx.MessageDialog(self, "A sample StyledTextCtrl editor in wxPython.", "About sample editor", wx.OK) dialog.ShowModal() dialog.Destroy() def OnCloseMe(self, event): """ Close the main window. """ self.Close(True) def OnCloseWindow(self, event): """ Quit and destroy application. """ self.Destroy() #------------------------------------------------------------------------------- class MyApp(wx.App): """ .... """ def OnInit(self): #------------ self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0] #------------ frame = MyFrame() self.SetTopWindow(frame) frame.Show(True) return True #--------------------------------------------------------------------------- def GetInstallDir(self): """ Returns the installation directory for my application. """ return self.installDir def GetIconsDir(self): """ Returns the icons directory for my application. """ icons_dir = os.path.join(self.installDir, "icons") return icons_dir #------------------------------------------------------------------------------- def main(): app = MyApp(False) app.MainLoop() #------------------------------------------------------------------------------- if __name__ == "__main__" : main() }}} -------- == Sample three == {{attachment:img_sample_three.png}} Here we have a simple text editor. Notice the use of exceptions. It is a programmer's task to find and handle bugs. This includes doing such nasty things like opening pictures in an editor, simulating all possible situations. If a script raises an unhandled exception, we simply write a code that handles this (info by '''ZetCode / Jan Bodnar'''). {{{#!python # sample_three.py """ Author : Zetcode Created : Apr., 2007 Updated : Nov. 16, 2020 by Ecco """ import wx import os # Editor #--------------------------------------------------------------------------- TBFLAGS = ( wx.TB_HORIZONTAL | wx.NO_BORDER | wx.TB_FLAT #| wx.TB_TEXT #| wx.TB_HORZ_LAYOUT ) # This is how you pre-establish a file filter so that the dialog # only shows the extension(s) you want it to. wildcard = "Python source (*.py)|*.py|" \ "Compiled Python (*.pyc)|*.pyc|" \ "SPAM files (*.spam)|*.spam|" \ "Egg file (*.egg)|*.egg|" \ "All files (*.*)|*.*" #--------------------------------------------------------------------------- class Editor(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title, size=(400, 300)) #------------ icon = wx.Icon("./icons/icon_wxWidgets.ico") self.SetIcon(icon) #------------ # Variables. self.modify = False self.last_name_saved = '' self.replace = False #------------ # Setting up menubar. menubar = wx.MenuBar() file = wx.Menu() new = wx.MenuItem(file, 101, '&New\tCtrl+N', 'Creates a new document.') new.SetBitmap(wx.Bitmap('./images/stock_new-16.png')) file.Append(new) open = wx.MenuItem(file, 102, '&Open\tCtrl+O', 'Open an existing file.') open.SetBitmap(wx.Bitmap('./images/stock_open-16.png')) file.Append(open) file.AppendSeparator() save = wx.MenuItem(file, 103, '&Save\tCtrl+S', 'Save the file.') save.SetBitmap(wx.Bitmap('./images/stock_save-16.png')) file.Append(save) saveas = wx.MenuItem(file, 104, 'Save &as...\tShift+Ctrl+S', 'Save the file with a different name.') saveas.SetBitmap(wx.Bitmap('./images/stock_save_as-16.png')) file.Append(saveas) file.AppendSeparator() quit = wx.MenuItem(file, 105, '&Quit\tCtrl+Q', 'Quit the application.') quit.SetBitmap(wx.Bitmap('./images/stock_exit-16.png')) file.Append(quit) edit = wx.Menu() cut = wx.MenuItem(edit, 106, 'C&ut\tCtrl+X', 'Cut the selection.') cut.SetBitmap(wx.Bitmap('./images/stock_cut-16.png')) edit.Append(cut) copy = wx.MenuItem(edit, 107, '&Copy\tCtrl+C', 'Copy the selection.') copy.SetBitmap(wx.Bitmap('./images/stock_copy-16.png')) edit.Append(copy) paste = wx.MenuItem(edit, 108, '&Paste\tCtrl+V', 'Paste text from clipboard.') paste.SetBitmap(wx.Bitmap('./images/stock_paste-16.png')) edit.Append(paste) delete = wx.MenuItem(edit, 109, '&Delete', 'Delete the selected text.') delete.SetBitmap(wx.Bitmap('./images/stock_delete-16.png')) edit.Append(delete) edit.AppendSeparator() edit.Append(110, 'Select &All\tCtrl+A', 'Select the entire text.') view = wx.Menu() view.Append(111, '&Statusbar', 'Show StatusBar.') help = wx.Menu() about = wx.MenuItem(help, 112, '&About\tF1', 'About Editor.') about.SetBitmap(wx.Bitmap('./images/stock_about-16.png')) help.Append(about) menubar.Append(file, '&File') menubar.Append(edit, '&Edit') menubar.Append(view, '&View') menubar.Append(help, '&Help') self.SetMenuBar(menubar) #------------ # setting up toolbar self.toolbar = self.CreateToolBar(TBFLAGS) self.toolbar.AddTool(801, "New", wx.Image('./images/stock_new.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, 'New', "Long help for 'New'", None) self.toolbar.AddTool(802, "Open", wx.Image('./images/stock_open.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, 'Open', "Long help for 'Open'", None) self.toolbar.AddTool(803, "Save", wx.Image('./images/stock_save.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, 'Save', "Long help for 'Save'", None) self.toolbar.AddSeparator() self.toolbar.AddTool(804, "Cut", wx.Image('./images/stock_cut.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, 'Cut', "Long help for 'Cut'", None) self.toolbar.AddTool(805, "Copy", wx.Image('./images/stock_copy.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, 'Copy', "Long help for 'Copy'", None) self.toolbar.AddTool(806, "Paste", wx.Image('./images/stock_paste.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, 'Paste', "Long help for 'Paste'", None) self.toolbar.AddSeparator() self.toolbar.AddTool(807, "Exit", wx.Image('./images/stock_exit.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(), wx.NullBitmap, wx.ITEM_NORMAL, 'Exit', "Long help for 'Exit'", None) self.toolbar.Realize() #------------ self.text = wx.TextCtrl(self, 1000, '', size=(-1, -1), style=wx.TE_MULTILINE | wx.TE_PROCESS_ENTER) self.text.SetFocus() #------------ self.text.Bind(wx.EVT_TEXT, self.OnTextChanged, id=1000) self.text.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown) self.Bind(wx.EVT_MENU, self.NewApplication, id=101) self.Bind(wx.EVT_MENU, self.OnOpenFile, id=102) self.Bind(wx.EVT_MENU, self.OnSaveFile, id=103) self.Bind(wx.EVT_MENU, self.OnSaveAsFile, id=104) self.Bind(wx.EVT_MENU, self.QuitApplication, id=105) self.Bind(wx.EVT_MENU, self.OnCut, id=106) self.Bind(wx.EVT_MENU, self.OnCopy, id=107) self.Bind(wx.EVT_MENU, self.OnPaste, id=108) self.Bind(wx.EVT_MENU, self.OnDelete, id=109) self.Bind(wx.EVT_MENU, self.OnSelectAll, id=110) self.Bind(wx.EVT_MENU, self.ToggleStatusBar, id=111) self.Bind(wx.EVT_MENU, self.OnAbout, id=112) self.Bind(wx.EVT_TOOL, self.NewApplication, id=801) self.Bind(wx.EVT_TOOL, self.OnOpenFile, id=802) self.Bind(wx.EVT_TOOL, self.OnSaveFile, id=803) self.Bind(wx.EVT_TOOL, self.OnCut, id=804) self.Bind(wx.EVT_TOOL, self.OnCopy, id=805) self.Bind(wx.EVT_TOOL, self.OnPaste, id=806) self.Bind(wx.EVT_TOOL, self.QuitApplication, id=807) self.Bind(wx.EVT_CLOSE, self.QuitApplication) #------------ vbox = wx.BoxSizer(wx.VERTICAL) vbox.Add(self.text, 1, wx.EXPAND, border=0) self.SetSizer(vbox) #------------ self.StatusBar() #------------ self.Centre() #------------ self.Show(True) #----------------------------------------------------------------------- def NewApplication(self, event): editor = Editor(None, -1, 'Editor') editor.Centre() editor.Show() def OnOpenFile(self, event): file_name = os.path.basename(self.last_name_saved) if self.modify: dlg = wx.MessageDialog(self, 'Save changes ?', '', wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_QUESTION) val = dlg.ShowModal() if val == wx.ID_YES: self.OnSaveFile(event) self.DoOpenFile() elif val == wx.ID_CANCEL: dlg.Destroy() else: self.DoOpenFile() else: self.DoOpenFile() def DoOpenFile(self): open_dlg = wx.FileDialog(self, message="Choose a file", defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.FD_OPEN | wx.FD_CHANGE_DIR | wx.FD_FILE_MUST_EXIST | wx.FD_PREVIEW) if open_dlg.ShowModal() == wx.ID_OK: path = open_dlg.GetPath() try: file = open(path, 'r') text = file.read() file.close() if self.text.GetLastPosition(): self.text.Clear() self.text.WriteText(text) self.last_name_saved = path self.statusbar.SetStatusText('', 1) self.modify = False except IOError as error: dlg = wx.MessageDialog(self, 'Error opening file\n' + str(error)) dlg.ShowModal() except UnicodeDecodeError as error: dlg = wx.MessageDialog(self, 'Error opening file\n' + str(error)) dlg.ShowModal() open_dlg.Destroy() def OnSaveFile(self, event): if self.last_name_saved: try: file = open(self.last_name_saved, 'w') text = self.text.GetValue() file.write(text) file.close() self.statusbar.SetStatusText(os.path.basename(self.last_name_saved) + ' Saved', 0) self.modify = False self.statusbar.SetStatusText('', 1) except IOError as error: dlg = wx.MessageDialog(self, 'Error saving file\n' + str(error)) dlg.ShowModal() else: self.OnSaveAsFile(event) def OnSaveAsFile(self, event): save_dlg = wx.FileDialog(self, message="Save file as ...", defaultDir=os.getcwd(), defaultFile="", wildcard=wildcard, style=wx.FD_SAVE | wx.FD_OVERWRITE_PROMPT) save_dlg.SetFilterIndex(0) if save_dlg.ShowModal() == wx.ID_OK: path = save_dlg.GetPath() try: file = open(path, 'w') text = self.text.GetValue() file.write(text) file.close() self.last_name_saved = os.path.basename(path) self.statusbar.SetStatusText(self.last_name_saved + ' Saved', 0) self.modify = False self.statusbar.SetStatusText('', 1) except IOError as error: dlg = wx.MessageDialog(self, 'Error saving file\n' + str(error)) dlg.ShowModal() save_dlg.Destroy() def OnCut(self, event): self.text.Cut() def OnCopy(self, event): self.text.Copy() def OnPaste(self, event): self.text.Paste() def QuitApplication(self, event): if self.modify: dlg = wx.MessageDialog(self, 'Save before Exit ?', '', wx.YES_NO | wx.YES_DEFAULT | wx.CANCEL | wx.ICON_QUESTION) val = dlg.ShowModal() if val == wx.ID_YES: self.OnSaveFile(event) if not self.modify: wx.Exit() elif val == wx.ID_CANCEL: dlg.Destroy() else: self.Destroy() else: self.Destroy() def OnDelete(self, event): frm, to = self.text.GetSelection() self.text.Remove(frm, to) def OnSelectAll(self, event): self.text.SelectAll() def OnTextChanged(self, event): self.modify = True self.statusbar.SetStatusText(' Modified', 1) event.Skip() def OnKeyDown(self, event): keycode = event.GetKeyCode() if keycode == wx.WXK_INSERT: if not self.replace: self.statusbar.SetStatusText('INS', 2) self.replace = True else: self.statusbar.SetStatusText('', 2) self.replace = False event.Skip() def ToggleStatusBar(self, event): if self.statusbar.IsShown(): self.statusbar.Hide() else: self.statusbar.Show() self.SendSizeEvent() def StatusBar(self): self.statusbar = self.CreateStatusBar() self.statusbar.SetFieldsCount(3) self.statusbar.SetStatusWidths([-5, -2, -1]) def OnAbout(self, event): dlg = wx.MessageDialog(self, '\tEditor\t\n'\ '\n'\ 'Another Tutorial\n'\ 'Jan Bodnar 2005-2006\n'\ 'Updated by Ecco 2020.', 'About Editor', wx.OK | wx.ICON_INFORMATION) dlg.ShowModal() dlg.Destroy() #--------------------------------------------------------------------------- app = wx.App() Editor(None, -1, 'Editor') app.MainLoop() }}} -------- = Download source = [[attachment:source.zip]] -------- = Additional Information = '''Link :''' https://teratail.com/questions/124859?link=qa_related_pc - - - - - https://wiki.wxpython.org/TitleIndex https://docs.wxpython.org/ -------- = Thanks to = ??? (sample_one.py coding), ??? (sample_two.py coding), Jan Bodnar (sample_three.py coding), the wxPython community... -------- = About this page = Date(d/m/y) Person (bot) Comments : 19/07/20 - Ecco (Created page and updated examples for wxPython Phoenix). -------- = Comments = - blah, blah, blah....