Topics

Next question about a wx.SingleChoiceDialog


Jacob Kruger
 

Ok, would like to ask a user to make a selection/choice sort of at runtime, and, thought maybe the wx.SingleChoiceDialog could handle it for me, but, am getting the following error from the log:

TypeError: SingleChoiceDialog(): argument 1 has unexpected type 'GlobalPlugin'


That's since this is currently executing inside a global plugin add-on, and, thus, self am trying to pass to the __init__ of the wx.SingleChoiceDialog is of that type?


And, here's the current test code snippet:

#start code snippet

dlg = wx.SingleChoiceDialog(self, 'Test Single Choice', 'The Caption', ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'], wx.CHOICEDLG_STYLE)
if dlg.ShowModal() == wx.ID_OK:
  ui.browseableMessage("You selected: %s\n" % dlg.GetStringSelection(), "choice made", False)

#end code snippet


It's that dlg =... line that's generating the exception?


Thoughts on something like this, or do I need to go the whole way, and, try build a full-on wx dialog from scratch? Ask since, all I really want is for the user to make a choice from a list of values at this stage.


TIA, again

Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."


Lukasz Golonka
 

On Wed, 6 Jan 2021 19:59:44 +0200
"Jacob Kruger" <jacob@blindza.co.za> wrote:

Ok, would like to ask a user to make a selection/choice sort of at runtime, and, thought maybe the wx.SingleChoiceDialog could handle it for me, but, am getting the following error from the log:
TypeError: SingleChoiceDialog(): argument 1 has unexpected type 'GlobalPlugin'


That's since this is currently executing inside a global plugin add-on, and, thus, self am trying to pass to the __init__ of the wx.SingleChoiceDialog is of that type?
The first parameter to the wx.SingleChoiceDialog constructor is its
parent, so you should pass gui.mainFrame instead of self.

--
Regards
Lukasz


Sean
 

Probably the problem is with the self method.

Writing another class might fix the problem.

On 06/01/2021 20:59, Jacob Kruger wrote:

Ok, would like to ask a user to make a selection/choice sort of at runtime, and, thought maybe the wx.SingleChoiceDialog could handle it for me, but, am getting the following error from the log:

TypeError: SingleChoiceDialog(): argument 1 has unexpected type 'GlobalPlugin'


That's since this is currently executing inside a global plugin add-on, and, thus, self am trying to pass to the __init__ of the wx.SingleChoiceDialog is of that type?


And, here's the current test code snippet:

#start code snippet

dlg = wx.SingleChoiceDialog(self, 'Test Single Choice', 'The Caption', ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight'], wx.CHOICEDLG_STYLE)
if dlg.ShowModal() == wx.ID_OK:
  ui.browseableMessage("You selected: %s\n" % dlg.GetStringSelection(), "choice made", False)

#end code snippet


It's that dlg =... line that's generating the exception?


Thoughts on something like this, or do I need to go the whole way, and, try build a full-on wx dialog from scratch? Ask since, all I really want is for the user to make a choice from a list of values at this stage.


TIA, again

Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."


Jacob Kruger
 

Ok, Lukasz, that works, but, only issue is NVDA goes silent when that choices dialogue pops up?


As in, if I then toggle narrator on, can make a selection, when NVDA will wake up again, but, inbetween, NVDA is sort of on hold?  Could that be due to the fact that it's showModal()?


But, tried switching it over to just show(), and, nothing seemed to be happening, except the result was being returned as None - will carry on playing around a bit.


Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."

On 2021-01-06 08:31 PM, Lukasz Golonka via groups.io wrote:
On Wed, 6 Jan 2021 19:59:44 +0200
"Jacob Kruger" <jacob@...> wrote:

Ok, would like to ask a user to make a selection/choice sort of at runtime, and, thought maybe the wx.SingleChoiceDialog could handle it for me, but, am getting the following error from the log:
TypeError: SingleChoiceDialog(): argument 1 has unexpected type 'GlobalPlugin'


That's since this is currently executing inside a global plugin add-on, and, thus, self am trying to pass to the __init__ of the wx.SingleChoiceDialog is of that type?
The first parameter to the wx.SingleChoiceDialog constructor is its
parent, so you should pass gui.mainFrame instead of self.


Sean
 

It may be blocking the main thread.

On 07/01/2021 11:22, Jacob Kruger wrote:

Ok, Lukasz, that works, but, only issue is NVDA goes silent when that choices dialogue pops up?


As in, if I then toggle narrator on, can make a selection, when NVDA will wake up again, but, inbetween, NVDA is sort of on hold?  Could that be due to the fact that it's showModal()?


But, tried switching it over to just show(), and, nothing seemed to be happening, except the result was being returned as None - will carry on playing around a bit.


Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."
On 2021-01-06 08:31 PM, Lukasz Golonka via groups.io wrote:
On Wed, 6 Jan 2021 19:59:44 +0200
"Jacob Kruger" <jacob@...> wrote:

Ok, would like to ask a user to make a selection/choice sort of at runtime, and, thought maybe the wx.SingleChoiceDialog could handle it for me, but, am getting the following error from the log:
TypeError: SingleChoiceDialog(): argument 1 has unexpected type 'GlobalPlugin'


That's since this is currently executing inside a global plugin add-on, and, thus, self am trying to pass to the __init__ of the wx.SingleChoiceDialog is of that type?
The first parameter to the wx.SingleChoiceDialog constructor is its
parent, so you should pass gui.mainFrame instead of self.


Jacob Kruger
 

Do you thus think I should be making use of a separate thread then, and, in main thread, do something like put in a while True loop to keep on checking if a value is returned/changed?


This is not too important, but, just wanted a quick easy way of asking user to make a choice, without needing to do full-on wx gui composition, but, maybe will look into that in any case.


Idea is also that the choice options might change somewhat dynamically, so, wouldn't want to hard-code them as such, like binding them to separate script key combinations, etc.


Thanks for responses


Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."

On 2021-01-07 12:28 PM, Sean wrote:

It may be blocking the main thread.

On 07/01/2021 11:22, Jacob Kruger wrote:

Ok, Lukasz, that works, but, only issue is NVDA goes silent when that choices dialogue pops up?


As in, if I then toggle narrator on, can make a selection, when NVDA will wake up again, but, inbetween, NVDA is sort of on hold?  Could that be due to the fact that it's showModal()?


But, tried switching it over to just show(), and, nothing seemed to be happening, except the result was being returned as None - will carry on playing around a bit.


Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."
On 2021-01-06 08:31 PM, Lukasz Golonka via groups.io wrote:
On Wed, 6 Jan 2021 19:59:44 +0200
"Jacob Kruger" <jacob@...> wrote:

Ok, would like to ask a user to make a selection/choice sort of at runtime, and, thought maybe the wx.SingleChoiceDialog could handle it for me, but, am getting the following error from the log:
TypeError: SingleChoiceDialog(): argument 1 has unexpected type 'GlobalPlugin'


That's since this is currently executing inside a global plugin add-on, and, thus, self am trying to pass to the __init__ of the wx.SingleChoiceDialog is of that type?
The first parameter to the wx.SingleChoiceDialog constructor is its
parent, so you should pass gui.mainFrame instead of self.


Oleksandr Gryshchenko
 

Hi friends,

Jacob, try to use gui.runScriptModalDialog method and callback function:

import gui, wx, ui

def resultHandler(result, dlg):
    if result==wx.ID_OK:
        ui.message(dlg.StringSelection)

def showDialog():
    choices = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']
    dlg = wx.SingleChoiceDialog(parent=gui.mainFrame, message='Test Single Choice', caption='The Caption', choices=choices, style=wx.CHOICEDLG_STYLE)
    gui.runScriptModalDialog(dlg, callback=lambda result: resultHandler(result, dlg))

Good luck!
Oleksandr


James Scholes
 

All wxPython-related interaction must happen on the main thread. But in NVDA, there are some specific steps you must take before showing a dialog to prevent blocking of event processing.

As Oleksandr points out here, you can use gui.runScriptModalDialog, but see below for a different option. Pass it your dialog instance without showing it yourself, as well as a callback function which should probably be a method on your global plugin/app module. The dialog will be modally displayed, and when the user dismisses it your callback function/method will be called with the result. Note that if you need to gain some information from the dialog itself after it has been closed, like the choice that was selected, you will need to keep a reference to the dialog around to retrieve that. Again, probably as a property on your global plugin/app module.

If all that sounds a bit much, there is an alternative: call gui.mainFrame.prePopup, show your dialog as normal with ShowModal, then call gui.mainFrame.postPopup. The runScriptModalDialog function takes care of this for you, but requires the creation of a callback and all the rest of it. So this method may be easier:

dlg = wx.SingleChoiceDialog(gui.mainFrame, 'Test Single Choice', ...)
gui.mainFrame.prePopup()
result = dlg.ShowModal()
gui.mainFrame.postPopup()
if result == wx.ID_OK:
# whatever

Regards,

James Scholes

On 07/01/2021 at 7:47 am, Oleksandr Gryshchenko wrote:
Hi friends,

Jacob, try to use gui.runScriptModalDialog method and callback function:

import gui, wx, ui

def resultHandler(result, dlg):
    if result==wx.ID_OK:
        ui.message(dlg.StringSelection)

def showDialog():
    choices = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']
    dlg = wx.SingleChoiceDialog(parent=gui.mainFrame, message='Test Single Choice', caption='The Caption', choices=choices, style=wx.CHOICEDLG_STYLE)
    gui.runScriptModalDialog(dlg, callback=lambda result: resultHandler(result, dlg))

Good luck!
Oleksandr


Jacob Kruger
 

Ok, Oleksandr and James, it's now working, using gui.runScriptModalDialog(), and, will try out the other method/means as well, just in case.


But, thanks for all your help/assistance, etc. - really appreciate it.


Jacob Kruger
+2782 413 4791
Skype: BlindZA
"...resistance is futile...but, acceptance is versatile..."

On 2021-01-07 06:58 PM, James Scholes wrote:
All wxPython-related interaction must happen on the main thread.  But in NVDA, there are some specific steps you must take before showing a dialog to prevent blocking of event processing.

As Oleksandr  points out here, you can use gui.runScriptModalDialog, but see below for a different option.  Pass it your dialog instance without showing it yourself, as well as a callback function which should probably be a method on your global plugin/app module.  The dialog will be modally displayed, and when the user dismisses it your callback function/method will be called with the result.  Note that if you need to gain some information from the dialog itself after it has been closed, like the choice that was selected, you will need to keep a reference to the dialog around to retrieve that.  Again, probably as a property on your global plugin/app module.

If all that sounds a bit much, there is an alternative: call gui.mainFrame.prePopup, show your dialog as normal with ShowModal, then call gui.mainFrame.postPopup.  The runScriptModalDialog function takes care of this for you, but requires the creation of a callback and all the rest of it.  So this method may be easier:

dlg = wx.SingleChoiceDialog(gui.mainFrame, 'Test Single Choice', ...)
gui.mainFrame.prePopup()
result = dlg.ShowModal()
gui.mainFrame.postPopup()
if result == wx.ID_OK:
 # whatever

Regards,

James Scholes

On 07/01/2021 at 7:47 am, Oleksandr Gryshchenko wrote:
Hi friends,

Jacob, try to use gui.runScriptModalDialog method and callback function:

import gui, wx, ui

def resultHandler(result, dlg):
    if result==wx.ID_OK:
        ui.message(dlg.StringSelection)

def showDialog():
    choices = ['zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight']
    dlg = wx.SingleChoiceDialog(parent=gui.mainFrame, message='Test Single Choice', caption='The Caption', choices=choices, style=wx.CHOICEDLG_STYLE)
    gui.runScriptModalDialog(dlg, callback=lambda result: resultHandler(result, dlg))

Good luck!
Oleksandr