wxPython


March 8, 2008: 3:17 pm: kpdPython, wxPython

TimeSpin has a bug in that it reports the same width for GetBestSize when AM/PM is shown and when it is not (24 hour format). This causes an empty space to appear after the control when it is set to display time in 24 hours. I’m not able to fix the bug at this point, but I was able to add a workaround that adjusts the width as needed.

Version 1.4 of the time_spin_and_control distrubution contains the workaround.

February 13, 2008: 7:21 am: kpdPython, wxPython

I added a workaround for a problem with timectrl.

You’ll want to upgrade to the 1.4 version of the time_spin_and_control distribution if you use limited, min, max, or value parameters in Glade when specifying the control.

Edit - 3/8 - updated to version 1.4

February 11, 2008: 7:17 am: kpdPython, wxPython

The program I’m working on (ErgMate) requires entry of hours/mins/seconds durations. I just defined input as total number of seconds for the initial prototypes, but the time has come to make it more usable. I was able to create the bridge code necessary to add the wx.lib.masked.TimeCtrl to the wxGlade widget palette by following examples from Alberto Griggio .

The normal TimeCtrl can bind to an external scroll button. The package also includes a new control called TimeSpin. It is based on Andrea Gavana’s FloatSpin control, and provides both a TimeCtrl and scroll button in one control. TimeSpin does not accept the format nor the scrollBar parameters, otherwise it should be a drop-in replacement for TimeCtrl. Let me know if I missed something important in the interface.

There is (at least!) one minor problem with TimeSpin: It seems to report too large a width - its bounding box is actually wider than the displayed control. I’d appreciate anyone with more knowledge of wxPython than I looking into it and sending a patch. For now it’s good enough to get started using.

Both time widgets are added to wxGlade by untarring the time_spin_and_control distribution from within your .wxglade directory. The included README contains more details.

Edit:
1.1 - fixed codegen problem w/value
1.2 - fixed loading problem when presetting a value
1.3 - added workaround for bug in timectrl when using min/max/limited settings

February 2, 2008: 8:18 am: kpdwxPython

This morning I started getting the following exception when generating code from wxGlade:

Traceback (most recent call last):
  File "c:tempwxGladeapplication.py", line 394, in generate_code
    class_names=class_names)
  File "c:tempwxGladexml_parse.py", line 503, in __init__
   .
   .
   .
  File "c:tempwxGladexml_parse.py", line 593, in endElement
    self.code_writer.add_class(obj)
  File "c:tempwxGladecodegenpy_codegen.py", line 640, in add_class
    indentation = prev_src.spaces[code_obj.klass]
KeyError: 'FancyListControl'

There was only one mention of a similar problem on the wxGlade mailing list. The solution posted there was to start a new project - not really an option at this stage of development.

So after a little digging, I found a different solution.

The item causing the problem is a fancy subclass of ListControl defined in another module. I had placed a wx.Panel in the sizer slot, and had then changed the class to my fancy ListControl. Is the problem now obvious? This fancy list control is not equivalent to a wx.Panel from wxGlade’s perspective. Removing the panel and instead adding a ListControl with my fancy control as the class name fixed everything up.

So, in summary, use the closest matching wxGlade class (ListControl instead of Panel) when using your own classes.

Doh.

February 15, 2007: 8:02 am: kpdwxPython

wxGlade has an option for ‘overwrite sources’ in the application dialog:

I normally have it off, but when doing some exploratory testing I enabled it. This morning I was working on my main application and regenerated the code. Guess what? Yes, it overwrote every gui class. Three things led to this:

1. I had assumed the overwrite setting was stored in the .wxg file (it is part of the configuration for a given application.)
2. My main wxsGlade window is sized so that option is not normally visible.
3. The value for ‘overwrite sources’ is actually a global configuration.

So BE CAREFUL with this option. Fortunately, a svn update brought the code back to where it was just a few minutes earlier minus a minor gui change.

February 11, 2007: 12:53 am: kpdwxPython

I just noticed that my wxPython application looks different after creation of an exe with Py2Exe. The image on the left is the application running under the normal python interpreter. The one on the right is the same application after creation of an exe with Py2exe.

Notice:
1. The dark gray below the Music label instead of white.
2. The area around Music is inset in the exe version.
3. The splash handle separator is different, it looks more 3D in the Py2EXE version.

This is with wxPython 2.8.1.1.

I’d guess there is a simple solution, but I’m not finding it. Any ideas?

Edit:
Solution is at: http://wiki.wxpython.org/index.cgi/DistributingYourApplication

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:

     # __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()

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.

def selectedXXX(self):
  self.mainSizer.Show(self.rXXXSizer)
  self.mainSizer.Hide(self.ZZZSizer)
  #hide other sizers/windows as needed
  .
  .
  .
  self.updateAfterControlsChange()
<br>
def updateAfterControlsChange(self):
&nbsp;&nbsp;self.Fit()
&nbsp;&nbsp;self.GetParent().Fit()
&nbsp;&nbsp;self.GetParent().SendSizeEvent()
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:
   index = self.InsertStringItem( sys.maxint, object.name )
   self.SetItemData(index, itemDataMapIndex)
   self.dataMap[dataMapIndex]=( clip )
   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.

Next Page »