Hallo Leute!
Ich versuche einen Downloadmanager zu programieren, und bin auf folgendes Problem gestoßen:
Ein Download wird bei mir durch Selektiren eines Antrages in der Liste und anschließendem Klicken Auf Button begonnen. Dabei wird an eine Download-Klasse die Position des Eintrages mit pos = self.urls.GetFocusedItem() übergeben. Soweit sogut. Dieses Download wird auch gestartet(im Bild datei "4.rar") und läuft ohne Probleme, dabei wird in regelmäßigen Abständen der Fortschritt des Downloads in die Downloaded-Spalte übergeben, dabei benutze ich folgende Anweisung: self.urls.SetStringItem(pos, 2, fortschritt), dabei ist fortschritt die übertragene Größe.
wenn ich jetzt während des Downloads ein Eintrag aus der Liste lösche(im Beispiel 3.rar) Dann ändert sich die Position des laufenden Eintrages(wird nach oben verschoben) self.urls.SetStringItem(pos, 2, fortschritt) schreibt aber weiterhin in die alte Position, auf der jetzt eine andere Datei ist(1.rar)
und jetzt die eingentliche Frage: mit welcher Anweisung kann ich die aktuelle Position meines laufenden eintrages Bestimmen?
ListCtrl Position eines Eintrages bestimmen
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo stasikz!stasikz hat geschrieben:mit welcher Anweisung kann ich die aktuelle Position meines laufenden eintrages Bestimmen?
So würde ich an die Sache heran gehen:
Code: Alles auswählen
#!/usr/bin/env python
# -*- coding: iso-8859-15 -*-
import wx
import sys
import itertools
wx.SetDefaultPyEncoding("iso-8859-15")
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)
listctrl = wx.ListCtrl(panel, style = wx.LC_REPORT)
vbox_main.Add(listctrl, 1, wx.EXPAND | wx.ALL, 5)
listctrl.InsertColumn(sys.maxint, "Spalte A")
listctrl.InsertColumn(sys.maxint, "Spalte B")
# Automatisch nummerierter Tupel :-)
counter = itertools.count()
data = (
(counter.next(), "A", "AA"),
(counter.next(), "B", "BB"),
(counter.next(), "C", "CC"),
)
for id, item1_text, item2_text in data:
item = listctrl.InsertStringItem(sys.maxint, item1_text)
print item
listctrl.SetStringItem(item, 1, item2_text)
listctrl.SetItemData(item, id)
# Reihenfolge verändern (einfach einen neuen Eintrag einfügen)
item = listctrl.InsertStringItem(0, "Hallo")
listctrl.SetStringItem(item, 1, "Welt")
listctrl.SetItemData(item, counter.next())
# Eintrag mit der ID 1 ("B") suchen
for item in xrange(listctrl.GetItemCount()):
if listctrl.GetItemData(item) == 1:
listctrl.SetStringItem(item, 1, "Gefunden")
print item
break
def main():
"""Testing"""
app = wx.PySimpleApp()
f = MyFrame()
f.Center()
f.Show()
app.MainLoop()
if __name__ == "__main__":
main()
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Danke Gerold für deine schnelle Antwort, allerdings habe ich immer noch ein Problem:
meine OnDelete Funktion:
wenn ich z.B zuerst dritten Einrtag in der Liste lösche, dann wird folgendes ausgegeben:2 (Position in der Liste)
2(id von GetItemData, zugewiesen mit counter.next())
2 (self.urls.GetFocusedItem())
wenn ich dann wieder dritten eintrag lösche, dann kommt das raus
2,3,2, was auch richtig ist, da sich die Liste nach oben verschoben hat, und auf Position 2(dritter Eintrag) der eintrag mit ID = 3 ist.
wenn ich dann aber versuche denn letzten Eintag zu löschen z.b mit ID = 7 von counter.next() zugewiesen, dann bekomme ich folgende Fehlermeldung: couldn't retrieve information about list control item 7
oder es wird folgendes ausgegeben: 5,7,5 der eintrag wird aber nicht gelöscht.
Edit: ich habe gesehen, dass Gerold in seinem Code oft sys.maxint verwendet, muss man dort nicht immer eine eindeutige Zahl eingeben, die sich dann immer ändert und als ID dient?[/code]
meine OnDelete Funktion:
Code: Alles auswählen
def OnDelete(self, event):
item = self.urls.GetFocusedItem()
print item
if item != -1:
pos = self.urls.GetItemData(item)
print pos
self.urls.DeleteItem(pos)
pos = self.urls.GetFocusedItem()
print pos
self.urls.Select(pos)
2(id von GetItemData, zugewiesen mit counter.next())
2 (self.urls.GetFocusedItem())
wenn ich dann wieder dritten eintrag lösche, dann kommt das raus
2,3,2, was auch richtig ist, da sich die Liste nach oben verschoben hat, und auf Position 2(dritter Eintrag) der eintrag mit ID = 3 ist.
wenn ich dann aber versuche denn letzten Eintag zu löschen z.b mit ID = 7 von counter.next() zugewiesen, dann bekomme ich folgende Fehlermeldung: couldn't retrieve information about list control item 7
oder es wird folgendes ausgegeben: 5,7,5 der eintrag wird aber nicht gelöscht.
Edit: ich habe gesehen, dass Gerold in seinem Code oft sys.maxint
Code: Alles auswählen
listctrl.InsertColumn(sys.maxint, "Spalte A")
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo stasikz!stasikz hat geschrieben:couldn't retrieve information about list control item 7
[...]
muss man dort nicht immer eine eindeutige Zahl eingeben, die sich dann immer ändert und als ID dient?[/code]
1.) Du musst vor jedem Zugriff die Position ermitteln, so wie ich es in Zeile 47 mache.
2.) Wenn das mit sys.maxint nicht funktionieren würde, dann hätte ich es dir nich so vorgezeigt. Beim Hinzufügen einer Zeile bekommst du eine Zahl zurück und diese Zahl zeigt die **momentane** Position des Eintrages an. Diese Position kann sich ändern. Deshalb habe ich eine eindeutige ID mit SetItemData dazu geschrieben. Bei jedem Zugriff wird zuerst jedes Element der Liste durchlaufen und nach dieser ID befragt. Wurde das Element mit der gewünschten ID gefunden, weiß man auch an welcher Position es steht und mit dieser Information kann man auf das Element zugreifen.
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
...vielleicht verstehe ich aber auch dein Problem nicht ganz. Wie auch immer. Ich habe mal das Beispiel so verändert, dass man per Mausklick einen Eintrag löschen kann.
Code: http://paste.pocoo.org/show/15834/
mfg
Gerold
Code: http://paste.pocoo.org/show/15834/
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Vielen Dank Gerold, das war genau das Problem. Ich dachte, dass man durch1.) Du musst vor jedem Zugriff die Position ermitteln, so wie ich es in Zeile 47 mache.
Code: Alles auswählen
pos = self.urls.GetItemData(item)
Außerdem hat mir deine Lösung mit dem Popup Menu sehr gefallen.
Was ich noch fragen wollte, kann es sein, dass wx.CallAfter() ziemlich langsam ist und etwa 0.1 ms braucht, um eine ziemlich einfache Funktion auszuführen? hängt die Geschwindigkeit vom Python oder allgemein vom Rechner ab oder ist der Wert 0.1 ms schon sehr gut?
- gerold
- Python-Forum Veteran
- Beiträge: 5555
- Registriert: Samstag 28. Februar 2004, 22:04
- Wohnort: Oberhofen im Inntal (Tirol)
- Kontaktdaten:
Hallo stasikz!stasikz hat geschrieben:kann es sein, dass wx.CallAfter() ziemlich langsam ist und etwa 0.1 ms braucht, um eine ziemlich einfache Funktion auszuführen
``wx.CallAfter()`` legt einen Event in die Eventwarteschlange. Wx arbeitet erst die noch anstehenden Events ab bevor ein so unwichtiges Event wie das von wx.CallAfter initiierte Event an die Reihe kommt.
Mit wx.CallAfter() kann aber am Einfachsten sicher gestellt werden, dass sich Threads nicht in die Quere kommen. Wenn du eine schnellere Reaktion brauchst, dann musst du dich selber (umständlich) um die Threadtrennung kümmern. So etwas möchte man, wenn möglich, lieber vermeiden.
mfg
Gerold
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.