Questions re GridCellBoolEditor

Hi all

There have been a number of posts in the past about getting a
GridCellBoolEditor to behave the same as a normal CheckBox. I am trying
this, and I am getting close - see attached program.

However, I still have some questions.

1. Is there an equivalent of EVT_CHECKBOX to indicate that the box has been
checked/unchecked? At present, if the user clicks with a mouse, I can detect
it because I can detect the mouse click. But if the user tabs to the cell
and presses 'space', the cell is changed, but I cannot detect it until the
user moves off the cell, when SetValue() is called.

2. Two images for a 'checked' box seem to be used - one while the editor is
active and one when it is not. I assume that the former is drawn by
GridCellBoolEditor and the latter is drawn by GridCellBoolRenderer. On GTK2
the images are wildly different, and the second one looks hideous. On MSW
the difference is less marked, but it is still there. Would it not make
sense for them to use the same image?

3. On MSW, if the editor is active (either by clicking on the cell or by
tabbing to it), it takes two tab presses to move to the next cell - one to
close the editor, and one to do the move. Is there any way to get rid of the
first step?

Thanks for any suggestions.

Frank Millman

fm48.py (2.48 KB)

Frank Millman wrote:

Hi all

There have been a number of posts in the past about getting a
GridCellBoolEditor to behave the same as a normal CheckBox. I am trying
this, and I am getting close - see attached program.

However, I still have some questions.

1. Is there an equivalent of EVT_CHECKBOX to indicate that the box has been
checked/unchecked? At present, if the user clicks with a mouse, I can detect
it because I can detect the mouse click. But if the user tabs to the cell
and presses 'space', the cell is changed, but I cannot detect it until the
user moves off the cell, when SetValue() is called.

You can catch the EVT_GRID_EDITOR_CREATED event, and then call evt.GetControl to get a reference to the checkbox and then bind a handler to it.

2. Two images for a 'checked' box seem to be used - one while the editor is
active and one when it is not. I assume that the former is drawn by
GridCellBoolEditor and the latter is drawn by GridCellBoolRenderer. On GTK2
the images are wildly different, and the second one looks hideous. On MSW
the difference is less marked, but it is still there. Would it not make
sense for them to use the same image?

One is a native checkbox widget, and one is just a representation of the value drawn on a DC. If you want them to be the same then you could write your own custom control and a cell editor that uses it, and also a renderer class that draws the value the same way that the custom control does. The only thing you would lose is the use of the native widget.

3. On MSW, if the editor is active (either by clicking on the cell or by
tabbing to it), it takes two tab presses to move to the next cell - one to
close the editor, and one to do the move. Is there any way to get rid of the
first step?

The tab that dismisses the editor should also cause it to move to the next cell, and it seems to be doing that just fine for me in the demo. If it's not working for you then I expect that something you have done is overriding default behavior.

···

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

Robin Dunn wrote:

Frank Millman wrote:
> Hi all
>
> There have been a number of posts in the past about getting a
> GridCellBoolEditor to behave the same as a normal CheckBox. I am
> trying this, and I am getting close - see attached program.
>
> However, I still have some questions.
>
> 1. Is there an equivalent of EVT_CHECKBOX to indicate that
the box has
> been checked/unchecked? At present, if the user clicks with
a mouse, I
> can detect it because I can detect the mouse click. But if the user
> tabs to the cell and presses 'space', the cell is changed, but I
> cannot detect it until the user moves off the cell, when
SetValue() is called.

You can catch the EVT_GRID_EDITOR_CREATED event, and then
call evt.GetControl to get a reference to the checkbox and
then bind a handler to it.

Thanks for this tip - I would never have figured it out by myself.

It needed quite a few tweaks before I could get it to behave itself, but it
seems to be working correctly now. See attached program fm48.py if you are
interested.

>
> 2. Two images for a 'checked' box seem to be used - one while the
> editor is active and one when it is not. I assume that the
former is
> drawn by GridCellBoolEditor and the latter is drawn by
> GridCellBoolRenderer. On GTK2 the images are wildly
different, and the
> second one looks hideous. On MSW the difference is less
marked, but it
> is still there. Would it not make sense for them to use the
same image?

One is a native checkbox widget, and one is just a
representation of the value drawn on a DC. If you want them
to be the same then you could write your own custom control
and a cell editor that uses it, and also a renderer class
that draws the value the same way that the custom control
does. The only thing you would lose is the use of the native widget.

I guess my main concern is the image drawn by the renderer on GTK2. If I
felt strongly enough, I might try a custom renderer to draw it better. Does
anyone else agree with me that it looks horrible?

>
> 3. On MSW, if the editor is active (either by clicking on
the cell or
> by tabbing to it), it takes two tab presses to move to the
next cell -
> one to close the editor, and one to do the move. Is there
any way to
> get rid of the first step?

The tab that dismisses the editor should also cause it to
move to the next cell, and it seems to be doing that just
fine for me in the demo.
If it's not working for you then I expect that something you
have done is overriding default behavior.

I confirm that it does not happen in the demo, but for the life of me I
cannot see what is different in my program. I have attached a very
stripped-down version, fm49.py, that shows the faulty behaviour. Would you
mind checking to see if you get the same effect that I do, and if so, can
you pinpoint the reason? My platform is wxPython 2.8.0.1, Python 2.5, MS
Windows Server 2003. To see the behaviour, do the following -

If you tab twice, it correctly moves to column 2 and then column 3.
If you tab once, then press 'space', it correctly invokes the editor and
toggles the value. If you then press tab, it closes the editor, but stays on
column 2. You have to press tab again to move to column 3.

Thanks

Frank

fm48.py (1.87 KB)

fm49.py (822 Bytes)

Frank Millman wrote:

I confirm that it does not happen in the demo, but for the life of me I
cannot see what is different in my program. I have attached a very
stripped-down version, fm49.py, that shows the faulty behaviour. Would you
mind checking to see if you get the same effect that I do, and if so, can
you pinpoint the reason? My platform is wxPython 2.8.0.1, Python 2.5, MS
Windows Server 2003. To see the behaviour, do the following -

If you tab twice, it correctly moves to column 2 and then column 3.
If you tab once, then press 'space', it correctly invokes the editor and
toggles the value. If you then press tab, it closes the editor, but stays on
column 2. You have to press tab again to move to column 3.

The extra tab is being used by the panel as a navigation key. This is because the checkbox doesn't have something like the wx.TE_PROCESS_TAB style to ensure that it gets the key first. If you pass style=0 to the wx.Panel constructor then it should work as you expect.

···

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

Robin Dunn wrote:

Frank Millman wrote:

> I confirm that it does not happen in the demo, but for the
life of me
> I cannot see what is different in my program. I have
attached a very
> stripped-down version, fm49.py, that shows the faulty
behaviour. Would
> you mind checking to see if you get the same effect that I
do, and if
> so, can you pinpoint the reason? My platform is wxPython 2.8.0.1,
> Python 2.5, MS Windows Server 2003. To see the behaviour, do the
> following -
>
> If you tab twice, it correctly moves to column 2 and then column 3.
> If you tab once, then press 'space', it correctly invokes
the editor
> and toggles the value. If you then press tab, it closes the editor,
> but stays on column 2. You have to press tab again to move
to column 3.
>

The extra tab is being used by the panel as a navigation key.
This is because the checkbox doesn't have something like the
wx.TE_PROCESS_TAB
style to ensure that it gets the key first. If you pass style=0 to
the wx.Panel constructor then it should work as you expect.

Thank you, it works perfectly.

It also explains the difference between my program and the demo. The demo
uses Frame > Grid, where I use Frame > Panel > Grid. It was so obvious I did
not notice it!

It will make my life easier if I can standardise on 'style=0' for panels
throughout my app. Is there any potential downside to this?

Thanks

Frank

Robin Dunn wrote:
>
> The extra tab is being used by the panel as a navigation key.
> This is because the checkbox doesn't have something like the
> wx.TE_PROCESS_TAB
> style to ensure that it gets the key first. If you pass
style=0 to
> the wx.Panel constructor then it should work as you expect.
>

Thank you, it works perfectly.

Arghhh - I spoke too soon.

Now I find that, on MSW, I can no longer use the left/right arrow keys to
navigate the grid. Once I land on a checkbox, the arrow keys are ignored.
Tab/shift_tab work as normal. The arrow keys work fine on GTK2, even with
'style=0'.

I will continue experimenting, but I thought I should correct my previous
post asap. I will report back if I find a solution.

Frank

Robin Dunn wrote:

Frank Millman wrote:

>
> If you tab twice, it correctly moves to column 2 and then column 3.
> If you tab once, then press 'space', it correctly invokes
the editor
> and toggles the value. If you then press tab, it closes the editor,
> but stays on column 2. You have to press tab again to move
to column 3.
>

The extra tab is being used by the panel as a navigation key.
This is because the checkbox doesn't have something like the
wx.TE_PROCESS_TAB
style to ensure that it gets the key first. If you pass style=0 to
the wx.Panel constructor then it should work as you expect.

It looks as if I will have to abandon this idea, (or learn to live with
'press tab twice on MSW'), unless Robin comes up with some inspiration. It
would be a shame, as I was getting close, and it felt 'right'.

As I reported elsewhere, if I pass style=0, the checkbox no longer responds
to the arrow keys for navigation purposes.

I now realise that setting 'style=0' on a panel switches off TAB_TRAVERSAL.
This is not a practical option for a typical panel with a mixture of
controls.

I tried setting the WANTS_CHARS style on the checkbox, and adding a KEY_DOWN
event handler, but it does not generate an event for the tab key. Even if it
did, I have not figured out how to force the editor to close itself, and I
have not figured out how to tell the grid to respond as if the user has
pressed tab - there seems to be no equivalent to Navigate() for a grid.

Out of interest, why does GTK2 not have this problem?

Thanks

Frank

Frank Millman wrote:

Robin Dunn wrote:

Frank Millman wrote:

If you tab twice, it correctly moves to column 2 and then column 3.
If you tab once, then press 'space', it correctly invokes

the editor

and toggles the value. If you then press tab, it closes the editor, but stays on column 2. You have to press tab again to move

to column 3.
The extra tab is being used by the panel as a navigation key. This is because the checkbox doesn't have something like the wx.TE_PROCESS_TAB style to ensure that it gets the key first. If you pass style=0 to the wx.Panel constructor then it should work as you expect.

It looks as if I will have to abandon this idea, (or learn to live with
'press tab twice on MSW'), unless Robin comes up with some inspiration. It
would be a shame, as I was getting close, and it felt 'right'.

As I reported elsewhere, if I pass style=0, the checkbox no longer responds
to the arrow keys for navigation purposes.

I now realise that setting 'style=0' on a panel switches off TAB_TRAVERSAL.
This is not a practical option for a typical panel with a mixture of
controls.

I assume that you have other controls that appear on the same panel as the grid, and so you want to be able to do tab traversal between them, right? Is it feasible to put the grid next to the panel, instead of on it? Or perhaps the other controls could be on a sub-panel that does have the tab traversal style turned on?

I tried setting the WANTS_CHARS style on the checkbox, and adding a KEY_DOWN
event handler, but it does not generate an event for the tab key. Even if it
did, I have not figured out how to force the editor to close itself,

grid.DisableCellEditControl()

and I
have not figured out how to tell the grid to respond as if the user has
pressed tab

grid.MoveCursorRight(expandSelection)

The parameter is a boolean indicating whether the selection should be expanded with the moving cursor, so depending on what keys are being used to change the current cell you could pass event.ShiftDown() to it if you want.

Out of interest, why does GTK2 not have this problem?

Because it's not draconian about the navigation keys and always gives the key handlers first shot. wxWidgets has to jump through hoops on Windows just to give us the level of control that we have now, but even then has to use styles to turn it on in order to not break the native widgets by default. It gets pretty ugly in there.

···

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

Hi all

I think I have cracked this - fingers crossed!

To recap, I have a GridCellBoolEditor on a grid. It looks like a normal
CheckBox, but by default it does not behave like a normal CheckBox. I wanted
to be able to toggle the check box, and generate the appropriate event,
based either on a single mouse click or on the user pressing the space bar.

Attached is a program that shows the results of my efforts. As far as I can
tell it behaves like a normal CheckBox in all respects, on MSW and on GTK2.

For this to work, it is necessary to set 'style=0' on the panel that
contains the grid. This caused a problem in my live app, as this switches
off TAB_TRAVERSAL, and therefore interferes with tabbing between the other
controls on the panel.

My solution was that, instead of creating the grid as a child of the main
panel, I create a sub-panel with 'style=0', make the grid a child of the
sub-panel, and make the sub-panel a child of the main panel. It took me a
while to get the sizers sorted out, but it seems to be ok now.

Many thanks to Robin for his assistance in getting this working.

Frank Millman

fm51.py (2.74 KB)