How to create a simple text editor (Phoenix)
Keywords : Editor, Text, TextCtrl, Stc, StyledTextCtrl.
Contents
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
1 # sample_one.py
2
3 import sys
4 import os.path
5 import wx
6
7 # class MyFrame
8 # class MyApp
9
10 #-------------------------------------------------------------------------------
11
12 # This is how you pre-establish a file filter so that the
13 # dialog only shows the extension(s) you want it to.
14
15 wildcard = "Text (*.txt)|*.txt|" \
16 "Executable (*.exe)|*.exe|" \
17 "Library (*.dll)|*.dll|" \
18 "Driver (*.sys)|*.sys|" \
19 "ActiveX (*.ocx)|*.ocx|" \
20 "Python (*.py)|*.py|" \
21 "Python (*.pyw)|*.pyw|" \
22 "All (*.*)|*.*"
23
24 #-------------------------------------------------------------------------------
25
26 class MyFrame(wx.Frame):
27 def __init__(self, filename="noname.txt"):
28 super(MyFrame, self).__init__(None, size=(400, 300))
29
30 #------------
31
32 # Return icons folder.
33 self.icons_dir = wx.GetApp().GetIconsDir()
34
35 #------------
36
37 self.filename = filename
38 self.dirname = "."
39
40 #------------
41
42 # Simplified init method.
43 self.CreateInteriorWindowComponents()
44 self.CreateExteriorWindowComponents()
45
46 #------------
47
48 self.CenterOnScreen()
49
50 #---------------------------------------------------------------------------
51
52 def SetTitle(self):
53 """
54 ...
55 """
56
57 # MyFrame.SetTitle overrides wx.Frame.SetTitle,
58 # so we have to call it using super :
59 super(MyFrame, self).SetTitle("Editor %s" % self.filename)
60
61
62 def CreateInteriorWindowComponents(self):
63 """
64 Create "interior" window components. In this case
65 it is just a simple multiline text control.
66 """
67
68 self.control = wx.TextCtrl(self, -1, value="", style=wx.TE_MULTILINE)
69
70
71 def CreateExteriorWindowComponents(self):
72 """
73 Create "exterior" window components, such as menu and status bar.
74 """
75
76 # Simplified init method.
77 self.SetTitle()
78
79 #------------
80
81 frameIcon = wx.Icon(os.path.join(self.icons_dir,
82 "icon_wxWidgets.ico"),
83 type=wx.BITMAP_TYPE_ICO)
84 self.SetIcon(frameIcon)
85
86 #------------
87
88 self.CreateMenu()
89 self.CreateStatusBar()
90 self.BindEvents()
91
92
93 def CreateMenu(self):
94 """
95 Create menu and menu bar.
96 """
97
98 menuBar = wx.MenuBar()
99
100 #------------
101
102 fileMenu = wx.Menu()
103
104 for id, label, helpText, handler in \
105 [(wx.ID_ABOUT, "&About",
106 "Information about this program.", self.OnAbout),
107 (None, None, None, None),
108 (wx.ID_OPEN, "&Open",
109 "Open a new file.", self.OnOpen),
110 (wx.ID_SAVE, "&Save",
111 "Save the current file.", self.OnSave),
112 (wx.ID_SAVEAS, "Save &as",
113 "Save the file under a different name.", self.OnSaveAs),
114 (None, None, None, None),
115 (wx.ID_EXIT, "E&xit",
116 "Terminate the program.", self.OnCloseMe)]:
117
118 if id == None:
119 fileMenu.AppendSeparator()
120 else:
121 item = fileMenu.Append(id, label, helpText)
122
123 #------------
124
125 # Bind some events to an events handler.
126 self.Bind(wx.EVT_MENU, handler, item)
127
128 #------------
129
130 # Add the fileMenu to the menuBar.
131 menuBar.Append(fileMenu, "&File")
132
133 #------------
134
135 # Add the menuBar to the frame.
136 self.SetMenuBar(menuBar)
137
138
139 def BindEvents(self):
140 """
141 ...
142 """
143
144 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
145
146
147 def DefaultFileDialogOptions(self):
148 """
149 Return a dictionary with file dialog options that can be
150 used in both the save file dialog as well as in the open
151 file dialog.
152 """
153
154 return dict(message="Choose a file :",
155 defaultDir=self.dirname,
156 wildcard=wildcard)
157
158
159 def AskUserForFilename(self, **dialogOptions):
160 """
161 ...
162 """
163
164 dialog = wx.FileDialog(self, **dialogOptions)
165
166 if dialog.ShowModal() == wx.ID_OK:
167 userProvidedFilename = True
168 self.filename = dialog.GetFilename()
169 self.dirname = dialog.GetDirectory()
170 # Update the window title with the new filename.
171 self.SetTitle()
172 else:
173 userProvidedFilename = False
174
175 dialog.Destroy()
176
177 return userProvidedFilename
178
179
180 def OnOpen(self, event):
181 """
182 Open file.
183 """
184
185 if self.AskUserForFilename(style=wx.FD_OPEN,
186 **self.DefaultFileDialogOptions()):
187 file = open(os.path.join(self.dirname, self.filename), 'r', encoding='utf-8')
188 self.control.SetValue(file.read())
189 file.close()
190
191
192 def OnSave(self, event):
193 """
194 Save file.
195 """
196
197 with open(os.path.join(self.dirname, self.filename), 'w', encoding='utf-8') as file:
198 file.write(self.control.GetValue())
199
200
201 def OnSaveAs(self, event):
202 """
203 Save file as.
204 """
205
206 if self.AskUserForFilename(defaultFile=self.filename, style=wx.FD_SAVE,
207 **self.DefaultFileDialogOptions()):
208 self.OnSave(event)
209
210
211 def OnAbout(self, event):
212 """
213 About dialog.
214 """
215
216 dialog = wx.MessageDialog(self,
217 "A sample editor in wxPython.",
218 "About sample editor",
219 wx.OK)
220 dialog.ShowModal()
221 dialog.Destroy()
222
223
224 def OnCloseMe(self, event):
225 """
226 Close the main window.
227 """
228
229 self.Close(True)
230
231
232 def OnCloseWindow(self, event):
233 """
234 Quit and destroy application.
235 """
236
237 self.Destroy()
238
239 #-------------------------------------------------------------------------------
240
241 class MyApp(wx.App):
242 """
243 ....
244 """
245 def OnInit(self):
246
247 #------------
248
249 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
250
251 #------------
252
253 frame = MyFrame()
254 self.SetTopWindow(frame)
255 frame.Show(True)
256
257 return True
258
259 #---------------------------------------------------------------------------
260
261 def GetInstallDir(self):
262 """
263 Returns the installation directory for my application.
264 """
265
266 return self.installDir
267
268
269 def GetIconsDir(self):
270 """
271 Returns the icons directory for my application.
272 """
273
274 icons_dir = os.path.join(self.installDir, "icons")
275 return icons_dir
276
277 #-------------------------------------------------------------------------------
278
279 def main():
280 app = MyApp(False)
281 app.MainLoop()
282
283 #-------------------------------------------------------------------------------
284
285 if __name__ == "__main__" :
286 main()
Sample two
1 # sample_two.py
2
3 import sys
4 import os.path
5 import wx
6 import wx.stc as stc # StyledTextCtrl
7
8 # class MyFrame
9 # class MyApp
10
11 #-------------------------------------------------------------------------------
12
13 # This is how you pre-establish a file filter so that the
14 # dialog only shows the extension(s) you want it to.
15
16 wildcard = "Text (*.txt)|*.txt|" \
17 "Config (*.cfg)|*.cfg|" \
18 "Python (*.py)|*.py|" \
19 "Python (*.pyw)|*.pyw|" \
20 "All (*.*)|*.*"
21
22 #-------------------------------------------------------------------------------
23
24 class MyFrame(wx.Frame):
25 def __init__(self, filename="noname.txt"):
26 super(MyFrame, self).__init__(None, size=(400, 300))
27
28 #------------
29
30 # Return icons folder.
31 self.icons_dir = wx.GetApp().GetIconsDir()
32
33 #------------
34
35 self.filename = filename
36 self.dirname = "."
37 self.flagDirty = False
38
39 #------------
40
41 # Simplified init method.
42 self.SetProperties()
43 self.CreateMenuBar()
44 self.CreateStyledTextControl()
45 self.CreateStatusBar()
46 self.BindEvents()
47
48 #---------------------------------------------------------------------------
49
50 def SetProperties(self):
51 """
52 ...
53 """
54
55 self.SetTitle()
56
57 #------------
58
59 frameIcon = wx.Icon(os.path.join(self.icons_dir,
60 "icon_wxWidgets.ico"),
61 type=wx.BITMAP_TYPE_ICO)
62 self.SetIcon(frameIcon)
63
64
65 def SetTitle(self):
66 """
67 ...
68 """
69
70 # MyFrame.SetTitle overrides wx.Frame.SetTitle,
71 # so we have to call it using super :
72 super(MyFrame, self).SetTitle("Editor %s" % self.filename)
73
74
75 def CreateMenuBar(self):
76 """
77 Create menu and menu bar.
78 """
79
80 menuBar = wx.MenuBar()
81
82 #------------
83
84 menu_File = wx.Menu()
85 menu_Edit = wx.Menu()
86 menu_About = wx.Menu()
87
88 #------------
89 #------------
90
91 self.menu_File_Open = menu_File.Append(wx.ID_OPEN,
92 "&Open" + "\t" + "Ctrl+O",
93 "Open a new file.")
94 #------------
95
96 menu_File.AppendSeparator()
97
98 #------------
99
100 self.menu_File_Save = menu_File.Append(wx.ID_SAVE,
101 "&Save" + "\t" + "Ctrl+S",
102 "Save the current file.")
103 self.menu_File_SaveAs = menu_File.Append(wx.ID_SAVEAS,
104 "&Save as" + "\t" + "Ctrl+Shift+S",
105 "Save the file under a different name.")
106
107 #------------
108
109 menu_File.AppendSeparator()
110
111 #------------
112
113 self.menu_File_Close = menu_File.Append(wx.ID_EXIT,
114 "&Exit" + "\t" + "Ctrl+X",
115 "Exit the program.")
116 #------------
117
118 self.menu_Edit_Cut = menu_Edit.Append(wx.ID_CUT,
119 "&Cut" + "\t" + "Ctrl+X",
120 "Cut")
121 self.menu_Edit_Copy = menu_Edit.Append(wx.ID_COPY,
122 "&Copy" + "\t" + "Ctrl+C",
123 "Copy")
124 self.menu_Edit_Paste = menu_Edit.Append(wx.ID_PASTE,
125 "&Paste" + "\t" + "Ctrl+V",
126 "Paste")
127 #------------
128
129 menu_Edit.AppendSeparator()
130
131 #------------
132
133 self.menu_Edit_Undo = menu_Edit.Append(wx.ID_UNDO,
134 "&Undo" + "\t" + "Ctrl+Z",
135 "Undo")
136 self.menu_Edit_Redo = menu_Edit.Append(wx.ID_REDO,
137 "&Redo" + "\t" + "Ctrl+Shift+Z",
138 "Redo")
139
140 #------------
141
142 self.menu_About_Info = menu_About.Append(wx.ID_ABOUT,
143 "&About" + "\t" + "Ctrl+I",
144 "Information about this program.")
145
146 #------------
147 #------------
148
149 menuBar.Append(menu_File, "File")
150 menuBar.Append(menu_Edit, "Edit")
151 menuBar.Append(menu_About, "About")
152
153 #------------
154
155 self.SetMenuBar(menuBar)
156
157
158 def CreateStyledTextControl(self):
159 """
160 ...
161 """
162
163 self.St_TextCtrl = stc.StyledTextCtrl(self)
164 self.St_TextCtrl.SetWindowStyle(self.St_TextCtrl.GetWindowStyle() | wx.DOUBLE_BORDER)
165 self.St_TextCtrl.StyleSetSpec(stc.STC_STYLE_DEFAULT, "size:10,face:Courier New")
166 self.St_TextCtrl.SetWrapMode(stc.STC_WRAP_WORD)
167
168 #------------
169
170 layout = wx.BoxSizer(wx.HORIZONTAL)
171 layout.Add(self.St_TextCtrl, proportion=1, border=0, flag=wx.ALL|wx.EXPAND)
172 self.SetSizer(layout)
173
174 #------------
175
176 self.St_TextCtrl.Bind(stc.EVT_STC_CHANGE, self.OnChangeTxtCtrl)
177
178
179 def BindEvents(self):
180 """
181 ...
182 """
183
184 self.Bind(wx.EVT_MENU, self.OnOpen, self.menu_File_Open)
185 self.Bind(wx.EVT_MENU, self.OnSave, self.menu_File_Save)
186 self.Bind(wx.EVT_MENU, self.OnSaveAs, self.menu_File_SaveAs)
187 self.Bind(wx.EVT_MENU, self.OnCloseMe, self.menu_File_Close)
188 self.Bind(wx.EVT_MENU, self.OnCut, self.menu_Edit_Cut)
189 self.Bind(wx.EVT_MENU, self.OnCopy, self.menu_Edit_Copy)
190 self.Bind(wx.EVT_MENU, self.OnPaste, self.menu_Edit_Paste)
191 self.Bind(wx.EVT_MENU, self.OnUndo, self.menu_Edit_Undo)
192 self.Bind(wx.EVT_MENU, self.OnRedo, self.menu_Edit_Redo)
193 self.Bind(wx.EVT_MENU, self.OnAbout, self.menu_About_Info)
194
195 self.Bind(wx.EVT_CLOSE, self.OnCloseWindow)
196
197
198 def OnChangeTxtCtrl(self, event):
199 """
200 ...
201 """
202
203 lines = self.St_TextCtrl.GetLineCount()
204 width = self.St_TextCtrl.TextWidth(stc.STC_STYLE_LINENUMBER, str(lines) + " ")
205 self.St_TextCtrl.SetMarginWidth(0, width)
206
207 self.flagDirty = True
208
209
210 def DefaultFileDialogOptions(self):
211 """
212 Return a dictionary with file dialog options that can be
213 used in both the save file dialog as well as in the open
214 file dialog.
215 """
216
217 return dict(message="Choose a file :",
218 defaultDir=self.dirname,
219 wildcard=wildcard)
220
221
222 def AskUserForFilename(self, **dialogOptions):
223 """
224 ...
225 """
226
227 dialog = wx.FileDialog(self, **dialogOptions)
228
229 if dialog.ShowModal() == wx.ID_OK:
230 userProvidedFilename = True
231 self.filename = dialog.GetFilename()
232 self.dirname = dialog.GetDirectory()
233 # Update the window title with the new filename.
234 self.SetTitle()
235 else:
236 userProvidedFilename = False
237
238 dialog.Destroy()
239
240 return userProvidedFilename
241
242
243 def OnOpen(self, event):
244 """
245 Open file.
246 """
247
248 if self.AskUserForFilename(style=wx.FD_OPEN,
249 **self.DefaultFileDialogOptions()):
250 file = open(os.path.join(self.dirname, self.filename), 'r', encoding='utf-8')
251 self.St_TextCtrl.SetValue(file.read())
252 file.close()
253
254
255 def OnSave(self, event):
256 """
257 Save file.
258 """
259
260 with open(os.path.join(self.dirname, self.filename), 'w', encoding='utf-8') as file:
261 file.write(self.St_TextCtrl.GetValue())
262
263
264 def OnSaveAs(self, event):
265 """
266 Save file as.
267 """
268
269 if self.AskUserForFilename(defaultFile=self.filename, style=wx.FD_SAVE,
270 **self.DefaultFileDialogOptions()):
271 self.OnSave(event)
272
273
274 def OnCut(self, event):
275 """
276 ...
277 """
278
279 self.St_TextCtrl.Cut()
280
281
282 def OnCopy(self, event):
283 """
284 ...
285 """
286
287 self.St_TextCtrl.Copy()
288
289
290 def OnPaste(self, event):
291 """
292 ...
293 """
294
295 self.St_TextCtrl.Paste()
296
297
298 def OnUndo(self, event):
299 """
300 ...
301 """
302
303 self.St_TextCtrl.Undo()
304
305
306 def OnRedo(self, event):
307 """
308 ...
309 """
310
311 self.St_TextCtrl.Redo()
312
313
314 def OnAbout(self, event):
315 """
316 About dialog.
317 """
318
319 dialog = wx.MessageDialog(self,
320 "A sample StyledTextCtrl editor in wxPython.",
321 "About sample editor",
322 wx.OK)
323 dialog.ShowModal()
324 dialog.Destroy()
325
326
327 def OnCloseMe(self, event):
328 """
329 Close the main window.
330 """
331
332 self.Close(True)
333
334
335 def OnCloseWindow(self, event):
336 """
337 Quit and destroy application.
338 """
339
340 self.Destroy()
341
342 #-------------------------------------------------------------------------------
343
344 class MyApp(wx.App):
345 """
346 ....
347 """
348 def OnInit(self):
349
350 #------------
351
352 self.installDir = os.path.split(os.path.abspath(sys.argv[0]))[0]
353
354 #------------
355
356 frame = MyFrame()
357 self.SetTopWindow(frame)
358 frame.Show(True)
359
360 return True
361
362 #---------------------------------------------------------------------------
363
364 def GetInstallDir(self):
365 """
366 Returns the installation directory for my application.
367 """
368
369 return self.installDir
370
371
372 def GetIconsDir(self):
373 """
374 Returns the icons directory for my application.
375 """
376
377 icons_dir = os.path.join(self.installDir, "icons")
378 return icons_dir
379
380 #-------------------------------------------------------------------------------
381
382 def main():
383 app = MyApp(False)
384 app.MainLoop()
385
386 #-------------------------------------------------------------------------------
387
388 if __name__ == "__main__" :
389 main()
Sample three
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).
1 # sample_three.py
2
3 """
4
5 Author : Zetcode
6 Created : Apr., 2007
7 Updated : Nov. 16, 2020 by Ecco
8
9 """
10
11 import wx
12 import os
13
14 # Editor
15
16 #---------------------------------------------------------------------------
17
18 TBFLAGS = ( wx.TB_HORIZONTAL
19 | wx.NO_BORDER
20 | wx.TB_FLAT
21 #| wx.TB_TEXT
22 #| wx.TB_HORZ_LAYOUT
23 )
24
25 # This is how you pre-establish a file filter so that the dialog
26 # only shows the extension(s) you want it to.
27 wildcard = "Python source (*.py)|*.py|" \
28 "Compiled Python (*.pyc)|*.pyc|" \
29 "SPAM files (*.spam)|*.spam|" \
30 "Egg file (*.egg)|*.egg|" \
31 "All files (*.*)|*.*"
32
33 #---------------------------------------------------------------------------
34
35 class Editor(wx.Frame):
36 def __init__(self, parent, id, title):
37 wx.Frame.__init__(self, parent, id, title, size=(400, 300))
38
39 #------------
40
41 icon = wx.Icon("./icons/icon_wxWidgets.ico")
42 self.SetIcon(icon)
43
44 #------------
45
46 # Variables.
47 self.modify = False
48 self.last_name_saved = ''
49 self.replace = False
50
51 #------------
52
53 # Setting up menubar.
54 menubar = wx.MenuBar()
55
56 file = wx.Menu()
57 new = wx.MenuItem(file, 101, '&New\tCtrl+N', 'Creates a new document.')
58 new.SetBitmap(wx.Bitmap('./images/stock_new-16.png'))
59 file.Append(new)
60
61 open = wx.MenuItem(file, 102, '&Open\tCtrl+O', 'Open an existing file.')
62 open.SetBitmap(wx.Bitmap('./images/stock_open-16.png'))
63 file.Append(open)
64 file.AppendSeparator()
65
66 save = wx.MenuItem(file, 103, '&Save\tCtrl+S', 'Save the file.')
67 save.SetBitmap(wx.Bitmap('./images/stock_save-16.png'))
68 file.Append(save)
69
70 saveas = wx.MenuItem(file, 104, 'Save &as...\tShift+Ctrl+S', 'Save the file with a different name.')
71 saveas.SetBitmap(wx.Bitmap('./images/stock_save_as-16.png'))
72 file.Append(saveas)
73 file.AppendSeparator()
74
75 quit = wx.MenuItem(file, 105, '&Quit\tCtrl+Q', 'Quit the application.')
76 quit.SetBitmap(wx.Bitmap('./images/stock_exit-16.png'))
77 file.Append(quit)
78
79 edit = wx.Menu()
80 cut = wx.MenuItem(edit, 106, 'C&ut\tCtrl+X', 'Cut the selection.')
81 cut.SetBitmap(wx.Bitmap('./images/stock_cut-16.png'))
82 edit.Append(cut)
83
84 copy = wx.MenuItem(edit, 107, '&Copy\tCtrl+C', 'Copy the selection.')
85 copy.SetBitmap(wx.Bitmap('./images/stock_copy-16.png'))
86 edit.Append(copy)
87
88 paste = wx.MenuItem(edit, 108, '&Paste\tCtrl+V', 'Paste text from clipboard.')
89 paste.SetBitmap(wx.Bitmap('./images/stock_paste-16.png'))
90 edit.Append(paste)
91
92 delete = wx.MenuItem(edit, 109, '&Delete', 'Delete the selected text.')
93 delete.SetBitmap(wx.Bitmap('./images/stock_delete-16.png'))
94
95 edit.Append(delete)
96 edit.AppendSeparator()
97 edit.Append(110, 'Select &All\tCtrl+A', 'Select the entire text.')
98
99 view = wx.Menu()
100 view.Append(111, '&Statusbar', 'Show StatusBar.')
101
102 help = wx.Menu()
103 about = wx.MenuItem(help, 112, '&About\tF1', 'About Editor.')
104 about.SetBitmap(wx.Bitmap('./images/stock_about-16.png'))
105 help.Append(about)
106
107 menubar.Append(file, '&File')
108 menubar.Append(edit, '&Edit')
109 menubar.Append(view, '&View')
110 menubar.Append(help, '&Help')
111
112 self.SetMenuBar(menubar)
113
114 #------------
115
116 # setting up toolbar
117 self.toolbar = self.CreateToolBar(TBFLAGS)
118 self.toolbar.AddTool(801, "New", wx.Image('./images/stock_new.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
119 wx.NullBitmap, wx.ITEM_NORMAL, 'New', "Long help for 'New'", None)
120 self.toolbar.AddTool(802, "Open", wx.Image('./images/stock_open.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
121 wx.NullBitmap, wx.ITEM_NORMAL, 'Open', "Long help for 'Open'", None)
122 self.toolbar.AddTool(803, "Save", wx.Image('./images/stock_save.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
123 wx.NullBitmap, wx.ITEM_NORMAL, 'Save', "Long help for 'Save'", None)
124 self.toolbar.AddSeparator()
125
126 self.toolbar.AddTool(804, "Cut", wx.Image('./images/stock_cut.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
127 wx.NullBitmap, wx.ITEM_NORMAL, 'Cut', "Long help for 'Cut'", None)
128 self.toolbar.AddTool(805, "Copy", wx.Image('./images/stock_copy.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
129 wx.NullBitmap, wx.ITEM_NORMAL, 'Copy', "Long help for 'Copy'", None)
130 self.toolbar.AddTool(806, "Paste", wx.Image('./images/stock_paste.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
131 wx.NullBitmap, wx.ITEM_NORMAL, 'Paste', "Long help for 'Paste'", None)
132 self.toolbar.AddSeparator()
133
134 self.toolbar.AddTool(807, "Exit", wx.Image('./images/stock_exit.png', wx.BITMAP_TYPE_PNG).ConvertToBitmap(),
135 wx.NullBitmap, wx.ITEM_NORMAL, 'Exit', "Long help for 'Exit'", None)
136
137 self.toolbar.Realize()
138
139 #------------
140
141 self.text = wx.TextCtrl(self, 1000, '', size=(-1, -1), style=wx.TE_MULTILINE | wx.TE_PROCESS_ENTER)
142 self.text.SetFocus()
143
144 #------------
145
146 self.text.Bind(wx.EVT_TEXT, self.OnTextChanged, id=1000)
147 self.text.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
148
149 self.Bind(wx.EVT_MENU, self.NewApplication, id=101)
150 self.Bind(wx.EVT_MENU, self.OnOpenFile, id=102)
151 self.Bind(wx.EVT_MENU, self.OnSaveFile, id=103)
152 self.Bind(wx.EVT_MENU, self.OnSaveAsFile, id=104)
153 self.Bind(wx.EVT_MENU, self.QuitApplication, id=105)
154 self.Bind(wx.EVT_MENU, self.OnCut, id=106)
155 self.Bind(wx.EVT_MENU, self.OnCopy, id=107)
156 self.Bind(wx.EVT_MENU, self.OnPaste, id=108)
157 self.Bind(wx.EVT_MENU, self.OnDelete, id=109)
158 self.Bind(wx.EVT_MENU, self.OnSelectAll, id=110)
159 self.Bind(wx.EVT_MENU, self.ToggleStatusBar, id=111)
160 self.Bind(wx.EVT_MENU, self.OnAbout, id=112)
161
162 self.Bind(wx.EVT_TOOL, self.NewApplication, id=801)
163 self.Bind(wx.EVT_TOOL, self.OnOpenFile, id=802)
164 self.Bind(wx.EVT_TOOL, self.OnSaveFile, id=803)
165 self.Bind(wx.EVT_TOOL, self.OnCut, id=804)
166 self.Bind(wx.EVT_TOOL, self.OnCopy, id=805)
167 self.Bind(wx.EVT_TOOL, self.OnPaste, id=806)
168 self.Bind(wx.EVT_TOOL, self.QuitApplication, id=807)
169
170 self.Bind(wx.EVT_CLOSE, self.QuitApplication)
171
172 #------------
173
174 vbox = wx.BoxSizer(wx.VERTICAL)
175 vbox.Add(self.text, 1, wx.EXPAND, border=0)
176
177 self.SetSizer(vbox)
178
179 #------------
180
181 self.StatusBar()
182
183 #------------
184
185 self.Centre()
186
187 #------------
188
189 self.Show(True)
190
191 #-----------------------------------------------------------------------
192
193 def NewApplication(self, event):
194 editor = Editor(None, -1, 'Editor')
195 editor.Centre()
196 editor.Show()
197
198
199 def OnOpenFile(self, event):
200 file_name = os.path.basename(self.last_name_saved)
201
202 if self.modify:
203 dlg = wx.MessageDialog(self,
204 'Save changes ?',
205 '',
206 wx.YES_NO |
207 wx.YES_DEFAULT |
208 wx.CANCEL |
209 wx.ICON_QUESTION)
210
211 val = dlg.ShowModal()
212 if val == wx.ID_YES:
213 self.OnSaveFile(event)
214 self.DoOpenFile()
215 elif val == wx.ID_CANCEL:
216 dlg.Destroy()
217 else:
218 self.DoOpenFile()
219 else:
220 self.DoOpenFile()
221
222
223 def DoOpenFile(self):
224 open_dlg = wx.FileDialog(self,
225 message="Choose a file",
226 defaultDir=os.getcwd(),
227 defaultFile="",
228 wildcard=wildcard,
229 style=wx.FD_OPEN |
230 wx.FD_CHANGE_DIR |
231 wx.FD_FILE_MUST_EXIST |
232 wx.FD_PREVIEW)
233
234 if open_dlg.ShowModal() == wx.ID_OK:
235 path = open_dlg.GetPath()
236
237 try:
238 file = open(path, 'r')
239 text = file.read()
240 file.close()
241 if self.text.GetLastPosition():
242 self.text.Clear()
243 self.text.WriteText(text)
244 self.last_name_saved = path
245 self.statusbar.SetStatusText('', 1)
246 self.modify = False
247
248 except IOError as error:
249 dlg = wx.MessageDialog(self, 'Error opening file\n' + str(error))
250 dlg.ShowModal()
251
252 except UnicodeDecodeError as error:
253 dlg = wx.MessageDialog(self, 'Error opening file\n' + str(error))
254 dlg.ShowModal()
255
256 open_dlg.Destroy()
257
258
259 def OnSaveFile(self, event):
260 if self.last_name_saved:
261
262 try:
263 file = open(self.last_name_saved, 'w')
264 text = self.text.GetValue()
265 file.write(text)
266 file.close()
267 self.statusbar.SetStatusText(os.path.basename(self.last_name_saved) + ' Saved', 0)
268 self.modify = False
269 self.statusbar.SetStatusText('', 1)
270
271 except IOError as error:
272 dlg = wx.MessageDialog(self, 'Error saving file\n' + str(error))
273 dlg.ShowModal()
274 else:
275 self.OnSaveAsFile(event)
276
277
278 def OnSaveAsFile(self, event):
279 save_dlg = wx.FileDialog(self, message="Save file as ...",
280 defaultDir=os.getcwd(),
281 defaultFile="",
282 wildcard=wildcard,
283 style=wx.FD_SAVE |
284 wx.FD_OVERWRITE_PROMPT)
285 save_dlg.SetFilterIndex(0)
286
287 if save_dlg.ShowModal() == wx.ID_OK:
288 path = save_dlg.GetPath()
289
290 try:
291 file = open(path, 'w')
292 text = self.text.GetValue()
293 file.write(text)
294 file.close()
295 self.last_name_saved = os.path.basename(path)
296 self.statusbar.SetStatusText(self.last_name_saved + ' Saved', 0)
297 self.modify = False
298 self.statusbar.SetStatusText('', 1)
299
300 except IOError as error:
301 dlg = wx.MessageDialog(self, 'Error saving file\n' + str(error))
302 dlg.ShowModal()
303 save_dlg.Destroy()
304
305
306 def OnCut(self, event):
307 self.text.Cut()
308
309
310 def OnCopy(self, event):
311 self.text.Copy()
312
313
314 def OnPaste(self, event):
315 self.text.Paste()
316
317
318 def QuitApplication(self, event):
319 if self.modify:
320 dlg = wx.MessageDialog(self, 'Save before Exit ?', '', wx.YES_NO | wx.YES_DEFAULT |
321 wx.CANCEL | wx.ICON_QUESTION)
322 val = dlg.ShowModal()
323 if val == wx.ID_YES:
324 self.OnSaveFile(event)
325 if not self.modify:
326 wx.Exit()
327 elif val == wx.ID_CANCEL:
328 dlg.Destroy()
329 else:
330 self.Destroy()
331 else:
332 self.Destroy()
333
334
335 def OnDelete(self, event):
336 frm, to = self.text.GetSelection()
337 self.text.Remove(frm, to)
338
339
340 def OnSelectAll(self, event):
341 self.text.SelectAll()
342
343
344 def OnTextChanged(self, event):
345 self.modify = True
346 self.statusbar.SetStatusText(' Modified', 1)
347
348 event.Skip()
349
350
351 def OnKeyDown(self, event):
352 keycode = event.GetKeyCode()
353 if keycode == wx.WXK_INSERT:
354 if not self.replace:
355 self.statusbar.SetStatusText('INS', 2)
356 self.replace = True
357 else:
358 self.statusbar.SetStatusText('', 2)
359 self.replace = False
360 event.Skip()
361
362
363 def ToggleStatusBar(self, event):
364 if self.statusbar.IsShown():
365 self.statusbar.Hide()
366 else:
367 self.statusbar.Show()
368 self.SendSizeEvent()
369
370
371 def StatusBar(self):
372 self.statusbar = self.CreateStatusBar()
373 self.statusbar.SetFieldsCount(3)
374 self.statusbar.SetStatusWidths([-5, -2, -1])
375
376
377 def OnAbout(self, event):
378 dlg = wx.MessageDialog(self,
379 '\tEditor\t\n'\
380 '\n'\
381 'Another Tutorial\n'\
382 'Jan Bodnar 2005-2006\n'\
383 'Updated by Ecco 2020.',
384 'About Editor',
385 wx.OK |
386 wx.ICON_INFORMATION)
387 dlg.ShowModal()
388 dlg.Destroy()
389
390 #---------------------------------------------------------------------------
391
392
393 app = wx.App()
394 Editor(None, -1, 'Editor')
395 app.MainLoop()
Download source
Additional Information
Link :
https://teratail.com/questions/124859?link=qa_related_pc
- - - - -
https://wiki.wxpython.org/TitleIndex
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....