Editing fields in a wxListCtrl

Because this question comes up periodically, I have attached a mixin that
enables any text in any column of a multi-column listctrl to be edited by
clicking on the given row and column. You close the text editor by hitting
the ENTER key or clicking somewhere else on the listctrl.

Note that I am using 2.4.x but this should work with 2.5.x. Also, this has
only been tested on Win XP, Python 2.3.3; I have no idea if it works on
*nix.

To enable the mixin to you add the following lines to the demo's
wxListCtrl.py:

1) Assuming you put the mixin in wxPython.lib.mixins then you need to add
this import

from wxPython.lib.mixins.wxListCtrlTextEdit import TextEdit

2) The Class definition for TestListCtrl is changed as follows

# add TextEdit mixin to class TestListCtrl
class TestListCtrl(wxListCtrl, wxListCtrlAutoWidthMixin, TextEdit):
    def __init__(self, parent, ID, pos=wxDefaultPosition,
                 size=wxDefaultSize, style=0):
        wxListCtrl.__init__(self, parent, ID, pos, size, style)
        wxListCtrlAutoWidthMixin.__init__(self)
        # call TextEdit __init__
        TextEdit.__init__(self)

3) In the method OnItemSelected in class TestListCtrlPanel (line ~212) add
the line:

   self.list.curRow = event.m_itemIndex

Note that the mixin requires that EVT_LIST_ITEM_SELECTED be bound to a
method that sets the listctrl's curRow attribute.

···

--------------------------------------------------

For text in columns of the ListCtrl that are left-justified the text editor
lines up pretty well with the text although you can always add some empiric
adjustment factors if you need them. In the demo, one column is right
justified so you could check for that and use a textctrl with style =
wxTE_RIGHT for right-justified columns but I didn't take the time to do
that.

And finally, if the edited text needs to be saved somewhere permanently
(like to a db) then you would need to take add the code to take care of
that.

Steve

Zatz, Steve wrote:

Because this question comes up periodically, I have attached a mixin that
enables any text in any column of a multi-column listctrl to be edited by
clicking on the given row and column. You close the text editor by hitting
the ENTER key or clicking somewhere else on the listctrl.

Great!

Note that I am using 2.4.x but this should work with 2.5.x. Also, this has
only been tested on Win XP, Python 2.3.3; I have no idea if it works on
*nix.

You need a small fix if list is in report mode with headers enabled on GTK2:
line 54:
y0 = self.GetItemPosition(row)[1]
should be: y0 = self.GetItemRect(row)[1]

It is a GTK only thing but GetItemRect behaves correctly on win32 too.

I also attached a new version which supports using tab to switch to the next column.

(wxPython-2.5.1.5, Linux/Windows)

Pim

wxListCtrlTextEdit.py (2.86 KB)

···

--
   Dr. Pim Van Heuven
   www.ThinkWize.com
Research and Development

pim@think-wize.com wrote:

You need a small fix if list is in report mode with headers enabled on GTK2:
line 54:
y0 = self.GetItemPosition(row)[1]
should be: y0 = self.GetItemRect(row)[1]

It is a GTK only thing but GetItemRect behaves correctly on win32 too.

Could you please add this to:

http://wiki.wxpython.org/index.cgi/wxPython_20Platform_20Inconsistencies

-thanks, Chris

···

--
Christopher Barker, Ph.D.
Oceanographer
                                         
NOAA/OR&R/HAZMAT (206) 526-6959 voice
7600 Sand Point Way NE (206) 526-6329 fax
Seattle, WA 98115 (206) 526-6317 main reception

Chris.Barker@noaa.gov

pim@think-wize.com wrote:

Zatz, Steve wrote:

Because this question comes up periodically, I have attached a mixin that
enables any text in any column of a multi-column listctrl to be edited by
clicking on the given row and column. You close the text editor by hitting
the ENTER key or clicking somewhere else on the listctrl.

Great!

Note that I am using 2.4.x but this should work with 2.5.x. Also, this has
only been tested on Win XP, Python 2.3.3; I have no idea if it works on
*nix.

You need a small fix if list is in report mode with headers enabled on GTK2:
line 54:
y0 = self.GetItemPosition(row)[1]
should be: y0 = self.GetItemRect(row)[1]

It is a GTK only thing but GetItemRect behaves correctly on win32 too.

I also attached a new version which supports using tab to switch to the next column.

(wxPython-2.5.1.5, Linux/Windows)

If somebody wants to convert this to use "import wx" and add some good docstrings that include how to use it, then I'll add it to the lib.

···

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

[...]

If somebody wants to convert this to use "import wx" and add some good docstrings that include how to use it, then I'll add it to the lib.

Ok, done, file attached

Pim.

wxListCtrlTextEdit.py (4.31 KB)

···

--
   Dr. Pim Van Heuven
   www.ThinkWize.com
Research and Development

I've long noticed a potential problem with double-click behavior in wxPython, at least under Windows (XP). The event is triggered on the 2nd mouse-down, which means there's an additional mouse-up waiting to be tripped. This is especially annoying when the item being double-clicked is in the system tray, where on double-click the tray icon is removed, letting the mouse-up be sent to an entirely different icon.

Is this behavior under Windows consistent with Linux and other OSes? Do you think it will be changed in future wxPython/wxWidget versions? I need to know so that if I add some code to wait for that last mouse-up, it won't break for other OSes (not for the tray but for other implementations) or when a new wx version comes out.

John Hoffman wrote:

I've long noticed a potential problem with double-click behavior in wxPython, at least under Windows (XP). The event is triggered on the 2nd mouse-down, which means there's an additional mouse-up waiting to be tripped.

I think this is pretty typical for toolkits like this.

This is especially annoying when the item being double-clicked is in the system tray, where on double-click the tray icon is removed, letting the mouse-up be sent to an entirely different icon.

An easy workaround is to use wx.CallAfter in your double-click handler
to cause the function that actually does the work to be called at the
next idle time. If the mouse ups are already queued then your worker
will be called after they are processed.

Is this behavior under Windows consistent with Linux and other OSes? Do you think it will be changed in future wxPython/wxWidget versions?

Probably not.

···

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