SingleChoiceDialog ShowModal() will disable buttons in parent panel in EVT_UPDATE_UI event handler

Hi,

I am porting some application from python 2.4 to 3.7, and in python 3.7(wxPython version is 4.0.5a1.dev4094) I noticed when I created a Modal dialog(SingleChoiceDialog), in the event handler of EVT_UPDATE_UI of the parent panel, some buttons will be disabled, and after the dialog is closed, the buttons will be enabled again.
and if I created a Modal MessageDialog, the buttons will not be disabled, and actually the event handler of EVT_UPDATE_UI will not be called during the period when the dialog is opened.

In python 2.4(wxPython version is 2.8), I noticed the buttons will not be disabled in the event handler of EVT_UPDATE_UI when SingleChoiceDialog or MessageDialog is opened.

Is this caused by some issue in wxPython 4.0.5a1? and if I want the buttons not be affected by EVT_UPDATE_UI handler when ShowModal is called, just like the behavior in wxPython 2.8, what should I do? Any suggestions will be appreciated!

P.S. Please check the attached file for details, I created it based on wxPython demo. When “Toggle Button” is clicked, a SingleChoiceDialog will be created with ShowModal, then some buttons are disabled in “on_update_ui”. After the dialog is closed, the buttons will be enabled again when “on_update_ui” is called.

GenericButtons2.py (6.9 KB)

I’m not sure I understand your issue. Please create a small standalone sample with just enough to demonstrate the problem and without all the extra widgets and such. Also, I don’t think an update_ui handler is a good place to be showing a modal dialog, those events are intended to be very lightweight and just do state changes of the widgets they are bound to. You may have better results if you just trigger the dialog functionality to be run later with a wx.CallAfter or similar.

···

On Monday, May 20, 2019 at 8:26:44 AM UTC-7, Kedodo wrote:

Hi,

I am porting some application from python 2.4 to 3.7, and in python 3.7(wxPython version is 4.0.5a1.dev4094) I noticed when I created a Modal dialog(SingleChoiceDialog), in the event handler of EVT_UPDATE_UI of the parent panel, some buttons will be disabled, and after the dialog is closed, the buttons will be enabled again.
and if I created a Modal MessageDialog, the buttons will not be disabled, and actually the event handler of EVT_UPDATE_UI will not be called during the period when the dialog is opened.

In python 2.4(wxPython version is 2.8), I noticed the buttons will not be disabled in the event handler of EVT_UPDATE_UI when SingleChoiceDialog or MessageDialog is opened.

Is this caused by some issue in wxPython 4.0.5a1? and if I want the buttons not be affected by EVT_UPDATE_UI handler when ShowModal is called, just like the behavior in wxPython 2.8, what should I do? Any suggestions will be appreciated!

P.S. Please check the attached file for details, I created it based on wxPython demo. When “Toggle Button” is clicked, a SingleChoiceDialog will be created with ShowModal, then some buttons are disabled in “on_update_ui”. After the dialog is closed, the buttons will be enabled again when “on_update_ui” is called.

Robin

Hi Robin,

Thank you!

I simplified the sample code for your reference.

Now there are three buttons on the sample panel as the follows,

  1. GenToggleButton 2. GenBitmapToggleButton 3. GenBitmapTextButton

In sample app I registered a EVT_BUTTON handler for GenToggleButton,

and in this handler(not in update_ui handler), a SingleChoiceDialog is created with ShowModal().

and I registered a EVT_UPDATE_UI handler for GenBitmapToggleButton,

the handler will be called every second by calling “wx.UpdateUIEvent.SetUpdateInterval(1000)”.

Now the issue is, when I clicked the GenToggleButton and the SingleChoiceDialog is shown in Modal mode,

then I found the EVT_UPDATE_UI handler(on_update_ui) for GenBitmapToggleButton is stll being called,

and the IsEnabled() result for GenBitmapToggleButton and GenBitmapTextButton are False,

which means ShowModal of SingleChoiceDialog will disable the buttons on the panel.

But if I changed to show MessageDialog in the event handler of GenToggleButton,

I found the on_update_ui handler for GenBitmapToggleButton is not being called at all,

so the status of the buttons are not affected by ShowModal() at this time.

According to the wx api docs, “A modal dialog blocks program flow and user input on other windows until it is dismissed”,

but here for the case of SingleChoiceDialog, we can see the on_update_ui of the button from the parent panel is still

being called. and furthermore, the status of the buttons are also affected(changed to be disabled).

I checked my application in python 2.4(wxPython version is 2.8), I found in the the similar case for SingleChoiceDialog,

the on_update_ui is called but the status of the buttons will not be disabled.

If I want my button status keeps not being affected by ShowModal at wxPython4.0.5a1,

what should I do? Thank you so much!

在 2019年5月21日星期二 UTC+8上午12:44:26,Robin Dunn写道:

GenericButtons3.py (3.25 KB)

···

On Monday, May 20, 2019 at 8:26:44 AM UTC-7, Kedodo wrote:

Hi,

I am porting some application from python 2.4 to 3.7, and in python 3.7(wxPython version is 4.0.5a1.dev4094) I noticed when I created a Modal dialog(SingleChoiceDialog), in the event handler of EVT_UPDATE_UI of the parent panel, some buttons will be disabled, and after the dialog is closed, the buttons will be enabled again.
and if I created a Modal MessageDialog, the buttons will not be disabled, and actually the event handler of EVT_UPDATE_UI will not be called during the period when the dialog is opened.

In python 2.4(wxPython version is 2.8), I noticed the buttons will not be disabled in the event handler of EVT_UPDATE_UI when SingleChoiceDialog or MessageDialog is opened.

Is this caused by some issue in wxPython 4.0.5a1? and if I want the buttons not be affected by EVT_UPDATE_UI handler when ShowModal is called, just like the behavior in wxPython 2.8, what should I do? Any suggestions will be appreciated!

P.S. Please check the attached file for details, I created it based on wxPython demo. When “Toggle Button” is clicked, a SingleChoiceDialog will be created with ShowModal, then some buttons are disabled in “on_update_ui”. After the dialog is closed, the buttons will be enabled again when “on_update_ui” is called.

I’m not sure I understand your issue. Please create a small standalone sample with just enough to demonstrate the problem and without all the extra widgets and such. Also, I don’t think an update_ui handler is a good place to be showing a modal dialog, those events are intended to be very lightweight and just do state changes of the widgets they are bound to. You may have better results if you just trigger the dialog functionality to be run later with a wx.CallAfter or similar.

Robin

According to the wx api docs, “A modal dialog blocks program flow and user input on other windows until it is dismissed”,

but here for the case of SingleChoiceDialog, we can see the on_update_ui of the button from the parent panel is still

being called.

That is the intended behavior, nested event loops like ShowModal will still allow events to happen in other parts of the application, just no user interaction in the case of modal dialogs.

and furthermore, the status of the buttons are also affected(changed to be disabled).

I think that is also intended behavior. I can’t find it at the moment but I seem to recall that a change was made to explicitly disable widgets when a modal dialog is shown, in addition to the default behavior of the platform. It’s not happening for me on OSX so it may have been a platform-specific change.

I checked my application in python 2.4(wxPython version is 2.8), I found in the the similar case for SingleChoiceDialog,

the on_update_ui is called but the status of the buttons will not be disabled.

Things do tend to evolve over time. It’s been 8 years since the last 2.8 release.

If I want my button status keeps not being affected by ShowModal at wxPython4.0.5a1,

what should I do? Thank you so much!

It will likely take some experimentation to find a good solution, like explicitly re-enabling the buttons after ther dialog is shown, or something like that. But I assume that it’s just the change in appearance that you want to avoid, since the user can’t click on the buttons while the dialog is shown anyway. In that case you could derive new classes from the generic button classes and then change how they draw themselves when disabled, perhaps only when there is an active model dialog.

···

On Monday, May 20, 2019 at 7:11:55 PM UTC-7, Kedodo wrote:

Robin

Hi Robin,

Thank you so much for the explanation!

Actually my problem in the current project is after the modal dialog is closed, and the button status has been changed back to enable,

the bitmaps on those bitmap buttons are not changed back simultaneously.

Now my workaround is, in “on_update_ui” of one panel, force the bitmap buttons to refresh if the status is enabled.

and in another panel, I removed the “on_update_ui” at all.

I noticed if I don’t register the handler for EVT_UPDATE_UI or don’t call refresh() in “on_update_ui” handler, then this issue does not occur.

So looks like the issue is related to some combined result of ShowModal() and EVT_UPDATE_UI handler.

在 2019年5月22日星期三 UTC+8上午2:07:02,Robin Dunn写道:

···

On Monday, May 20, 2019 at 7:11:55 PM UTC-7, Kedodo wrote:

According to the wx api docs, “A modal dialog blocks program flow and user input on other windows until it is dismissed”,

but here for the case of SingleChoiceDialog, we can see the on_update_ui of the button from the parent panel is still

being called.

That is the intended behavior, nested event loops like ShowModal will still allow events to happen in other parts of the application, just no user interaction in the case of modal dialogs.

and furthermore, the status of the buttons are also affected(changed to be disabled).

I think that is also intended behavior. I can’t find it at the moment but I seem to recall that a change was made to explicitly disable widgets when a modal dialog is shown, in addition to the default behavior of the platform. It’s not happening for me on OSX so it may have been a platform-specific change.

I checked my application in python 2.4(wxPython version is 2.8), I found in the the similar case for SingleChoiceDialog,

the on_update_ui is called but the status of the buttons will not be disabled.

Things do tend to evolve over time. It’s been 8 years since the last 2.8 release.

If I want my button status keeps not being affected by ShowModal at wxPython4.0.5a1,

what should I do? Thank you so much!

It will likely take some experimentation to find a good solution, like explicitly re-enabling the buttons after ther dialog is shown, or something like that. But I assume that it’s just the change in appearance that you want to avoid, since the user can’t click on the buttons while the dialog is shown anyway. In that case you could derive new classes from the generic button classes and then change how they draw themselves when disabled, perhaps only when there is an active model dialog.

Robin