[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