Any way to expand wx.Choice/ wx.ComboBox programatically?

Hi all

With MSW, pressing F4 expands a wx.Choice or wx.ComboBox so that the user
can use the up/down arrows to make a selection. I cannot find a way to get
similar behaviour with GTK2. I can bind EVT_KEY_DOWN, and I can trap F4 or
any other key, but I cannot find a method to tell the control to expand
itself.

Without it, the only way the user can make a selection is to use the mouse
to expand the control, and this breaks the philosophy that the user should
be able to process an entire form using only the keyboard.

Any suggestions?

Thanks

Frank Millman

Frank Millman wrote:

Hi all

With MSW, pressing F4 expands a wx.Choice or wx.ComboBox so that the user
can use the up/down arrows to make a selection. I cannot find a way to get
similar behaviour with GTK2.

Hmm... I thought that there was a standard key to do it on GTK too, but I can't seem to find it now.

I can bind EVT_KEY_DOWN, and I can trap F4 or

any other key, but I cannot find a method to tell the control to expand
itself.

There isn't one.

Without it, the only way the user can make a selection is to use the mouse
to expand the control, and this breaks the philosophy that the user should
be able to process an entire form using only the keyboard.

Any suggestions?

If you switch to using a custom ComboCtrl then you have more control over it, and can force the drop-down to display.

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

Frank Millman wrote:
> Hi all
>
> With MSW, pressing F4 expands a wx.Choice or wx.ComboBox so
that the
> user can use the up/down arrows to make a selection. I
cannot find a
> way to get similar behaviour with GTK2.

Hmm... I thought that there was a standard key to do it on
GTK too, but I can't seem to find it now.

Thanks, Robin. Sorry for the delay in replying. It took me a while to figure
out how the custom ComboCtrl works.

I have found that, if you use wx.Choice, the space bar expands the selection
in GTK2, which actually feels quite smooth. Of course that cannot work with
wx.ComboBox as it is editable, so a space is treated as replacing the
current string.

If you switch to using a custom ComboCtrl then you have more
control over it, and can force the drop-down to display.

Yes, this was a great suggestion, thanks.

I was looking for the equivalent of wx.Choice, so after experimenting, I
ended up with combining a wx.ListBox with a custom ComboCtrl. I have got it
working quite nicely, as you can see from the attached sample. It has the
following functionality -

1. clicking on the button or pressing the spacebar opens the listbox
2. clicking an item with the mouse selects the item and closes the listbox
3. using the up/down arrows changes the selection
4. pressing enter selects the item and closes the listbox
5. pressing escape closes the listbox without changing the selection
6. using the up/down arrows without opening the listbox scrolls through the
items in situ

This is almost the same functionality as wx.Choice itself, except -
    MSW uses F4 instead of space to open the dropdown
    GTK2 does not have number 6, which I find quite useful

I still have a few cosmetic problems -

1. I want to adjust the height of the listbox so that it is just big enough
to show the choices, but it is dependant on the height of the current font.
I was hoping that wx.ListBox would have a GetRowHeight method, but it does
not. What is the best way to determine the appropriate height?

2. With GTK2, when the listbox is open, the selected line is highlighted
with the brown, inactive, background instead of the usual blue one. Is there
a way to change this?

3. With GTK2, when the ComboCtrl loses focus, it leaves the text highlighted
with the brown, inactive, background. I want to clear the background
altogether. I had a similar problem with wx.TextCtrl, which I solved by
calling SetSelection(-1,-1) on LostFocus. I tried that with my new control,
but firstly, the lostfocus event seems to be triggered when the control
gains focus (!), and secondly, there is no SetSelection method. Is there a
way to solve this?

Thanks

Frank

fm55.py (4.51 KB)

Frank Millman wrote:

I was looking for the equivalent of wx.Choice, so after experimenting, I
ended up with combining a wx.ListBox with a custom ComboCtrl. I have got it
working quite nicely, as you can see from the attached sample. It has the
following functionality -

1. clicking on the button or pressing the spacebar opens the listbox
2. clicking an item with the mouse selects the item and closes the listbox
3. using the up/down arrows changes the selection
4. pressing enter selects the item and closes the listbox
5. pressing escape closes the listbox without changing the selection
6. using the up/down arrows without opening the listbox scrolls through the
items in situ

This is almost the same functionality as wx.Choice itself, except -
    MSW uses F4 instead of space to open the dropdown
    GTK2 does not have number 6, which I find quite useful

I still have a few cosmetic problems -

1. I want to adjust the height of the listbox so that it is just big enough
to show the choices, but it is dependant on the height of the current font.
I was hoping that wx.ListBox would have a GetRowHeight method, but it does
not. What is the best way to determine the appropriate height?

You could use GetBestSize, but I think it has some built-in limits that you may not like. You can also use GetTextExtent to find the height needed by the font for a single line, but you'll also need to multiply that by some platform specific value that is the space between lines.

2. With GTK2, when the listbox is open, the selected line is highlighted
with the brown, inactive, background instead of the usual blue one. Is there
a way to change this?

I think it's because the listbox isn't actually getting the focus, so the platform colour for selected-but-inactive is used. IIRC this is a side-effect of using a wx.PopupWindow as the base, and I don't think it can be changed.

3. With GTK2, when the ComboCtrl loses focus, it leaves the text highlighted
with the brown, inactive, background.

This is a similar issue as the above, and it is the native platform behavior. GTK defines that whichever widget has the current X selection (aka the primary selection, aka what you get if you middle click in some other widget) will still show that text as selected, even if it doesn't have the focus. If some other widget grabs the primary selection then the one that looses it will be redrawn without the selection colour. (You can see this in your example by putting some text in Field1 and Field2, then select some text in Field1, then click in Field2. You'll see that the selection is still shown in 1, possibly with a different colour. Then select some text in 2 and 1 will show that it has lost the active selection)

So the short answer is that the ComboCtrl is doing the right thing here according to platform standards.

I want to clear the background
altogether. I had a similar problem with wx.TextCtrl, which I solved by
calling SetSelection(-1,-1) on LostFocus. I tried that with my new control,
but firstly, the lostfocus event seems to be triggered when the control
gains focus (!),

The focus is being moved to the wx.TextCtrl that is embedded within the ComboCtrl.

and secondly, there is no SetSelection method. Is there a
way to solve this?

You can get access to the embedded wx.TextCtrl with self.GetTextCtrl()

···

--
Robin Dunn
Software Craftsman
http://wxPython.org Java give you jitters? Relax with wxPython!

Robin Dunn wrote:

Frank Millman wrote:

> I was looking for the equivalent of wx.Choice, so after
experimenting, I
> ended up with combining a wx.ListBox with a custom
ComboCtrl.
>
> I still have a few cosmetic problems -
>
> 1. I want to adjust the height of the listbox so that it is
just big enough
> to show the choices, but it is dependant on the height of
the current font.
> I was hoping that wx.ListBox would have a GetRowHeight
method, but it does
> not. What is the best way to determine the appropriate height?

You could use GetBestSize, but I think it has some built-in
limits that
you may not like. You can also use GetTextExtent to find the height
needed by the font for a single line, but you'll also need to
multiply
that by some platform specific value that is the space between lines.

Thanks. I will experiment with this.

>
> 2. With GTK2, when the listbox is open, the selected line
is highlighted
> with the brown, inactive, background instead of the usual
blue one. Is there
> a way to change this?

I think it's because the listbox isn't actually getting the focus, so
the platform colour for selected-but-inactive is used. IIRC
this is a
side-effect of using a wx.PopupWindow as the base, and I
don't think it
can be changed.

Thanks for the explanation. I can live with it.

>
> 3. With GTK2, when the ComboCtrl loses focus, it leaves the
text highlighted
> with the brown, inactive, background.

This is a similar issue as the above, and it is the native platform
behavior.

So the short answer is that the ComboCtrl is doing the right
thing here
according to platform standards.

> I want to clear the background
> altogether. I had a similar problem with wx.TextCtrl, which
I solved by
> calling SetSelection(-1,-1) on LostFocus. I tried that with
my new control,
> but firstly, the lostfocus event seems to be triggered when
the control
> gains focus (!),

The focus is being moved to the wx.TextCtrl that is embedded
within the
ComboCtrl.

> and secondly, there is no SetSelection method. Is there a
> way to solve this?

You can get access to the embedded wx.TextCtrl with self.GetTextCtrl()

Thanks for the explanation. I 'solved' it by getting the text control,
binding the lost focus event, and calling SetSelection(0,0) - I made a
mistake above when I referred to SetSelection(-1,-1), which selects the
entire text. According to your explanation this breaks the GTK standard, but
I must admit I don't particularly like the standard behaviour, so my
modification feels more natural to me.

Thanks for all the assistance.

Frank