ListCtrl sortieren

Plattformunabhängige GUIs mit wxWidgets.
Antworten
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

Hallo,
ich will Euch nicht nerven, aber ich stehe schon wieder auf dem Schlauch...
Ich habe eine ListCtrl im Report_Modus. Diese sortiere ich mit Mixin. Allerdings verstehe ich die Sortierweise von Mixin nicht ganz.
Hier der Beispielcode:

Code: Alles auswählen

    def createList(self):
        # die mir noch etwas undurchsichtige Liste.....
        il = wx.ImageList(26,26, False)
        Bilderliste = glob.glob("./icons/e_icon*.png")
        Bilderliste.sort()
        for name in Bilderliste:
            bmp = wx.Bitmap(name, wx.BITMAP_TYPE_PNG)
            il_max = il.Add(bmp)
        self.up = il.AddWithColourMask(wx.Bitmap("./icons/sm_up.bmp", wx.BITMAP_TYPE_BMP), "blue")
        self.dn = il.AddWithColourMask(wx.Bitmap("./icons/sm_down.bmp", wx.BITMAP_TYPE_BMP), "blue")
        self.list_ctrl_uebersicht.AssignImageList(il, wx.IMAGE_LIST_SMALL)
        
        for col, text in enumerate(dataColumns):
            self.list_ctrl_uebersicht.InsertColumn(col, text, format=wx.LIST_FORMAT_CENTER)
        self.itemDataMap = {}
        for item in dataRows:
            index = self.list_ctrl_uebersicht.InsertStringItem(sys.maxint, item[0])
            for col, text in enumerate(item[1:]):
                self.list_ctrl_uebersicht.SetStringItem(index, col+1, text)
            self.list_ctrl_uebersicht.SetItemData(index, index)
            self.itemDataMap[index] = item
            img = index
            print index
            self.list_ctrl_uebersicht.SetItemImage(index, img, img)
Leider funktioniert es nicht wie erhofft.
Meine Columns enthalten folgendes:
1. Name, 2.Datum 1 (als String im Format Jahr-Monat-Tag) 3. Datum 2 (selbes Format), 4. Preis (auch als String, z.B.: 13,55 €)
Beim sortieren kommt aber nur Quark heraus. Ich vermute, es liegt an meiner "itemDataMap", aber ehrlich gesagt, habe ich diese auch nicht wirklich verstanden.
Kann mir jemand einen Tipp geben, wie ich es schaffe dass:
-die Namen alphabetisch sortiert werden (Namen sind teilweise unterschiedlich lange Strings)
-die Datumsangaben auf- oder absteigend sortiert werden, und
- man ebenfalls nach Preis sortieren kann( 12 € > 1 € > -1 € > -12 €)

ich vermute, dass ich zwecks richtigem Preissortieren von den Strings weg muss, oder? Ich hätte eben gerne das €-Zeichen dabei.

Gruß, Doc
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo DocFisher!

Meist ist es die einfachste Lösung, die Daten vorher in einer Liste zu sortieren und dann erst in das ListCtrl zu schreiben.

mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

Hallo Gerold,
ich habe die Date in einer Liste, die ich "gepickelt" habe. Was ich erreichen will, ist, dass man diese Liste z.B. nach dem Datum sortiert um schnell eine Monatsübersicht zu bekommen. Oder aber nach dem Punkt "Bilanz"(habe ich oben nicht erwähnt), damit ich sehen kann, wo ich zuviel Geld gelassen habe...

Diese Liste will ich nicht verändern, da ich über den Listenindex auch das Icon in der ImageList wähle.

Irgendwie erscheint mir das ganze sehr "verhuddelt", aber ich bin bisher auf keine Möglichkeit gestossen, ein Icon an ein Listenelemnt zu "binden", außer der Verwendung des Listenindex, der bei passender Namensgebung der Icon-Dateien (durchnummeriert 0001, 0002 etc.) das passende Icon aus der ImageList "wählt".

Ich habe langsam das Gefühl, das ganze Projekt ist doch etwas zu groß für mich. Aber ich versuche daran zu lernen... Mal sehen, ob es was wird.
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

DocFisher hat geschrieben:dass man diese Liste z.B. nach dem Datum sortiert um schnell eine Monatsübersicht zu bekommen. Oder aber nach dem Punkt "Bilanz", damit ich sehen kann, wo ich zuviel Geld gelassen habe...
Hallo DocFisher!

Das hier ist ein Minimalbeispiel für ein *ColumnSorterMixin*-ListCtrl. Die Daten müssen in einem Dictionary in der gezeigten Form vorliegen und an ``self.itemDataMap`` gebunden werden. Weiters muss es die Methode *self.GetListCtrl* geben und der Dictionary-Daten-Key muss mit *SetItemData* gesetzt werden.

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
"""Sorted ListCtrl"""

import wx
import wx.lib.mixins.listctrl as listmix
import datetime
import sys

wx.SetDefaultPyEncoding("iso-8859-15")


class SortedListCtrl(wx.ListCtrl, listmix.ColumnSorterMixin):
    
    def __init__(self, parent):
        wx.ListCtrl.__init__(self, parent, style = wx.LC_REPORT)
        
        # Daten mit ID (sortierbare Rohdaten -- keine Strings)
        self.data = {
            0: ("A", 1, datetime.date(2000, 10, 15)),
            1: ("X", 50, datetime.date(1960, 1, 5)),
            2: ("B", 599, datetime.date(3020, 5, 1)),
            3: ("U", 5, datetime.date(1970, 11, 30)),
            4: ("I", 8, datetime.date(2007, 6, 20)),
        }
        self.itemDataMap = self.data
        
        # Spaltenüberschriften
        self.InsertColumn(sys.maxint, "Buchstabe")
        self.InsertColumn(sys.maxint, "Zahl")
        self.InsertColumn(sys.maxint, "Datum")
        
        # Daten in ListCtrl schreiben
        for key in sorted(self.data.keys()):
            char_value, number_value, date_value = self.data[key]
            index = self.InsertStringItem(sys.maxint, char_value)
            self.SetItemData(index, key) #muss sein
            self.SetStringItem(index, 1, str(number_value))
            self.SetStringItem(index, 2, date_value.strftime("%d.%m.%Y"))
            self.SetColumnWidth(2, wx.LIST_AUTOSIZE)
        
        listmix.ColumnSorterMixin.__init__(self, numColumns = 3)
    
    
    def GetListCtrl(self):
        return self
    

class MyFrame(wx.Frame):
    
    def __init__(
        self, parent = None, title = "Example", size = wx.Size(550, 420)
    ):
        wx.Frame.__init__(self, parent, -1, title, size = size)
        
        panel = wx.Panel(self)
        
        vbox_main = wx.BoxSizer(wx.VERTICAL)
        panel.SetSizer(vbox_main)
        
        my_list = SortedListCtrl(panel)
        vbox_main.Add(my_list, 1, wx.EXPAND | wx.ALL, 10)


def main():
    """Testing"""
    app = wx.PySimpleApp()
    f = MyFrame()
    f.Center()
    f.Show()
    app.MainLoop()


if __name__ == "__main__":
    main()
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

Vielen Dank Gerold!

Ich versuche, Dein Beispiel bei mir zu implementieren.
Ich gebe Bescheid, ob es geklappt hat.
Antworten