[Python-de] Python QT und Listen

Ulrich Berning ulrich.berning at desys.de
Die Aug 9 10:20:27 CEST 2005


Stefan Miefert schrieb:

>
>>
>> item = None
>> for row in result:
>>    item = QListBoxText(self.listBoxMitarbeiter, 
>> row["nachname"]+","+row["vorname"], item)
>>    item.MITARBEITERID = row["MAID"]
>>
>> Alternativ könnte man QListView und QListViewItem verwenden.
>>
> Hallo,
>
> das scheint jetzt so zu funktioneiren. Wie greif ich aber später auf 
> diesen Wert zu ?
>
> Den Text erhalte ich mit
> print self.listBoxMitarbeiter.text(self.listBoxMitarbeiter.currentItem())
>       aber wie erhalte ich jetzt den neuen Wert MITARBEIETRID ?!
>
> print self.listBoxMitarbeiter.currentItem().MITARBEITERID
>
Mit allen Methoden, die ein QListBoxItem zurück liefern:

QListBoxItem * selectedItem () const
QListBoxItem * item ( int index ) const
QListBoxItem * findItem ( const QString & text, ComparisonFlags compare 
= BeginsWith ) const
QListBoxItem * itemAt ( const QPoint & p ) const
QListBoxItem * firstItem () const

Oder indem Du die Signale verwendest, die ein QListBoxItem an die 
Slot-Routine liefern:

void highlighted ( QListBoxItem * )
void selected ( QListBoxItem * )
void selectionChanged ( QListBoxItem * item )
void currentChanged ( QListBoxItem * item )
void clicked ( QListBoxItem * item )
void clicked ( QListBoxItem * item, const QPoint & pnt )
void pressed ( QListBoxItem * item )
void pressed ( QListBoxItem * item, const QPoint & pnt )
void doubleClicked ( QListBoxItem * item )
void returnPressed ( QListBoxItem * )
void rightButtonClicked ( QListBoxItem *, const QPoint & )
void rightButtonPressed ( QListBoxItem *, const QPoint & )
void mouseButtonPressed ( int button, QListBoxItem * item, const QPoint 
& pos )
void mouseButtonClicked ( int button, QListBoxItem * item, const QPoint 
& pos )
void contextMenuRequested ( QListBoxItem * item, const QPoint & pos )
void onItem ( QListBoxItem * i )

Alle Methoden oder Signale, die nur den Text des QListBoxItem liefern, 
sind nicht zu gebrauchen.
Alle Methoden oder Signale, die nur den Index des QListBoxItem liefern, 
 können zusammen mit der Methode item() verwendet werden.

Also z.B.: print 
self.listBoxMitarbeiter.item(self.listBoxMitarbeiter.currentItem()).MITARBEITERID

Meines Erachtens ist is besser, das ganze Objekt (row) im QListBoxItem 
zu referenzieren und nicht nur ein einzelnes Attribut, dann ist der 
spätere Zugriff auf alle Attribute einfacher und lesbarer:
...
item.refobj = row
...
obj = self.listBoxMitarbeiter.selectedItem().refobj
print obj["vorname"], obj["nachname"], obj["MAID"]
...

Noch lesbarer wird das ganze, wenn die Daten als Instanzen einer Klasse 
vorliegen:
...
print obj.vorname, obj.nachname, obj.MAID
...

Ich habe ein kleines funktionierendes Beispiel angehängt.


Ulli

-------------- nächster Teil --------------
#!/usr/bin/env python

import sys
from qt import *

# Diese Daten moegen das Ergebnis einer Datenbank-Abfrage sein:
result = [{"vorname": "Ulli",
           "nachname": "Berning",
           "MAID": 105},
          {"vorname": "Stefan",
           "nachname": "Miefert",
           "MAID": 104},
          {"vorname": "Otto",
           "nachname": "Meyer",
           "MAID": 103}]

# Diese Klasse nimmt die Daten eines Mitabeiters auf
class Mitarbeiter:
    def __init__(self, d):
        for key, value in d.items():
            self.__dict__[key] = value

# Erzeugen der Liste aller Mitarbeiter-Instanzen
mitarbeiter_liste = []
for row in result:
    mitarbeiter_liste.append(Mitarbeiter(row))

class MainWidget(QWidget):
    def __init__(self, parent=None, name=None):
        QWidget.__init__(self, parent, name)
        v = QVBoxLayout(self, 4, 4)
        
        self.lbm = QListBox(self)
        v.addWidget(self.lbm)        
        self.connect(self.lbm,
                     SIGNAL("selectionChanged(QListBoxItem *)"),
                     self.slotItemSelected)

        h = QHBoxLayout()
        v.addLayout(h)

        l = QLabel("Mitarbeiter:", self)
        h.addWidget(l)

        self.l = QLabel(self)
        h.addWidget(self.l)
        
        # Fuellen der ListBox
        item = None        
        for ma in mitarbeiter_liste:
            item = QListBoxText(self.lbm,
                                "%s,%s" % (ma.nachname, ma.vorname),
                                item)
            item.refobj = ma

    def slotItemSelected(self, item):
        self.l.setText("[%d] %s %s" % (item.refobj.MAID,
                                       item.refobj.vorname,
                                       item.refobj.nachname))
    
if __name__=="__main__":
    a = QApplication(sys.argv)
    QObject.connect(a, SIGNAL("lastWindowClosed()"), a, SLOT("quit()"))
    w = MainWidget()
    a.setMainWidget(w)
    w.show()
    a.exec_loop()