button/radio interaction bug in 2.9; workaround?

I’m constructing a preferences dialog, in which there’s an Apply button, initially disabled. Whenever a setting changes, I want to enable the Apply button. Whenever the Apply button is pressed, it should be disabled again (until another setting changes).

Sample code attached: a simple app with 3 radio buttons and an Apply button only.

I get strange behavior though, with wxPython 2.9.4.0 under Python 2.7.3 on Windows XP SP3. Run the attached sample code:

> python interaction_test.py
2.9.4.0 msw (classic)
interaction_test.py:35: wxPyDeprecationWarning: Using deprecated class PySimpleApp.
  app = wx.PySimpleApp()

(Where’s the Python-specific documentation for 2.9? http://www.wxpython.org/docs/api/ is for 2.8)

Choose radio B:

in on_radio for B
entering enable_apply_button(True)
selection at start: B
selection at end: B
leaving enable_apply_button(True)

Apply is enabled. So far so good. Now press Apply:

entering on_apply_button
entering enable_apply_button(False)
selection at start: B
in on_radio for A

What the…!? Radio A is being activated automatically here, undesired behavior. Why?

entering enable_apply_button(True)
selection at start: A
selection at end: A
leaving enable_apply_button(True)
selection at end: A
leaving enable_apply_button(False)
leaving on_apply_button

Choose radio B:

in on_radio for C
entering enable_apply_button(True)
selection at start: C
selection at end: C
leaving enable_apply_button(True)

The Apply button is not enabled. It seems to be permanently disabled. Huh?

This caused me many hours of frustration, thinking I had done a Bind call wrong or my widget hierarchy was wonky. But in wxPython 2.8, there is no problem. After editing the attached sample app to switch versions:

> python interaction_test.py
2.8.12.1 (msw-unicode)

Choose radio B:

in on_radio for B
entering enable_apply_button(True)
selection at start: B
selection at end: B

leaving enable_apply_button(True)

Apply is enabled. Now press Apply:

entering on_apply_button
entering enable_apply_button(False)
selection at start: B
selection at end: B
leaving enable_apply_button(False)

leaving on_apply_button

Works fine. Apply is disabled, the radio B selection doesn’t change. Choose radio C:

in on_radio for C
entering enable_apply_button(True)
selection at start: C

selection at end: C
leaving enable_apply_button(True)

Apply is enabled again. All is well.

I would like to stick to wxPython 2.9, since I’m using ToolBar.InsertStretchableSpace(0) and ToolBar.AddStretchableSpace(), not available in 2.8.

Any workaround to the bug above?

If this is novel, I’ll happily add it to the bug tracker.

Thanks!

interaction_test.py (1.52 KB)

···


David Goodger <http://python.net/~goodger>

David Goodger wrote:

I'm constructing a preferences dialog, in which there's an Apply button,
initially disabled. Whenever a setting changes, I want to enable the
Apply button. Whenever the Apply button is pressed, it should be
disabled again (until another setting changes).

Sample code attached: a simple app with 3 radio buttons and an Apply
button only.

I get strange behavior though, with wxPython 2.9.4.0 under Python 2.7.3
on Windows XP SP3. Run the attached sample code:

> python interaction_test.py
     2.9.4.0 msw (classic)
     interaction_test.py:35: wxPyDeprecationWarning: Using deprecated
class PySimpleApp.
       app = wx.PySimpleApp()

(Where's the Python-specific documentation for 2.9?
wxPython API Documentation — wxPython Phoenix 4.2.2 documentation is for 2.8)

The old docs have essentially been abandoned and effort is going in to the auto-generation of the docs for Phoenix instead. They won't exactly match what is in Classic wxPython but are probably still better than using the old 2.8 docs.

http://wxpython.org/Phoenix/docs/html/main.html

What the...!? Radio A is being activated automatically here, undesired
behavior. Why?

When a widget with the focus is disabled then Windows automatically moves the focus to the next widget in the tab order. For groups of RadioButtons explicitly moving the focus to one of them also selects it. You can work around this awkwardness by having some other focusable widget after the apply button, or before the radio buttons.

···

--
Robin Dunn
Software Craftsman

This is really bizarre, and has to be a bug. If there’s something wrong with your code, I sure don’t see it…

I tested your code on 2.9.1.1 under both Windows and Linux, and it works fine. 2.9.4.0 on Windows exhibits the problem.

I also mucked with the code for a while, and found out that if you add some other control after the apply button, it works. Of course, now that means you have an unneeded control swimming around, and I found that it has to be visible. Creating the control and hiding it gets back to the original problem. It’s almost like the disabling of the button while it has focus, shifts the focus to the next item in the tab traversal list, and then activates it, or the next item is catching a stray wx.EVT_LEFT_UP.

As an aside, a much better way to handle your situation is with wx.EVT_UPDATE_UI. I rewrote your code with this, but it does exhibit the same problem as you have originally reported.

interaction_test.py (1.82 KB)

···

On Mon, Feb 25, 2013 at 12:11 PM, David Goodger goodger@python.org wrote:

I’m constructing a preferences dialog, in which there’s an Apply button, initially disabled. Whenever a setting changes, I want to enable the Apply button. Whenever the Apply button is pressed, it should be disabled again (until another setting changes).

Sample code attached: a simple app with 3 radio buttons and an Apply button only.

I get strange behavior though, with wxPython 2.9.4.0 under Python 2.7.3 on Windows XP SP3. Run the attached sample code:

> python interaction_test.py
2.9.4.0 msw (classic)
interaction_test.py:35: wxPyDeprecationWarning: Using deprecated class PySimpleApp.
  app = wx.PySimpleApp()

(Where’s the Python-specific documentation for 2.9? http://www.wxpython.org/docs/api/ is for 2.8)

Choose radio B:

in on_radio for B
entering enable_apply_button(True)
selection at start: B
selection at end: B
leaving enable_apply_button(True)

Apply is enabled. So far so good. Now press Apply:

entering on_apply_button
entering enable_apply_button(False)
selection at start: B
in on_radio for A

What the…!? Radio A is being activated automatically here, undesired behavior. Why?

entering enable_apply_button(True)
selection at start: A
selection at end: A
leaving enable_apply_button(True)
selection at end: A
leaving enable_apply_button(False)
leaving on_apply_button

Choose radio B:

in on_radio for C
entering enable_apply_button(True)
selection at start: C
selection at end: C
leaving enable_apply_button(True)

The Apply button is not enabled. It seems to be permanently disabled. Huh?

This caused me many hours of frustration, thinking I had done a Bind call wrong or my widget hierarchy was wonky. But in wxPython 2.8, there is no problem. After editing the attached sample app to switch versions:

> python interaction_test.py
2.8.12.1 (msw-unicode)

Choose radio B:

in on_radio for B
entering enable_apply_button(True)
selection at start: B
selection at end: B





leaving enable_apply_button(True)

Apply is enabled. Now press Apply:

entering on_apply_button
entering enable_apply_button(False)
selection at start: B
selection at end: B
leaving enable_apply_button(False)





leaving on_apply_button

Works fine. Apply is disabled, the radio B selection doesn’t change. Choose radio C:

in on_radio for C
entering enable_apply_button(True)
selection at start: C





selection at end: C
leaving enable_apply_button(True)

Apply is enabled again. All is well.

I would like to stick to wxPython 2.9, since I’m using ToolBar.InsertStretchableSpace(0) and ToolBar.AddStretchableSpace(), not available in 2.8.

Any workaround to the bug above?

If this is novel, I’ll happily add it to the bug tracker.

Thanks!


David Goodger <http://python.net/~goodger>–

You received this message because you are subscribed to the Google Groups “wxPython-users” group.

To unsubscribe from this group and stop receiving emails from it, send an email to wxpython-users+unsubscribe@googlegroups.com.

For more options, visit https://groups.google.com/groups/opt_out.


Daniel Hyams
dhyams@gmail.com

Grr, Robin! lol!

Thanks for the input… :wink:

But the behavior is definitely different moving from 2.9.1.1 to 2.9.4.0.

···

On Mon, Feb 25, 2013 at 1:58 PM, Daniel Hyams dhyams@gmail.com wrote:

Grr, Robin! lol!

Thanks for the input… :wink:


Daniel Hyams
dhyams@gmail.com

The old docs have essentially been abandoned and effort is
going in to the auto-generation of the docs for Phoenix
instead. They won’t exactly match what is in Classic wxPython
but are probably still better than using the old 2.8 docs.

Redirecting...

Thanks, bookmarked. Perhaps the front page & table of contents of
wxpython.org could use links to the new docs as well?

What the…!? Radio A is being activated automatically here,
undesired behavior. Why?

When a widget with the focus is disabled then Windows
automatically moves the focus to the next widget in the tab
order. For groups of RadioButtons explicitly moving the focus
to one of them also selects it.

Hmm. When I tab around normally (with Apply enabled), the next
widget to get the focus after Apply is the currently selected
radio button, not the first. Is the behavior you described a
bug/wart in Windows or wx? Because it’s not exhibited in wxPython
2.8 or (as Daniel Hyams pointed out) in 2.9.1.1.

You can work around this awkwardness by having some other
focusable widget after the apply button, or before the radio
buttons.

Perhaps another workaround is to explicitly set the focus to an
innocuous widget, like an OK button, before disabling the Apply
button. Tried it… works!

Thanks Robin & Daniel for your help.

– David Goodger

···

On Monday, February 25, 2013 12:53:47 PM UTC-6, Robin Dunn wrote:

David Goodger wrote:

···

On Monday, February 25, 2013 12:53:47 PM UTC-6, Robin Dunn wrote:

> When a widget with the focus is disabled then Windows
> automatically moves the focus to the next widget in the tab
> order. For groups of RadioButtons explicitly moving the focus
> to one of them also selects it.

Hmm. When I tab around normally (with Apply enabled), the next
widget to get the focus after Apply is the *currently selected*
radio button, not the first. Is the behavior you described a
bug/wart in Windows or wx? Because it's not exhibited in wxPython
2.8 or (as Daniel Hyams pointed out) in 2.9.1.1.

Yes, after some more thought I am guessing that this may be an unintended side effect of some other change. Go ahead and create a ticket for it at trac.wxwidgets.org, adding a "regression" keyword.

--
Robin Dunn
Software Craftsman

Done: wxTrac has been migrated to GitHub Issues - wxWidgets

···

On Mon, Feb 25, 2013 at 2:49 PM, Robin Dunn <robin@alldunn.com> wrote:

Yes, after some more thought I am guessing that this may be an unintended
side effect of some other change. Go ahead and create a ticket for it at
trac.wxwidgets.org, adding a "regression" keyword.

--
David Goodger <http://python.net/~goodger&gt;