Seite 1 von 1

Dictionary mit Keys vom Typ QDate auslesen

Verfasst: Dienstag 29. Juni 2010, 20:34
von EmaNymton
Hallo zusammen,
ich möchte gerne Fehlstunden von Schülern in einem dictionary verwalten, dass als keys das jeweilige Datum von Typ QDate enthält. Das ist soweit auch kein Problem, bei der Eingabe von den Fehlstunden werden diese in dem dictionary Fehlstunden gespeichert. Lasse ich mir das ganze z.B. für einen Schüler ausgeben, sieht es so aus:

Code: Alles auswählen

{PyQt4.QtCore.QDate(2010, 7, 31): 0, PyQt4.QtCore.QDate(2010, 7, 30): 1, PyQt4.QtCore.QDate(2010, 7, 27): 0}
Das sieht für mich eigentlich ok aus.

Mit folgendem Quelltext möchte ich die Schüler in einem QListWidget anzeigen lassen, um die Fehlstunden entschuldigen zu können.

Code: Alles auswählen

def fehlstundenAnzeigen(self):
	self.listWidget.clear()	
	for schueler in self.kurs.Teilnehmer:
		if self.datum in schueler.Fehlstunden:
			item = QtGui.QListWidgetItem()
			item.setText(schueler.Vorname + ' ' + schueler.Name)
			item.setFlags(QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsUserCheckable)
			if schueler.istFehlstundeEntschuldigt(self.datum):
			   item.setCheckState(QtCore.Qt.Checked)
			else:
			   item.setCheckState(QtCore.Qt.Unchecked)
			self.listWidget.addItem(item)
self.datum ist dabei das ausgewählte Datum eines QCalendarWidget, also auch vom Typ QDate.

Die if-Abfrage wird aber überhaupt nicht durchlaufen. Wenn ich self.datum in schueler.Fehlstunden.keys() überprüfe durchläuft er die if-Abfrage, meckert allerdings dann beim Aufruf der Methode istFehlstundeEntschuldigt über einen KeyError:

Code: Alles auswählen

KeyError: PyQt4.QtCore.QDate(2010, 7, 31)
Die Methode istFehlstundeEntschuldigt in der Klasse Schueler sieht so aus:

Code: Alles auswählen

def istFehlstundeEntschuldigt(self,datum):
		if self.Fehlstunden[datum]==1:
			return True
		else:
			return False
Ich steh irgendwie aufm Schlauch und bitte um Hilfe!
Gruß EmaNymton

Re: Dictionary mit Keys vom Typ QDate auslesen

Verfasst: Dienstag 29. Juni 2010, 22:11
von BlackJack
@EmaNymton: `QDate` kann man nicht als Schlüssel in Dictionaries verwenden. Die `__hash__()`-Methode ist dafür anscheinend falsch implementiert:

Code: Alles auswählen

from PyQt4.QtCore import QDate

a = QDate(2010, 7, 31)
b = QDate(2010, 7, 31)

print a == b, hash(a) == hash(b)
Ergibt:

Code: Alles auswählen

True False
Gleiche Objekte die einen unterschiedlichen Hash-Wert ergeben sind irgendwie kaputt.

Die letzte Methode ist übrigens umständlicher formuliert als es sein müsste, denn der Ausdruck beim ``if`` wird ja schon zu einem Wahrheitswert ausgewertet:

Code: Alles auswählen

def ist_fehlstunde_entschuldigt(self, datum):
    return self.fehlstunden[datum] == 1
Nachtrag: Ich hoffe in dem Dictionary wird zu jedem Datum die Anzahl der Fehlstunden gespeichert und nicht 0 und 1 als Wahrheitswerte missbraucht.

Re: Dictionary mit Keys vom Typ QDate auslesen

Verfasst: Dienstag 29. Juni 2010, 22:57
von jerch
Du kannst QDate ja eine hash-Methode anhand des Datums unterschieben:

Code: Alles auswählen

>>> from PyQt4.QtCore import QDate
>>> d={}
>>> d[QDate(2007, 1, 1)]=0
>>> QDate(2007, 1, 1) in d
False
>>> d[QDate(2007, 1, 1)]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
KeyError: PyQt4.QtCore.QDate(2007, 1, 1)
>>> class MyDate(QDate):
...   def __hash__(self):
...     return self.day()+self.month()*100+self.year()*10000 # oder self.toPyDate().__hash__()
...
>>> d[MyDate(2007, 1, 1)]=0
>>> MyDate(2007, 1, 1) in d
True
>>> d[MyDate(2007, 1, 1)]
0
>>> hash(MyDate(2007, 1, 1))
20070101

Re: Dictionary mit Keys vom Typ QDate auslesen

Verfasst: Mittwoch 30. Juni 2010, 09:40
von lunar
Mit der API-Version 2 ist __hash__ für QDate korrekt implementiert. Diese Version ist Standard unter Python 3, für Python 2 muss sie explizit aktiviert werden:

Code: Alles auswählen

import sip
sip.setapi('QDate' 2)
Mehr dazu in der Dokumentation. Das Ganze funktioniert iirc seit PyQt 4.6.

Re: Dictionary mit Keys vom Typ QDate auslesen

Verfasst: Mittwoch 30. Juni 2010, 13:47
von EmaNymton
Vielen Dank an alle drei, mit lunars Hinweis funktionierts jetzt, es fehlte allerdings ein Komma ;)

Code: Alles auswählen

import sip
sip.setapi('QDate', 2)
Vielleicht war der Fehler auch absichtlich drin, damit ich nochmal in die Doku reinschaue ;)
Nachtrag: Ich hoffe in dem Dictionary wird zu jedem Datum die Anzahl der Fehlstunden gespeichert und nicht 0 und 1 als Wahrheitswerte missbraucht.
Öhm, natürlich nicht ;)
Ich weiß, dass das nicht sauber ist. Ist ne dumme Angewohnheit von mir, habe ich aber jetzt berichtigt und gelobe Besserung. ;)

Re: Dictionary mit Keys vom Typ QDate auslesen

Verfasst: Mittwoch 30. Juni 2010, 16:01
von lunar
@EmaNymton: Oh, verzeih mir den Fehler, das war natürlich keine Absicht :)