[gelöst]LsitCtrl "neu laden"?

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

Hallo,

das Thema ListCtrl und die damit verbundenen Schwierigkeiten lassen mich nicht mehr los.

Kennt jemand von Euch eine Möglichkeit, wie ich ein ListCtrl komplett neu laden kann, z.B. via "Aktualisieren"-Button.
Ich dachte, ich könnte das panel mit .Refresh() updaten und damit würde das ListCtrl auch neu geladen. Aber ich müsste wohl eher das Frame, in dem das ListCtrl initialisiert wird neu laden.

Ich bin für alle Ideen offen.


Hintergrund:
Die Daten für das ListCtrl (gepickelt) und die zugehörige ImageList (die Icons liegen durchnummeriert in einem extra Ordner) werden teilweise von extern modifiziert. Diese Modifikationen sollen dann in die Liste einfließen....


Any Ideas?

Gruß
Zuletzt geändert von DocFisher am Mittwoch 6. Februar 2008, 17:40, insgesamt 1-mal geändert.
Jan-Peer
User
Beiträge: 166
Registriert: Dienstag 2. Oktober 2007, 10:55

Ich habe immer irgendwo ein Dictionary, daß ich zugleich auch als itemDataMap verwende. Fürs aktualisieren (bzw. initialisieren) habe ich eine Methode, die erst alles aus dem ListCtrl entfernt ( Stichwort DeleteAllItems() ) und dann die itemDataMap nimmt und die Liste neu füllt.

Ein Event, daß zu einer Listenaktualisierung führen soll, manipuliert halt erst die itemDataMap und ruft dann die o.g. Methode auf.
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

hmm, das bringt mich auf eine Idee...
Das sortieren funktioniert auch nur bedingt, aber ich könnte natürlich die itemDataMap selbst sortieren und dann mit Deiner genannten Methode alles wieder neu Zeichnen lassen...
Wie ich es mit den passenden Icons schaffen soll, weiß ich zwar noch nicht.

Aber ein Versuch ist es wert.
Ich denke, das testen und knobeln dauert ein paar Stunden, ich melde mich dann wieder...
Erstmal Danke!
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

hmm, wie kann ich denn das ListCtrl nach dem DeleteAllItems() wieder neu laden?!?
Ich versuche mich hier an update-Funktionen, aber irgendwie wills nicht hinhauen....
Hat jemand einen Hint für mich?
Benutzeravatar
martin101986
User
Beiträge: 85
Registriert: Montag 3. Dezember 2007, 19:15
Wohnort: Steiermark, Österreich

Hallo DocFisher,

ich habe vor kurzem das gleiche Problem gehabt. Es werden dabei Namen aus einer Datenbank ausgelesen.
Ich habe das so gelöst wenn aufgrund einer Änderung eines Names oder ein Eintrag gelöscht wird dass dann die Methode zum Löschen aller Einträge aufgerufen wird und dann eine Methode mit der die Liste wieder erstellt wird. Beim öffnen der Datenbank wird auch die Methode zum erstellen der Liste aufgerufen.

Code: Alles auswählen

self.treectrl = wx.TreeCtrl(self, parent, id, pos,size)

def deletelist(self):
    self.treectrl.DeleteAllItems()

def createlist(self, data):
    root = self.treectrl.AddRoot("rootname")
    for item in data:
        self.treectrl.AppendItem(root, item)
Hoffe das hilft die weiter.

mfg
Martin
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

Hallo Martin, ich versuche das mal mit meiner ListCtrl umzusetzen. Danke für den Hinweis. Klingt genau nach dem, was ich suche.
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

!!!DANKESCHÖN!!!

Ich hab ja wie ein Idiot auf dem Schlauch gestanden......
noise
User
Beiträge: 62
Registriert: Donnerstag 7. Februar 2008, 00:15

Das löschen und wiederherstellen des kompletten list controls, nur wegen eine Änderung eines Items, kann bei sehr vielen items viel Performance kosten! Ein anderes design wäre da anzuraten, zum beispiel ein Observer-Pattern.
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

Hallo Noise,

ich hätte es auch lieber anders designed, aber da ich dieses Projekt als Einstieg in wxpthon, pthon und Programmieren überhaupt sehe, fehlen mir etliche Grundlagen.
Was zum Beispiel ist ein Observer-Pattern?!? <-- rhetorische Frage, ich werde es im Netz suchen ;-)

Aber die ListCtrl in Verbindung mit einem Item und eindeutig zugehörigem Icon bringt mich zu Verzweifelung. Wenn das Sortieren funktioniert, kann ich nur noch das jeweils letzte Element löschen, ohne dass die ImageList durcheinander kommt....
Ich versuche seit mehrern Tagen jeweils mehrere Stunden die ListCtrl im Report-Modus in den Griff zu bekommen. Aber ist ein Problem gelöst, habe ich wieder ein anderes.... Aber das kennt ihr ja sicherlich auch. Aller Anfang ist schwer.

Gruß, Doc
noise
User
Beiträge: 62
Registriert: Donnerstag 7. Februar 2008, 00:15

Hallo DocFisher,

hast du schon mal versucht, da du die Daten extern beziehst, das ganze mit einem virtual list control zu machen? RefreshItem() und RefreshItems() funktioniert nur in diesem Mode. Das wär IMO das einfachste. Sobald du deine Daten änderst und auf deinen "Aktualisieren"-Button klickst, könnte eine `RefreshItems()` eingeleitet werden, das die Virtual list veranlasst die Daten neu zu beziehen. Das schöne daran ist das der Overhead gering ist, da nur für den aktuellen ausschnitt refresht wird und ein kompliziertes Observer-Pattern würde entfallen.

Wenn du magst, kann ich dir ein Beispiel fertigmachen.

HTH
noise
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

Hey Noise, das ist super nett von Dir. Ich melde mich mal via pn....
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hallo!

Hier findest du das Beispiel für eine VirtualList aus "wxPython in Action":

http://www.python-forum.de/post-36794.html#36794

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, damit ihr sehen könnt, was ich rummurkse, habe ich mal alles notwendige in ein Ziparchiv gepackt ( es werden u.a. Icons benötigt... ).

Nur den Code zu posten, ist vermutlich unpraktisch, dann könnt ihr es nicht nachvollziehen.
Ich habe versucht, möglichst viel zu kommentieren, desweiteren steckt der Teufel wohl in der Klasse SortedListCtrl.

Ich bin für jegliche Kritik offen, auch wenn sie syntaktischer, "layouterischer" oder sonst einer Natur ist.

Heute Abend werde ich allerdings nicht mehr dazu kommen, auf evt. Post von Euch zu reagieren, das ist dann keine Ignoranz ;-)

Ihr könnt Euch das Archiv unter http://www.barndogs.de/storage/python/L ... roblem.zip herunterladen (29,7kB).

Vielen Dank für Eure Anteilnahme,

gruß Doc
noise
User
Beiträge: 62
Registriert: Donnerstag 7. Februar 2008, 00:15

Hi, hab deinen Code kurz überfolgen. Das erste was mir ausfällt ist das du alle Widgets direkt auf den Frame platzierst. Widgets gehören auf ein Panel, und darauf werden dann die Widgets platziert. Nimm es erstmal als gegeben hin, ich kann später genauer ausführen warum das so ist. Ich werde mir den Code morgen genauer anschauen und den von mir gemachten Vorschlag implementieren. Die Überarbeitung paste ich dann bei http://paste.pocoo.org/ Falls das ok ist.
noise
User
Beiträge: 62
Registriert: Donnerstag 7. Februar 2008, 00:15

Hi, habe mich doch mal "jetzt" daran gesetzt.

Hier der Code: http://paste.pocoo.org/show/26364/

Ich habe `SortedListCtrl` neu implementiert und einige Kommentare geschrieben.


1. Aktualisierungen werden übernommen, mit dem update vom popup-menü. Auch wenn Bilder geändert wurden (Hab das eben gesteste und funktionierte alles wunderbar).

2. Die Aktualisierungen deiner Datensätze von extern werden ohne weiteres auch übernommen da in `DataSource.GetItem` direkt deine Funktion `getData()` aufgerufen wird. Ich will dir aber nicht verschweigen das durch `getData()` jedesmal das picklefile ja neu eingelesen wird, und das unter Umständen einiges an Overhead kostet. Aber, ich denke bei einigen 1000 Objekten sollte das ehe nicht spürbar sein. Falls doch muss du in `DataSource` ein caching implementieren. Aber, und das ist der Punkt, das ganze ist trotzdem immer noch Performanter als bei Änderung der Daten die liste komplett zu löschen und **komplett** neu Aufzubauen, dass bei ca. 9999 Items SEHR VIEL performacne kostet. Daher denke ich das meine Methode performant genug sein sollte.

3. Die Sortierung und das löschen der Items muss du selber implementieren. Siehe auch die Kommentare dazu.


Falls du noch fragen hast, dann frage ruhig nach.

HTH
noise
DocFisher
User
Beiträge: 50
Registriert: Donnerstag 29. November 2007, 21:04
Wohnort: Berlin
Kontaktdaten:

Noise, vielen dank für die Mühe!
Ich werde mich peu-à-peu durcharbeiten und durchlesen.
Ich hatte zwischenzeitlich auf den ColumnSorterMixin verzichtet, da der immer irgendwie sortiert hat, nur nicht so, wie ich wollte.

Es wird jetzt ein bischen dauern, bis ich mich durchgearbeitet habe, aber ich werde mich sicherlich noch(mehr)mal(s) melden.

1000 Danke,

Gruß, Doc
Antworten