[wxPython-dev] Behaviour problems with wx.ListCtrl.SetItemState
David Hughes
dfh at forestfield.co.uk
Wed Aug 2 07:05:56 PDT 2006
Robin Dunn wrote:
> 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)
>
> 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.
I should have explored the boundaries of the problem more thoroughly.
> 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)
A neat work around that's much better than the "flag and ignore the
second event" method I've been using.
>> 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.
I'll raise a bug report shortly and will assume you don't mind if I
quote or summarise your findings and solution.
--
Regards,
David Hughes
More information about the wxpython-dev
mailing list