[wxPython-dev] Behaviour problems with wx.ListCtrl.SetItemState
Robin Dunn
robin at alldunn.com
Tue Aug 1 16:19:02 PDT 2006
David Hughes wrote:
> I think this is MSW only. It's with wx version 2.6.3.2 (possibly there
> since 2.5) and can be demonstrated by adding the following code to
> ListCtrl demo - after line 233 (modified demo files are also attached)
>
>
> which results in:
> OnItemDeselected: 4 <== Selected item is immediately deselected
> OnItemSelected: 6, Blue Man Group, Klein Mandelbrot, New Age <==
> Deselected item is re-selected
> OnItem 6 Selected: Veto'd selection <== which brings up the dialog again
> OnItemDeselected: 6
>
> Adding the same code to ListCtrl_virtual (change all occurrences of
> "self.list" to "self"), the unconditional change works OK but there is
> the same problem after the conditional dialog.
I was about to write that I couldn't reproduce the problem, but they I
tried selecting the items with the mouse instead of the keyboard and
discovered that it is only an issue when selecting the items with the
mouse. A little more play and I discovered that it only happens when
you release the left mouse button. In fact if you hold the button down
and take the cursor outside of the listctrl and then release it then you
don't get the problem, so my guess is that the native control is doing
something on the left-up event that is "completing" the selection
started with the left-down (or something like that.)
I tried catching the EVT_LEFT_UP to try to work around this, but it
appears to be being eaten by the native control. I also don't see
anything in the wx code dealing with left up events.
I found that using a wx.FutureCall(100, ...) instead of the CallAfter
works, but if the user holds the mouse button down for longer than a
tenth of a second they the problem still happens. Using a timer much
longer than that would start to look silly for the normal clicks. So
instead I tried polling with wx.GetMouseState if it is safe to make the
selection change, and if not then delay the change again. This works well.
# unconditional change selection from 2 to 4
if self.currentItem == 2:
self.log.WriteText("OnItem 2 Selected: Veto'd selection\n")
wx.FutureCall(50, self.SelectAndFocus, 2, 4)
# conditionally change selection from 6 to 8
if self.currentItem == 6:
msgbox = wx.MessageDialog(self, 'Select Item 8
instead?','Message', wx.YES_NO)
if msgbox.ShowModal() == wx.ID_YES:
self.log.WriteText("OnItem 6 Selected: Veto'd selection\n")
wx.FutureCall(50, self.SelectAndFocus, 6, 8)
event.Skip()
def SelectAndFocus(self, oldidx, newidx):
if wx.GetMouseState().LeftDown():
wx.FutureCall(50, self.SelectAndFocus, oldidx, newidx)
else:
self.list.Select(oldidx, False)
self.list.Select(newidx, True)
self.list.Focus(newidx)
>
> Should these be reported back to wxWidgets (if they are reproducible)?
>
It would probably be a good idea if only to document that changing the
selection from within a EVT_LIST_ITEM_SELECTED handler or immediately
after the handler executes doesn't work on wxMSW. I'm not sure if
anything can be done to make it work.
--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!
More information about the wxpython-dev
mailing list