Archive for November, 2006

November 18, 2006: 11:48 am: kpdErgMate

It’s been some time since I last reported the state of ErgMate. It is coming along very well. I had hoped to release the beta this weekend, but there is still some work to do before it’s ready for initial testing. ErgMate has a simulated erg screen so you can test the sequences. This week involved a lot of work on making the user-interface work well as well as some refactoring of the erg simulator classes. You’ll like it when you see it!

Since 10/26:
o tweaked slide ratio voice
o added slideRatio to simulated erg
o added popup menus
o refactored drag and drop
o added split clip
o added cut-n-paste
o refactored simulated erg – now supports set distance and set time rows

November 16, 2006: 5:29 am: kpdPython, wxPython

wxGlade has the ability to integrate custom or 3rd party widgets into its pallette. This feature is not documented very well. By using some sample code from Alberto Griggio and digging through the core-widgets source code, I was able to create bridge code that adds Andrea Gavana’s FloatSpin control to the pallette. For those that follow, I suggest starting with the a similar class from the core pallette and the code for html_window. The only real gotcha for this integration was that the widget container was not seeing KILL FOCUS events from the FloatSpin controls and therefore changed data was not saved. This was fixed by trapping EV_FLOATSPIN events and calling the update.

wxGlade Pallette with Float Spin

The FloatSpin bridge code is installed by untarring from within your .wxglade directory. The included README contains more details.

Edits:
11/16/2006 – uploaded version 1.1. Adds event handlers and support for digits=0.

November 15, 2006: 6:07 am: kpdPython, wxPython

I try to create reusable windows as subclases of wx.Panel and then insert them into frames as needed. This morning I had a panel that needed to perform some cleanup. The problem was that the close event happens on the frame, not the panel. Overriding the obvious methods, Destroy, Close, etc did not work as expected. I found the answer from Robin Dunn deep in the wxPython mailing list:


<pre>
     # __init__ method of wx.Panel subclass
     self.Bind(wx.EVT_WINDOW_DESTROY, self.OnDestroy)

    def OnDestroy(self, event):
        ## clean up resources as needed here
        event.Skip()
</pre>

Seems obvious now. Another step forward in learning the wxPython/wxWidgets philosophy.

November 14, 2006: 10:07 pm: kpdPython, wxPython

I have a mini-Frame whose child controls change based on a user selection. It took awhile to get the resizing and layout working as controls are added and removed from the panel. This is the final code that works. The event handler calls selectedXXX, where XXX is one of the options. Each set of controls that are shown or hiddern reside in their own sizer, although if it were just one control you can show or hide it directly.

<pre>
def selectedXXX(self):
&nbsp;&nbsp;self.mainSizer.Show(self.rXXXSizer)
&nbsp;&nbsp;self.mainSizer.Hide(self.ZZZSizer)
&nbsp;&nbsp;#hide other sizers/windows as needed
&nbsp;&nbsp;.
&nbsp;&nbsp;.
&nbsp;&nbsp;.
&nbsp;&nbsp;self.updateAfterControlsChange()
<br>
def updateAfterControlsChange(self):
&nbsp;&nbsp;self.Fit()
&nbsp;&nbsp;self.GetParent().Fit()
&nbsp;&nbsp;self.GetParent().SendSizeEvent()
</pre>

November 7, 2006: 6:56 am: kpdPython, wxPython

After adding the LC_SORT_ASCENDING style to a list control I started to see some odd behavior. Some items would not drag-n-drop while other drag-n-drops dropped the wrong item! This is what happend:

Originally the list was unsorted. Since the data portion of items in a list control must be an integer (due to the underlying C++ wXWindows implementation), I had simply set the data portion to the index returned by InsertStringItem:


index = self.InsertStringItem( sys.maxint,  anObject.name )
self.SetItemData(index, index) 
self.dataMap[index] = anObject

Now this works fine as long as the ordering of the list control does not change. Naturally it does when you later go back and set the style to sorted! Once this style is set, you may receive the same index back multiple times from InsertStringItem. This sometimes overwrote entries in self.dataMap, causing the problems with drag-n-drop.

The solution was simple – when loading the list, keep your own index, incrementing it as items are added. Set the data for a given entry to this index and use this same index, not the one returned from InsertStringItem, to index the dataMap:


        self.dataMap = {}
        dataMapIndex=0
        for object in listOfObjectsToAdd:
&nbsp;&nbsp;            index = self.InsertStringItem( sys.maxint, object.name )
&nbsp;&nbsp;            self.SetItemData(index, itemDataMapIndex)
&nbsp;&nbsp;            self.dataMap[dataMapIndex]=( clip )
&nbsp;&nbsp;            dataMapIndex += 1

So now no matter how the list is reordered, the data associated with an entry will be the correct key into the dataMap.

I hope this tip may save others some time debugging, even though it is probably obvious to someone with wxPython/wxWindows experience.

November 4, 2006: 10:37 am: kpdErgTour, indoor-rowing

I’ve just uploaded a new version of Erg Tour. This version contains the following changes:

  • installs three races along with start-menu options to view the races without the erg attached
  • documents PM3 firmware requirements and how to upgrade
  • adds a new option to show the rower’s perspective
  • contains improved recording documentation
  • improves the recording function within the program

Links:
Updated Documentation
Latest Version of Erg Tour

November 2, 2006: 7:51 am: kpdErgMate, indoor-rowing

o cleaned up the gui
o added slideRatio to simulated erg
o looked into auto-connect to the Erg
o added popup menus
o started refactoring of drag and drop

Robin Dunn’s book wxPython in Action has already paid for itself in time savings. I can not recommend it enough. I was having trouble activiating the pop-up menus correctly today. They would only activate on a double-right-click instead of a single-click. Robin’s book demonstrated how I needed to change the event handling with a concise example ( I was using the right-click event instead of the context menu event).