Duda con wxpython mixins.listctrl

Oswaldo Hernández listas en soft-com.es
Mar Nov 3 16:38:27 CET 2009


Israel Santana Alemán escribió:
> Buenas tardes,
> 
> Este es mi primer correo a la lista, me presento mi nombre es Israel y tengo
> conocimiento (muy) básicos sobre python.
> 

Hola israel, bienvenido al mundo de Python y de wxPython.

> Me estaba adentrando en wxpython, y tengo un pequeño problema.
> 
> Tengo una listado de tipo mixins.listctrl y dibujo la lista, la cosa viene
> cuando edito la lista desde la venta gráfica y quiero que se ordene por lo
> valores nuevos, entiendo que en el ejemplo que envio, se hace por un
> diccionario que ya he creado anteriormente, pero como puedo hacerlo de forma
> que cada vez que modifique un dato se modifique el diccionario, o de la
> forma que sea más correcta.
> 
> Muchas gracias
> 
> <codigo>
> #!/usr/bin/python
> 
> # sorted.py
> 
> import wx
> import sys
> from wx.lib.mixins.listctrl import ColumnSorterMixin
> from wx.lib.mixins.listctrl import TextEditMixin
> 
> actresses = {
> 1 : ('jessica alba', 'pomona', '1981'),
> 2 : ('sigourney weaver', 'new york', '1949'),
> 3 : ('angelina jolie', 'los angeles', '1975'),
> 4 : ('natalie portman', 'jerusalem', '1981'),
> 5 : ('rachel weiss', 'london', '1971'),
> 6 : ('scarlett johansson', 'new york', '1984')
> }
> 
> 
> class SortedListCtrl(wx.ListCtrl, ColumnSorterMixin, TextEditMixin):
>     def __init__(self, parent):
>         wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT)
>         TextEditMixin.__init__(self)
>         ColumnSorterMixin.__init__(
> self, wx.LC_SORT_ASCENDING|wx.LC_VIRTUAL)
>         self.itemDataMap = actresses
> 
>     def GetListCtrl(self):
>         return self
> 
> class Actresses(wx.Frame):
>     def __init__(self, parent, id, title):
>         wx.Frame.__init__(self, parent, id, title, size=(380, 230))
> 
>         hbox = wx.BoxSizer(wx.HORIZONTAL)
> 
>         panel = wx.Panel(self, -1)
> 
>         self.list = SortedListCtrl(panel)
>         self.list.InsertColumn(0, 'name', width=140)
>         self.list.InsertColumn(1, 'place', width=130)
>         self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)
> 
>         items = actresses.items()
> 
>         for key, data in items:
>             index = self.list.InsertStringItem(sys.maxint, data[0])
>             self.list.SetStringItem(index, 1, data[1])
>             self.list.SetStringItem(index, 2, data[2])
>             self.list.SetItemData(index, key)
> 
>         hbox.Add(self.list, 1, wx.EXPAND)
>         panel.SetSizer(hbox)
> 
>         self.Centre()
>         self.Show(True)
> 
> app = wx.App()
> Actresses(None, -1, 'actresses')
> app.MainLoop()
> </codigo>
> 

Tienes varios problemas en el código:

- ColumnSorterMixin esta mal iniciado, el 2º parametro debe ser el número de columnas.
- wx.LC_VIRTUAL es un parámetro de estilo de ListCtrl, no de ColumnSorterMixin.
- Caundo se usa el modo LC_VIRTUAL no se cargan directamente los datos en el listctrl, sino que hay 
que sobreescribir el método 'OnGetItemText' para que provea de datos al listctrl.
- Al utilizar TextEditMixin para editar datos, debes proveerlos en formato lista en vez de tupla.

Este es el codigo modificado y comentado para que veas el funcionamiento:

<code>
#!/usr/bin/python
#coding=utf-8

import wx
from wx.lib.mixins.listctrl import ColumnSorterMixin
from wx.lib.mixins.listctrl import TextEditMixin
from wx.lib.mixins.listctrl import ListCtrlAutoWidthMixin

actresses = {
1 : ['jessica alba', 'pomona', '1981'],
2 : ['sigourney weaver', 'new york', '1949'],
3 : ['angelina jolie', 'los angeles', '1975'],
4 : ['natalie portman', 'jerusalem', '1981'],
5 : ['rachel weiss', 'london', '1971'],
6 : ['scarlett johansson', 'new york', '1984']
}


class SortedListCtrl(wx.ListCtrl,
             ColumnSorterMixin,
             ListCtrlAutoWidthMixin,
             TextEditMixin):

     def __init__(self, parent):
         wx.ListCtrl.__init__(self, parent, -1, style=wx.LC_REPORT|wx.LC_VIRTUAL)
         ColumnSorterMixin.__init__(self, -1)
         ListCtrlAutoWidthMixin.__init__(self)
         TextEditMixin.__init__(self)

     def GetListCtrl(self):
         return self

     def OnGetItemText(self, item, col):
         # Lee el valor a mostrar en mddo LC_VIRTUAL desde el diccionario de datos
         return self.itemDataMap[self.itemIndexMap[item]][col]

     def SetVirtualData(self, item, col, text):
         # Guarda el valor editado al diccionario de datos
         self.itemDataMap[self.itemIndexMap[item]][col] = text

     def SortItems(self,sorter=cmp):
         # Ajusta el indice de columnas al nuevo ordenamiento
         items = list(self.itemDataMap.keys())
         items.sort(sorter)
         self.itemIndexMap = items
         self.Refresh()


class Actresses(wx.Frame):
     def __init__(self, parent, id, title):
         wx.Frame.__init__(self, parent, id, title, size=(380, 230))

         hbox = wx.BoxSizer(wx.HORIZONTAL)

         panel = wx.Panel(self, -1)

         self.list = SortedListCtrl(panel)

         # Definicion de Columnas ListCtrl
         self.list.InsertColumn(0, 'name', width=140)
         self.list.InsertColumn(1, 'place', width=130)
         self.list.InsertColumn(2, 'year', wx.LIST_FORMAT_RIGHT, 90)

         # Nº de lineas para el modo LC_VIRTUAL
         self.list.SetItemCount(len(actresses))

         # Valores para ColumnSorterMixin
         self.list.itemDataMap = actresses
         self.list.itemIndexMap = actresses.keys()
         self.list.SetColumnCount(self.list.GetColumnCount())
         self.list.SortListItems(0, 1)

         hbox.Add(self.list, 1, wx.EXPAND)
         panel.SetSizer(hbox)

         self.Centre()

app = wx.PySimpleApp()
Actresses(None, -1, 'actresses').Show(True)
app.MainLoop()

</code>


Saludos,

-- 
*****************************************
Oswaldo Hernández
oswaldo (@) soft-com (.) es
*****************************************
PD:
Antes de imprimir este mensaje, asegúrese de que es necesario.
El medio ambiente está en nuestra mano.
_______________________________________________
Lista de correo Python-es 
http://listas.aditel.org/listinfo/python-es
FAQ: http://listas.aditel.org/faqpyes





Más información sobre la lista de distribución Python-es