Patch #1428181: Sample wxProject.py updated

git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@37421 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
This commit is contained in:
Robin Dunn
2006-02-09 15:37:39 +00:00
parent b18f44e244
commit 7153b2cb86
3 changed files with 260 additions and 195 deletions

View File

@@ -793,14 +793,14 @@ class DrawingFrame(wx.Frame):
menu.Enable(menu_MOVE_BACKWARD, obj != self.contents[-1]) menu.Enable(menu_MOVE_BACKWARD, obj != self.contents[-1])
menu.Enable(menu_MOVE_TO_BACK, obj != self.contents[-1]) menu.Enable(menu_MOVE_TO_BACK, obj != self.contents[-1])
EVT_MENU(self, menu_DUPLICATE, self.doDuplicate) self.Bind(wx.EVT_MENU, self.doDuplicate, id=menu_DUPLICATE)
EVT_MENU(self, menu_EDIT_TEXT, self.doEditText) self.Bind(wx.EVT_MENU, self.doEditText, id=menu_EDIT_TEXT)
EVT_MENU(self, menu_DELETE, self.doDelete) self.Bind(wx.EVT_MENU, self.doDelete, id=menu_DELETE)
EVT_MENU(self, menu_MOVE_FORWARD, self.doMoveForward) self.Bind(wx.EVT_MENU, self.doMoveForward, id=menu_MOVE_FORWARD)
EVT_MENU(self, menu_MOVE_TO_FRONT, self.doMoveToFront) self.Bind(wx.EVT_MENU, self.doMoveToFront, id=menu_MOVE_TO_FRONT)
EVT_MENU(self, menu_MOVE_BACKWARD, self.doMoveBackward) self.Bind(wx.EVT_MENU, self.doMoveBackward, id=menu_MOVE_BACKWARD)
EVT_MENU(self, menu_MOVE_TO_BACK, self.doMoveToBack) self.Bind(wx.EVT_MENU, self.doMoveToBack, id=menu_MOVE_TO_BACK)
# Show the pop-up menu. # Show the pop-up menu.
clickPt = wx.Point(mousePt.x + self.drawPanel.GetPosition().x, clickPt = wx.Point(mousePt.x + self.drawPanel.GetPosition().x,

View File

@@ -1,3 +1,36 @@
This sample comes from an IBM developerWorks article at This sample comes from an IBM developerWorks article at
http://www-106.ibm.com/developerworks/library/l-wxpy/index.html http://www-106.ibm.com/developerworks/library/l-wxpy/index.html
Modifications by Franz Steinhaeusler 08.Feb.2006:
- tried to meet the wxPython Style Guide
(http://wiki.wxpython.org/index.cgi/wxPython_20Style_20Guide)
(also take care to use id's as less as possible)
- added docstrings
- used wx Namespace (recommend use after wxPython 2.5)
and Bind instead directly EVT_MENU
- set indentation to 4 spaces
- used MsgDlg for better overview
- added info (for adding or removing files without a root item)
- completed the menu function: File open.
- if a file was changed, and you want to quit the app, you are now
asked to save the file.
- there was a traceback with self.tree.GetFirstChild(self.root). fixed.
- close handler (save file, if you also close with mouse or alt-F4)
Modifications by Chris Barker, 08.Feb.2006:
- changed first line to #!/usr/bin/env python.
- Removing a bunch of superfluous IDs of the menu items and
event handlers and in splitterwindow.
Modifications by Franz Steinhaeusler 08.Feb.2006:
- added short program description.
- removed the string module (it is somewhat "deprecated".
- added some comments
- changed treecontrol to default style.
(I think, because of the plus and minus signs,
it is much clearer then, whether the root
item is empty or not. If there is no sign, the
root item doesn't have any children).

View File

@@ -1,286 +1,318 @@
#!/bin/python #!/usr/bin/env python
"""
This sample comes from an IBM developerWorks article at
http://www-106.ibm.com/developerworks/library/l-wxpy/index.html
This small program was adapted to demonstrate the current guide lines
on http://wiki.wxpython.org/index.cgi/wxPython_20Style_20Guide.
Changes are noted in readme.txt.
"""
import sys, os import sys, os
from wxPython.wx import * import wx
from string import *
# Process the command line. Not much to do; # Process the command line. Not much to do;
# just get the name of the project file if it's given. Simple. # just get the name of the project file if it's given. Simple.
projfile = 'Unnamed' projfile = 'Unnamed'
if len(sys.argv) > 1: if len(sys.argv) > 1:
projfile = sys.argv[1] projfile = sys.argv[1]
def MsgBox (window, string): def MsgDlg(window, string, caption='wxProject', style=wx.YES_NO|wx.CANCEL):
dlg=wxMessageDialog(window, string, 'wxProject', wxOK) """Common MessageDialog."""
dlg.ShowModal() dlg = wx.MessageDialog(window, string, caption, style)
result = dlg.ShowModal()
dlg.Destroy() dlg.Destroy()
return result
class main_window(wxFrame):
def __init__(self, parent, id, title):
wxFrame.__init__(self, parent, -1, title, size = (500, 500), class main_window(wx.Frame):
style=wxDEFAULT_FRAME_STYLE|wxNO_FULL_REPAINT_ON_RESIZE) """wxProject MainFrame."""
def __init__(self, parent, title):
"""Create the wxProject MainFrame."""
wx.Frame.__init__(self, parent, title=title, size=(500, 500),
style=wx.DEFAULT_FRAME_STYLE|wx.NO_FULL_REPAINT_ON_RESIZE)
# ------------------------------------------------------------------------------------
# Set up menu bar for the program. # Set up menu bar for the program.
# ------------------------------------------------------------------------------------ self.mainmenu = wx.MenuBar() # Create menu bar.
self.mainmenu = wxMenuBar() # Create menu bar.
mainwindow = self
menu=wxMenu() # Make a menu (will be the Project menu) # Make the 'Project' menu.
menu = wx.Menu()
exitID=wxNewId() # Make a new ID for a menu entry. item = menu.Append(wx.ID_OPEN, '&Open', 'Open project') # Append a new menu
menu.Append(exitID, '&Open', 'Open project') # Name the ID by adding it to the menu. self.Bind(wx.EVT_MENU, self.OnProjectOpen, item) # Create and assign a menu event.
EVT_MENU(self, exitID, self.OnProjectOpen) # Create and assign a menu event.
exitID=wxNewId()
menu.Append(exitID, '&New', 'New project')
EVT_MENU(self, exitID, self.OnProjectNew)
exitID=wxNewId()
menu.Append(exitID, 'E&xit', 'Exit program')
EVT_MENU(self, exitID, self.OnProjectExit)
self.mainmenu.Append (menu, '&Project') # Add the project menu to the menu bar. item = menu.Append(wx.ID_NEW, '&New', 'New project')
self.Bind(wx.EVT_MENU, self.OnProjectNew, item)
item = menu.Append(wx.ID_EXIT, 'E&xit', 'Exit program')
self.Bind(wx.EVT_MENU, self.OnProjectExit, item)
menu=wxMenu() # Make a menu (will be the File menu) self.mainmenu.Append(menu, '&Project') # Add the project menu to the menu bar.
exitID=wxNewId() # Make the 'File' menu.
menu.Append(exitID, '&Add', 'Add file to project') menu = wx.Menu()
EVT_MENU(self, exitID, self.OnFileAdd)
exitID=wxNewId()
menu.Append(exitID, '&Remove', 'Remove file from project')
EVT_MENU(self, exitID, self.OnFileRemove)
exitID=wxNewId()
menu.Append(exitID, '&Open', 'Open file for editing')
EVT_MENU(self, exitID, self.OnFileOpen)
exitID=wxNewId()
menu.Append(exitID, '&Save', 'Save file')
EVT_MENU(self, exitID, self.OnFileSave)
self.mainmenu.Append (menu, '&File') # Add the file menu to the menu bar. item = menu.Append(wx.ID_ANY, '&Add', 'Add file to project')
self.Bind(wx.EVT_MENU, self.OnFileAdd, item)
self.SetMenuBar (self.mainmenu) # Attach the menu bar to the window. item = menu.Append(wx.ID_ANY, '&Remove', 'Remove file from project')
self.Bind(wx.EVT_MENU, self.OnFileRemove, item)
item = menu.Append(wx.ID_ANY, '&Open', 'Open file for editing')
self.Bind(wx.EVT_MENU, self.OnFileOpen, item)
item = menu.Append(wx.ID_ANY, '&Save', 'Save file')
self.Bind(wx.EVT_MENU, self.OnFileSave, item)
self.mainmenu.Append(menu, '&File') # Add the file menu to the menu bar.
# Attach the menu bar to the window.
self.SetMenuBar(self.mainmenu)
# ------------------------------------------------------------------------------------
# Create the splitter window. # Create the splitter window.
# ------------------------------------------------------------------------------------ splitter = wx.SplitterWindow(self, style=wx.NO_3D|wx.SP_3D)
splitter = wxSplitterWindow (self, -1, style=wxNO_3D|wxSP_3D) splitter.SetMinimumPaneSize(1)
splitter.SetMinimumPaneSize (1)
# ------------------------------------------------------------------------------------
# Create the tree on the left. # Create the tree on the left.
# ------------------------------------------------------------------------------------ self.tree = wx.TreeCtrl(splitter, style=wx.TR_DEFAULT_STYLE)
tID = wxNewId() self.tree.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTreeLabelEdit)
self.tree = wxTreeCtrl (splitter, tID, style=wxTR_HAS_BUTTONS | self.tree.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTreeLabelEditEnd)
wxTR_EDIT_LABELS | self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTreeItemActivated)
wxTR_HAS_VARIABLE_ROW_HEIGHT)
EVT_TREE_BEGIN_LABEL_EDIT(self.tree, tID, self.OnTreeLabelEdit)
EVT_TREE_END_LABEL_EDIT(self.tree, tID, self.OnTreeLabelEditEnd)
EVT_TREE_ITEM_ACTIVATED(self.tree, tID, self.OnTreeItemActivated)
# ------------------------------------------------------------------------------------
# Create the editor on the right. # Create the editor on the right.
# ------------------------------------------------------------------------------------ self.editor = wx.TextCtrl(splitter, style=wx.TE_MULTILINE)
self.editor = wxTextCtrl(splitter, -1, style=wxTE_MULTILINE) self.editor.Enable(0)
self.editor.Enable (0)
# ------------------------------------------------------------------------------------
# Install the tree and the editor. # Install the tree and the editor.
# ------------------------------------------------------------------------------------ splitter.SplitVertically(self.tree, self.editor)
splitter.SplitVertically (self.tree, self.editor) splitter.SetSashPosition(180, True)
splitter.SetSashPosition (180, True)
self.Show(True)
# Some global state variables. # Some global state variables.
self.projectdirty = False self.projectdirty = False
self.root = None
self.close = False
self.Bind(wx.EVT_CLOSE, self.OnProjectExit)
self.Show(True)
# ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------
# Some nice little handlers. # Some nice little handlers.
# ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------
def project_open(self, project_file): def project_open(self, project_file):
"""Open and process a wxProject file."""
try: try:
input = open (project_file, 'r') input = open(project_file, 'r')
self.tree.DeleteAllItems() self.tree.DeleteAllItems()
self.project_file = project_file self.project_file = project_file
name = replace (input.readline(), "\n", "") name = input.readline().replace ('\n', '')
self.SetTitle (name) self.SetTitle(name)
# create the file elements in the tree control.
self.root = self.tree.AddRoot(name) self.root = self.tree.AddRoot(name)
self.activeitem = self.root self.activeitem = self.root
for line in input.readlines(): for line in input.readlines():
self.tree.AppendItem (self.root, replace(line, "\n", "")) self.tree.AppendItem(self.root, line.replace ('\n', ''))
input.close input.close()
self.tree.Expand (self.root) self.tree.Expand(self.root)
self.editor.Clear() self.editor.Clear()
self.editor.Enable (False) self.editor.Enable(False)
self.projectdirty = False self.projectdirty = False
except IOError: except IOError:
pass pass
def project_save(self): def project_save(self):
"""Save a wxProject file."""
try: try:
output = open (self.project_file, 'w+') output = open(self.project_file, 'w+')
output.write (self.tree.GetItemText (self.root) + "\n") output.write(self.tree.GetItemText(self.root) + '\n')
count = self.tree.GetChildrenCount(self.root) # collect all file (tree) items.
count = self.tree.GetChildrenCount (self.root)
iter = 0 iter = 0
child = '' child = ''
for i in range(count): for i in range(count):
if i == 0: if i == 0:
(child,iter) = self.tree.GetFirstChild(self.root,iter) child, cookie = self.tree.GetFirstChild(self.root)
else: else:
(child,iter) = self.tree.GetNextChild(self.root,iter) child, cookie = self.tree.GetNextChild(self.root, cookie)
output.write (self.tree.GetItemText(child) + "\n") output.write(self.tree.GetItemText(child) + '\n')
output.close() output.close()
self.projectdirty = False self.projectdirty = False
except IOError: except IOError:
dlg_m = wxMessageDialog (self, 'There was an error saving the project file.', MsgDlg(self, 'There was an error saving the new project file.', 'Error!', wx.OK)
'Error!', wxOK)
dlg_m.ShowModal() def CheckProjectDirty(self):
dlg_m.Destroy() """Were the current project changed? If so, save it before."""
open_it = True
if self.projectdirty:
# save the current project file first.
result = MsgDlg(self, 'The project has been changed. Save?')
if result == wx.ID_YES:
self.project_save()
if result == wx.ID_CANCEL:
open_it = False
return open_it
def CheckTreeRootItem(self):
"""Is there any root item?"""
if not self.root:
MsgDlg(self, 'Please create or open a project before.', 'Error!', wx.OK)
return False
return True
# ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------
# Event handlers from here on out. # Event handlers from here on out.
# ---------------------------------------------------------------------------------------- # ----------------------------------------------------------------------------------------
def OnProjectOpen(self, event): def OnProjectOpen(self, event):
open_it = True """Open a wxProject file."""
if self.projectdirty: open_it = self.CheckProjectDirty()
dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject',
wxYES_NO | wxCANCEL)
result = dlg.ShowModal()
if result == wxID_YES:
self.project_save()
if result == wxID_CANCEL:
open_it = False
dlg.Destroy()
if open_it: if open_it:
dlg = wxFileDialog(self, "Choose a project to open", ".", "", "*.wxp", wxOPEN) dlg = wx.FileDialog(self, 'Choose a project to open', '.', '', '*.wxp', wx.OPEN)
if dlg.ShowModal() == wxID_OK: if dlg.ShowModal() == wx.ID_OK:
self.project_open(dlg.GetPath()) self.project_open(dlg.GetPath())
dlg.Destroy() dlg.Destroy()
def OnProjectNew(self, event): def OnProjectNew(self, event):
open_it = True """Create a new wxProject."""
if self.projectdirty: open_it = self.CheckProjectDirty()
dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject',
wxYES_NO | wxCANCEL)
result = dlg.ShowModal()
if result == wxID_YES:
self.project_save()
if result == wxID_CANCEL:
open_it = False
dlg.Destroy()
if open_it: if open_it:
dlg = wxTextEntryDialog (self, "Name for new project:", "New Project", dlg = wx.TextEntryDialog(self, 'Name for new project:', 'New Project',
"New project", wxOK | wxCANCEL) 'New project', wx.OK|wx.CANCEL)
if dlg.ShowModal() == wxID_OK: if dlg.ShowModal() == wx.ID_OK:
newproj = dlg.GetValue() newproj = dlg.GetValue()
dlg.Destroy() dlg.Destroy()
dlg = wxFileDialog (self, "Place to store new project", ".", "", "*.wxp", dlg = wx.FileDialog(self, 'Place to store new project.', '.', '', '*.wxp', wx.SAVE)
wxSAVE) if dlg.ShowModal() == wx.ID_OK:
if dlg.ShowModal() == wxID_OK: try:
try: # save the project file.
proj = open (dlg.GetPath(), 'w') proj = open(dlg.GetPath(), 'w')
proj.write (newproj + "\n") proj.write(newproj + '\n')
proj.close() proj.close()
self.project_open (dlg.GetPath()) self.project_open(dlg.GetPath())
except IOError: except IOError:
dlg_m = wxMessageDialog (self, MsgDlg(self, 'There was an error saving the new project file.', 'Error!', wx.OK)
'There was an error saving the new project file.', dlg.Destroy()
'Error!', wxOK)
dlg_m.ShowModal() def SaveCurrentFile(self):
dlg_m.Destroy() """Check and save current file."""
dlg.Destroy() go_ahead = True
if self.root:
if self.activeitem != self.root:
if self.editor.IsModified(): # Save modified file before
result = MsgDlg(self, 'The edited file has changed. Save it?')
if result == wx.ID_YES:
self.editor.SaveFile(self.tree.GetItemText(self.activeitem))
if result == wx.ID_CANCEL:
go_ahead = False
if go_ahead:
self.tree.SetItemBold(self.activeitem, 0)
return go_ahead
def OnProjectExit(self, event): def OnProjectExit(self, event):
close = True """Quit the program."""
if self.projectdirty: if not self.close:
dlg=wxMessageDialog(self, 'The project has been changed. Save?', 'wxProject', self.close = True
wxYES_NO | wxCANCEL) if not self.SaveCurrentFile():
result = dlg.ShowModal() self.close = False
if result == wxID_YES: if self.projectdirty and self.close:
self.project_save() result = MsgDlg(self, 'The project has been changed. Save?')
if result == wxID_CANCEL: if result == wx.ID_YES:
close = False self.project_save()
dlg.Destroy() if result == wx.ID_CANCEL:
if close: self.close = False
self.Close() if self.close:
self.Close()
else:
event.Skip()
def OnFileAdd(self, event): def OnFileAdd(self, event):
dlg = wxFileDialog (self, "Choose a file to add", ".", "", "*.*", wxOPEN) """Adds a file to the current project."""
if dlg.ShowModal() == wxID_OK: if not self.CheckTreeRootItem():
path = os.path.split(dlg.GetPath()) return
self.tree.AppendItem (self.root, path[1])
self.tree.Expand (self.root) dlg = wx.FileDialog(self, 'Choose a file to add.', '.', '', '*.*', wx.OPEN)
self.project_save() if dlg.ShowModal() == wx.ID_OK:
path = os.path.split(dlg.GetPath())
self.tree.AppendItem(self.root, path[1])
self.tree.Expand(self.root)
self.project_save()
def OnFileRemove(self, event): def OnFileRemove(self, event):
"""Removes a file to the current project."""
if not self.CheckTreeRootItem():
return
item = self.tree.GetSelection() item = self.tree.GetSelection()
if item != self.root: if item != self.root:
self.tree.Delete (item) self.tree.Delete(item)
self.project_save() self.project_save()
def OnFileOpen(self, event): def OnFileOpen(self, event):
item = self.tree.GetSelection() """Opens current selected file."""
if self.root:
item = self.tree.GetSelection()
if item != self.root:
self.OnTreeItemActivated(None, item)
return
MsgDlg(self, 'There is no file to load.', 'Error!', wx.OK)
def OnFileSave(self, event): def OnFileSave(self, event):
if self.activeitem != self.root: """Saves current selected file."""
self.editor.SaveFile (self.tree.GetItemText (self.activeitem)) if self.root:
if self.activeitem != self.root:
self.editor.SaveFile(self.tree.GetItemText(self.activeitem))
return
MsgDlg(self, 'There is no file to save.', 'Error!', wx.OK)
def OnTreeLabelEdit(self, event): def OnTreeLabelEdit(self, event):
item=event.GetItem() """Edit tree label (only root label can be edited)."""
item = event.GetItem()
if item != self.root: if item != self.root:
event.Veto() event.Veto()
def OnTreeLabelEditEnd(self, event): def OnTreeLabelEditEnd(self, event):
"""End editing the tree label."""
self.projectdirty = True self.projectdirty = True
def OnTreeItemActivated(self, event):
go_ahead = True def OnTreeItemActivated(self, event, item=None):
if self.activeitem != self.root: """Tree item was activated: try to open this file."""
if self.editor.IsModified(): go_ahead = self.SaveCurrentFile()
dlg=wxMessageDialog(self, 'The edited file has changed. Save it?',
'wxProject', wxYES_NO | wxCANCEL)
result = dlg.ShowModal()
if result == wxID_YES:
self.editor.SaveFile (self.tree.GetItemText (self.activeitem))
if result == wxID_CANCEL:
go_ahead = False
dlg.Destroy()
if go_ahead:
self.tree.SetItemBold (self.activeitem, 0)
if go_ahead: if go_ahead:
item=event.GetItem() if event:
self.activeitem = item item = event.GetItem()
if item != self.root: self.activeitem = item
self.tree.SetItemBold (item, 1) if item != self.root:
self.editor.Enable (1) # load the current selected file
self.editor.LoadFile (self.tree.GetItemText(item)) self.tree.SetItemBold(item, 1)
self.editor.SetInsertionPoint (0) self.editor.Enable(1)
self.editor.SetFocus() self.editor.LoadFile(self.tree.GetItemText(item))
else: self.editor.SetInsertionPoint(0)
self.editor.Clear() self.editor.SetFocus()
self.editor.Enable (0) else:
self.editor.Clear()
self.editor.Enable(0)
class App(wxApp):
class App(wx.App):
"""wxProject Application."""
def OnInit(self): def OnInit(self):
frame = main_window(None, -1, "wxProject - " + projfile) """Create the wxProject Application."""
self.SetTopWindow(frame) frame = main_window(None, 'wxProject - ' + projfile)
if (projfile != 'Unnamed'): if projfile != 'Unnamed':
frame.project_open (projfile) frame.project_open(projfile)
return True return True
app = App(0)
app.MainLoop()
if __name__ == '__main__':
app = App(0)
app.MainLoop()