ListCtrl -> "Cursorposition" rausfinden/setzen

Plattformunabhängige GUIs mit wxWidgets.
Antworten
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Donnerstag 18. Dezember 2008, 11:10

Ich habe eine virtuelle Listbox, aus der der Benutzer Eintraege loeschen kann, siehe Beispielcode. Das Problem ist, wenn ich mehrere Eintraege am Ende der Liste loesche, dass dann sozusagen der "Cursor" auf inzwischen ungueltigen Listeneintraegen stehen bleibt, was zu Problemen fuehrt, wenn man mit den Pfeiltasten durch die Liste laufen will.

Code: Alles auswählen

Traceback (most recent call last):
  File "test.py", line 23, in OnGetItemText
    return self.data[item]
IndexError: list index out of range
Jetzt habe ich mir ueberlegt, in der on_delete-Methode zu pruefen, ob die Cursor-Position gueltig ist und sie dann ggf zu aendern, aber ich habe dafuer die richtige ListCtrl-Methode nicht gesehen...

Oder denke ich allgemein zu kompliziert?
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
midan23
User
Beiträge: 137
Registriert: Sonntag 21. Mai 2006, 21:41
Wohnort: Müchen
Kontaktdaten:

Donnerstag 18. Dezember 2008, 13:45

Ohne zu behaupten, mich wirklich auszukennen ;-) :
  • Versuch doch mal, das self.list.update() aus Zeile 73 direkt nach dem Löschen zu plazieren
  • In der Methode update deiner MyList-Klasse würde ich noch ein "self.Refresh()" einbauen ...
Besser wäre es allerdings, die Datenverwaltung in einer eigenen Klasse unterzubringen. Dann würde es so aussehen:
  • Benutzer wählt die Menü-Option aus
  • Ereignis wird in "on_delete" verarbeitet:
    • View: Liefert gewählten Eintrag aus
    • Model: Löscht Eintrag
    • View: Aktualisiert die Anzeige
(Zumindest mach ich es in meinem derzeitigen Projekt so ...)
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Donnerstag 18. Dezember 2008, 16:55

midan23 hat geschrieben:
  • Versuch doch mal, das self.list.update() aus Zeile 73 direkt nach dem Löschen zu plazieren
  • In der Methode update deiner MyList-Klasse würde ich noch ein "self.Refresh()" einbauen ...
Das macht alles ueberhaupt keinen Unterschied...
midan23 hat geschrieben:Besser wäre es allerdings, die Datenverwaltung in einer eigenen Klasse unterzubringen.
Das ist auch nur ein Beispiel, was mein Problem mit dem ListCtrl verdeutlicht. Die echten Daten stecken tatsaechlich in einer eigenen Klasse (welche auf eine Datenbank zugreift).
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
midan23
User
Beiträge: 137
Registriert: Sonntag 21. Mai 2006, 21:41
Wohnort: Müchen
Kontaktdaten:

Donnerstag 18. Dezember 2008, 17:22

Also, ich hab mal ein wenig mit deinem Beispiel experimentiert ...

Wenn man nur mit der Tastatur arbeitet und man das letzte Element der Liste löscht, gibts einen Fehler.

Wenn man die Methode "OnGetItemText" folgendermassen ändert:

Code: Alles auswählen

    def OnGetItemText(self, item, col):
        print len(self.data), item
        return self.data[item]
sieht man, das bei einer Länge von x auf das Element mit dem Index x zugegriffen werden soll, was zu dem Fehler führt.

Mein Verdacht ist nun, das bei einem

Code: Alles auswählen

            self.list.Select(i, on=False)
bereits auf die Liste zugegiffen wird ... nur das zu diesem Zeitpunkt zwar die Daten gelöscht wurden, aber die Länge der Liste nicht mehr aktuel ist ...

Nachdem ich die Methode "on_delete" etwas geändert hatte:

Code: Alles auswählen

    def on_delete(self, evt):
        for i in self.list.get_selection():
            print "Delete", i
            self.list.data.remove(i)
            self.list.update()
            self.list.Select(i, on=False)
        self.list.update()
trat das Problem nicht mehr auf ... zumindest nicht im Beispiel.
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Freitag 19. Dezember 2008, 10:52

Bei mir bringt das nichts.

Wenn ich zum Beispiel die letzten drei Eintraege markiere und loesche, sieht man, dass der Eintrag, auf dem man gerade mit den Pfeiltasten ist, ausserhalb der Liste liegt:

Bild

In dem Moment habe ich noch keinen IndexError (dass Select macht also keine Probleme), erst wenn ich die Pfeiltasten benutze um mich in der Liste zu bewegen, bekomme ich den. Wenn ich dann mit der Maus irgendwo in die Liste clicke, funktioniert wieder alles wie es soll.

Zumindest ist das unter Linux mit Python 2.5/wx 2.8 so...
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
midan23
User
Beiträge: 137
Registriert: Sonntag 21. Mai 2006, 21:41
Wohnort: Müchen
Kontaktdaten:

Freitag 19. Dezember 2008, 13:11

Seltsam ...

Wenn ich deinen Code ausführe, die Einträge 4, 5 und 6 über die Tastatur markiere und lösche bekomme ich bei den letzen beiden Einträgen einen IndexError.

Wenn ich in der Methode "on_delete" die Select-Zeile auskommentiere läuft die gleiche Aktion wie oben ohne Fehler.

Ach ja: Python 2.5.2 mit wxPython 2.8.9.1 unter Windows XP ...
Benutzeravatar
Rebecca
User
Beiträge: 1662
Registriert: Freitag 3. Februar 2006, 12:28
Wohnort: DN, Heimat: HB
Kontaktdaten:

Samstag 20. Dezember 2008, 14:01

Ja, unter WinXP und auch unter Wine habe ich das gleiche Verhalten wie du. Da ist nach dem Loeschen die "Cursorposition" wieder am Anfang der Liste. OK, da das Programm eh unter Windows laufen soll (und es unter Linux ja trotzem benutzbar ist), kann ich erstmal damit leben. Es sei denn es hat noch wer eine Idee?

Es scheint, dass man unter Windows allgemein mehr von der Refresh-Methode gebrauch machen muss, unter Linux geht da mehr von allein...
Offizielles Python-Tutorial (Deutsche Version)

Urheberrecht, Datenschutz, Informationsfreiheit: Piratenpartei
Antworten