在wxpython中实现一个简单的文本编辑器。
请注意对列外(exception)的使用,找到和解决 bug 是一个程序员的义务。
这包括那些低级(nasty)错误,比如在编辑器里打开了图片,以及对各种可能情况的模拟。
如果脚本出现了一个未予处理的例外,我就会写些代码里解决这个问题。
专题:wxpython中文教程
例子:
#!/usr/bin/python
# -*- coding: utf-8 -*-
#Editor
import wx
import os
class Editor(wx.Frame):
def __init__(self, parent, id, title):
wx.Frame.__init__(self, parent, id, title, size=(600, 500))
#变量
self.modify = False
self.last_name_saved = ''
self.replace = False
#建立菜单栏
menubar = wx.MenuBar()
file = wx.Menu()
new = wx.MenuItem(file, 101, '新建(&N)tCtrl+N', '建立一个新文档')
new.SetBitmap(wx.Bitmap('icons/stock_new-16.png'))
file.AppendItem(new)
open = wx.MenuItem(file, 102, '打开(&O)tCtrl+O', '打开一个已有的文件')
open.SetBitmap(wx.Bitmap('icons/stock_open-16.png'))
file.AppendItem(open)
file.AppendSeparator()
save = wx.MenuItem(file, 103, '保存(&S)tCtrl+S', '保存文件')
save.SetBitmap(wx.Bitmap('icons/stock_save-16.png'))
file.AppendItem(save)
saveas = wx.MenuItem(file, 104, '另存为(Save &as)tCtrl+S',
'另存文件')
saveas.SetBitmap(wx.Bitmap('icons/stock_save_as-16.png'))
file.AppendItem(saveas)
file.AppendSeparator()
quit = wx.MenuItem(file, 105, '退出(&Q)tCtrl+Q', '退出程序')
quit.SetBitmap(wx.Bitmap('icons/stock_exit-16.png'))
file.AppendItem(quit)
edit = wx.Menu()
cut = wx.MenuItem(edit, 106, '剪切(C&ut)tCtrl+X',
'剪切选取内容到剪贴板')
cut.SetBitmap(wx.Bitmap('icons/stock_cut-16.png'))
edit.AppendItem(cut)
copy = wx.MenuItem(edit, 107, '复制(&C)tCtrl+C',
'复制选取内容剪贴板')
copy.SetBitmap(wx.Bitmap('icons/stock_copy-16.png'))
edit.AppendItem(copy)
paste = wx.MenuItem(edit, 108, '粘贴(&P)tCtrl+V',
'粘贴剪贴板中的内容')
paste.SetBitmap(wx.Bitmap('icons/stock_paste-16.png'))
edit.AppendItem(paste)
delete = wx.MenuItem(edit, 109, '删除(&D)', '删除选取内容')
delete.SetBitmap(wx.Bitmap('icons/stock_delete-16.png'))
edit.AppendItem(delete)
edit.AppendSeparator()
edit.Append(110, '选取所有(Select &All)tCtrl+A', '选取所有内容')
view = wx.Menu()
view.Append(111, '状态栏(&S)', '显示状态栏')
help = wx.Menu()
about = wx.MenuItem(help, 112, '关于(&A)tF11', '关于编辑器')
about.SetBitmap(wx.Bitmap('icons/stock_about-16.png'))
help.AppendItem(about)
menubar.Append(file, '文件(&F)')
menubar.Append(edit, '编辑(&E)')
menubar.Append(view, '视图(&V)')
menubar.Append(help, '帮助(&H)')
self.SetMenuBar(menubar)
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.toolbar = self.CreateToolBar(wx.TB_HORIZONTAL
|wx.NO_BORDER|wx.TB_FLAT|wx.TB_TEXT)
self.toolbar.AddSimpleTool(801, wx.Bitmap('icons/stock_new.png'),
'新建', '')
self.toolbar.AddSimpleTool(802, wx.Bitmap('icons/stock_open.png'),
'打开', '')
self.toolbar.AddSimpleTool(803, wx.Bitmap('icons/stock_save.png'),
'保存', '')
self.toolbar.AddSeparator()
self.toolbar.AddSimpleTool(804, wx.Bitmap('icons/stock_cut.png'),
'剪切', '')
self.toolbar.AddSimpleTool(805, wx.Bitmap('icons/stock_copy.png'),
'复制', '')
self.toolbar.AddSimpleTool(806, wx.Bitmap('icons/stock_paste.png'),
'粘贴', '')
self.toolbar.AddSeparator()
self.toolbar.AddSimpleTool(807, wx.Bitmap('icons/stock_exit.png'),
'退出', '')
self.toolbar.Realize()
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.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_CLOSE, self.QuitApplication)
self.StatusBar()
self.Center()
self.Show(True)
def NewApplication(self, event):
editor = Editor(None, -1, '编辑器')
editor.Center()
editor.Show(True)
def OnOpenFile(self, event):
file_name = os.path.basename(self.last_name_saved)
if self.modify:
dlg = wx.MessageDialog(self, '保存修改吗?', '',
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):
wcd = '所有文件 (*)|*|编辑器文件 (*.ef)|*.ef|'
dir = os.getcwd()
open_dlg = wx.FileDialog(self, message='选择一个文件',
defaultDir=dir, defaultFile='',
wildcard=wcd, style=wx.OPEN|wx.CHANGE_DIR)
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, error:
dlg = wx.MessageDialog(self, '打开文件错误n'+str(error))
dlg.ShowModal()
except UnicodeDecodeError, error:
dlg = wx.MessageDialog(self, '打开文件错误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, error:
dlg = wx.MessageDialog(self, '保存文件错误n'+str(error))
dlg.ShowModal()
else:
self.OnSaveAsFile(event)
def OnSaveAsFile(self, event):
wcd = '所有文件 (*)|*|编辑器文件 (*.ef)|*.ef|'
dir = os.getcwd()
save_dlg = wx.FileDialog(self, message='保存文件为:',
defaultDir=dir, defaultFile='',
wildcard=wcd, style=wx.SAVE|wx.OVERWRITE_PROMPT)
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, error:
dlg = wx.MessageDialog(self, '保存文件错误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, '要先保存文件,再退出吗?',
'', 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, evnet):
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(' 已修改', 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()
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, 't编辑器tn 另一个教程
njan bodnar 2005-2006nwxpython.cn 汉化')
dlg.ShowModal()
dlg.Destroy()
app = wx.App()
Editor(None, -1, '编辑器')
app.MainLoop()