maybe it is getting (so or with some changes) into the next wxPython Distribution.
···
On Wed, 8 Feb 2006 11:13:27 +0200, Derick Van Niekerk <derickvn@gmail.com> wrote:
The demo seems to work fine - Thanks!
I wonder why it wasn't updated on the site...or why the tutorial isn't
included with the code? You are right about the tracebacks, it looks like
the implementation of the TreeCtl might have changed. Oh well, at least now
I have (semi)working source to play with
Yes you are right, the page is very old (and uses the old namespace).
============================================================================================
#!/bin/python
# This sample comes from an IBM developerWorks article at
# IBM Developer
# Modified 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 (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)
import sys, os
import wx
from string import *
# Process the command line. Not much to do;
# just get the name of the project file if it's given. Simple.
projfile = 'Unnamed'
if len(sys.argv) > 1:
projfile = sys.argv[1]
def MsgDlg (window, string, caption='wxProject', style=wx.YES_NO|wx.CANCEL):
"""Common MessageDialog."""
dlg = wx.MessageDialog(window, string, caption, style)
result = dlg.ShowModal()
dlg.Destroy()
return result
class main_window(wx.Frame):
"""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.
self.mainmenu = wx.MenuBar() # Create menu bar.
mainwindow = self
menu = wx.Menu() # Make a menu (will be the Project menu)
nId = wx.NewId() # Make a new ID for every menu entry.
menu.Append(nId, '&Open', 'Open project') # Append a new menu
self.Bind(wx.EVT_MENU, self.OnProjectOpen, id=nId) # Create and assign a menu event.
nId = wx.NewId()
menu.Append(nId, '&New', 'New project')
self.Bind(wx.EVT_MENU, self.OnProjectNew, id=nId, )
nId = wx.NewId()
menu.Append(nId, 'E&xit', 'Exit program')
self.Bind(wx.EVT_MENU, self.OnProjectExit, id=nId)
self.Bind(wx.EVT_CLOSE, self.OnProjectExit)
self.mainmenu.Append (menu, '&Project') # Add the project menu to the menu bar.
menu = wx.Menu() # Make a menu (will be the File menu)
nId = wx.NewId()
menu.Append(nId, '&Add', 'Add file to project')
self.Bind(wx.EVT_MENU, self.OnFileAdd, id=nId)
nId = wx.NewId()
menu.Append(nId, '&Remove', 'Remove file from project')
self.Bind(wx.EVT_MENU, self.OnFileRemove, id=nId)
nId = wx.NewId()
menu.Append(nId, '&Open', 'Open file for editing')
self.Bind(wx.EVT_MENU, self.OnFileOpen, id=nId)
nId = wx.NewId()
menu.Append(nId, '&Save', 'Save file')
self.Bind(wx.EVT_MENU, self.OnFileSave, id=nId)
self.mainmenu.Append (menu, '&File') # Add the file menu to the menu bar.
self.SetMenuBar (self.mainmenu) # Attach the menu bar to the window.
# Create the splitter window.
splitter = wx.SplitterWindow(self, style=wx.NO_3D|wx.SP_3D)
splitter.SetMinimumPaneSize(1)
# Create the tree on the left.
tID = wx.NewId()
self.tree = wx.TreeCtrl(splitter, tID, style=wx.TR_HAS_BUTTONS|
wx.TR_EDIT_LABELS|
wx.TR_HAS_VARIABLE_ROW_HEIGHT)
self.tree.Bind(wx.EVT_TREE_BEGIN_LABEL_EDIT, self.OnTreeLabelEdit, id=tID)
self.tree.Bind(wx.EVT_TREE_END_LABEL_EDIT, self.OnTreeLabelEditEnd, id=tID)
self.tree.Bind(wx.EVT_TREE_ITEM_ACTIVATED, self.OnTreeItemActivated, id=tID)
# Create the editor on the right.
self.editor = wx.TextCtrl(splitter, style=wx.TE_MULTILINE)
self.editor.Enable (0)
# Install the tree and the editor.
splitter.SplitVertically (self.tree, self.editor)
splitter.SetSashPosition (180, True)
self.Show(True)
# Some global state variables.
self.projectdirty = False
self.root = None
self.close = False
# ----------------------------------------------------------------------------------------
# Some nice little handlers.
# ----------------------------------------------------------------------------------------
def project_open(self, project_file):
"""Open and process a wxProject file."""
try:
input = open (project_file, 'r')
self.tree.DeleteAllItems()
self.project_file = project_file
name = replace (input.readline(), "\n", "")
self.SetTitle (name)
self.root = self.tree.AddRoot(name)
self.activeitem = self.root
for line in input.readlines():
self.tree.AppendItem(self.root, replace(line, "\n", ""))
input.close
self.tree.Expand(self.root)
self.editor.Clear()
self.editor.Enable(False)
self.projectdirty = False
except IOError:
pass
def project_save(self):
"""Save a wxProject file."""
try:
output = open (self.project_file, 'w+')
output.write (self.tree.GetItemText (self.root) + "\n")
count = self.tree.GetChildrenCount (self.root)
iter = 0
child = ''
for i in range(count):
if i == 0:
child, cookie = self.tree.GetFirstChild(self.root)
else:
child, iter = self.tree.GetNextChild(self.root, cookie)
output.write (self.tree.GetItemText(child) + "\n")
output.close()
self.projectdirty = False
except IOError:
MsgDlg(self, 'There was an error saving the new project file.', 'Error!', wx.OK)
# ----------------------------------------------------------------------------------------
# Event handlers from here on out.
# ----------------------------------------------------------------------------------------
def OnProjectOpen(self, event):
"""Open a wxProject file."""
open_it = True
if self.projectdirty:
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
if open_it:
dlg = wx.FileDialog(self, "Choose a project to open", ".", "", "*.wxp", wx.OPEN)
if dlg.ShowModal() == wx.ID_OK:
self.project_open(dlg.GetPath())
dlg.Destroy()
def OnProjectNew(self, event):
"""Create a new wxProject."""
open_it = True
if self.projectdirty:
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
if open_it:
dlg = wx.TextEntryDialog (self, "Name for new project:", "New Project",
"New project", wx.OK | wx.CANCEL)
if dlg.ShowModal() == wx.ID_OK:
newproj = dlg.GetValue()
dlg.Destroy()
dlg = wx.FileDialog (self, "Place to store new project", ".", "", "*.wxp",
wx.SAVE)
if dlg.ShowModal() == wx.ID_OK:
try:
proj = open (dlg.GetPath(), 'w')
proj.write (newproj + "\n")
proj.close()
self.project_open (dlg.GetPath())
except IOError:
MsgDlg(self, 'There was an error saving the new project file.', 'Error!', wx.OK)
dlg.Destroy()
def CheckRoot(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
def SaveCurrentFile(self):
"""Check and save current file."""
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):
"""Quit the program."""
if not self.close:
self.close = True
if not self.SaveCurrentFile():
self.close = False
if self.projectdirty and self.close:
result = MsgDlg(self, 'The project has been changed. Save?')
if result == wx.ID_YES:
self.project_save()
if result == wx.ID_CANCEL:
self.close = False
if self.close:
self.Close()
else:
event.Skip()
def OnFileAdd(self, event):
"""Adds a file to the current project."""
if not self.CheckRoot():
return
dlg = wx.FileDialog (self, "Choose a file to add", ".", "", "*.*", wx.OPEN)
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):
"""Removes a file to the current project."""
if not self.CheckRoot():
return
item = self.tree.GetSelection()
if item != self.root:
self.tree.Delete (item)
self.project_save()
def OnFileOpen(self, event):
"""Opens current selected file."""
item = self.tree.GetSelection()
self.OnTreeItemActivated(None, item)
def OnFileSave(self, event):
"""Saves current selected file."""
if self.activeitem != self.root:
self.editor.SaveFile (self.tree.GetItemText (self.activeitem))
def OnTreeLabelEdit(self, event):
"""Edit tree label (only root label can be edited)."""
item = event.GetItem()
if item != self.root:
event.Veto()
def OnTreeLabelEditEnd(self, event):
"""End editing the tree label."""
self.projectdirty = True
def OnTreeItemActivated(self, event, item=None):
"""Tree item was activated: try to open this file."""
go_ahead = self.SaveCurrentFile()
if go_ahead:
if event:
item = event.GetItem()
self.activeitem = item
if item != self.root:
self.tree.SetItemBold (item, 1)
self.editor.Enable (1)
self.editor.LoadFile (self.tree.GetItemText(item))
self.editor.SetInsertionPoint (0)
self.editor.SetFocus()
else:
self.editor.Clear()
self.editor.Enable (0)
class App(wx.App):
"""wxProject Application."""
def OnInit(self):
"""Create the wxProject Application."""
frame = main_window(None, "wxProject - " + projfile)
self.SetTopWindow(frame)
if (projfile != 'Unnamed'):
frame.project_open(projfile)
return True
if __name__ == "__main__":
app = App(0)
app.MainLoop()
============================================================================================
--
Franz Steinhaeusler