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