QComboBox mit eigener Klasse füllen.

Alles rund um die Programmierung mit Qt
Antworten
skeemo
Beiträge: 39
Registriert: 8. Oktober 2010 09:39

QComboBox mit eigener Klasse füllen.

Beitrag von skeemo »

Hallo zusammen,

ich bin neu in QT, kenne mich aber recht gut mit andern Frameworks wie z.B. Flex oder .NET aus.

Zum "üben" habe ich ein 08/15 Widget gebaut das folgendes tut / tun soll :

- eine Combobox
- ein Button zum Hinzufügen eines Datensatzes (dazu gleich mehr)
- ein Label zum Anzeigen des in der Combobox ausgewählten Datensatzes.

Ein Datensatz besteht aus der total kreativen eigenen Klasse "Person" die über die Eigenschaften "Vorname", "Nachname" und "Alter" verfügt.

Ich zeige auf Buttondruck einen Dialog in dem ich eine neue Person anlege und übergebe die mittles eines Signals an das Widget.
Soweit so gut.
Was ich nun möchte ist, die ComboBox mit den Nachnamen (z.B.) zu füllen und bei Auswahl eines Eintrags ALLE Daten der entsprechenden Person im Label anzuzeigen.
Anscheinend kann ich aber die Einträge der Combobox NICHT direkt mit den Objekten der Klasse Person verknüpfen sondern nur mit einzelnen Strings.
Also führe ich eine QList<Person> in der die wirklichen Objekte stehen und kann mit den ComboBox - Indizes die richtigen String-Objekt Beziehungen herstellen.

Was mir nun gar nicht gefällt, ist allerdings die Tatsache, dass wenn ich die ComboBox alphabetisch sortiere (was ja per Flag möglich ist), ich die andere Liste manuell nachsortieren muss. Also bei jedem Hinzufügen.

Das finde ich sehr umständlich und unflexibel, und ich frage mich warum es keine komfortablere CollectionKlasse gibt, bzw. warum ich nicht direkt Daten an die ComboBox binden kann.

Darüberhinaus...natürlich habe ich versucht die QList manuell zu sortieren mit qSort und einer eigenen LessThan Funktion. Da habe ich mich aber irgendwie zu blöd angestellt.

Für Ideen, Hinweise, Tips wäre ich sehr dankbar.

Gruß

Chris.
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

http://doc.trolltech.com/4.6/qcombobox.html#setItemData

Damit kannst du der Combobox, für den gegebenen Index, Extradaten übergeben. Dabei wird ein QVariant gespeichert, du kannst hier also auch einen Pointer auf dein Person-Objekt speichern (wie man einen Pointer in QVariant speichert -> google selbiges, 1. oder 2. Treffer dürfte eine gute Anleitung bereit halten).
skeemo
Beiträge: 39
Registriert: 8. Oktober 2010 09:39

Beitrag von skeemo »

Hm das ist ne gute Idee.
QVariant habe ich schon im Zusammenhang mit der Combobox gesehen. Das kann man auch direkt beim Eintrag-adden mitgeben, eider konnte ich (natürlich) nicht direkt meinen eigenen Datentyp anhängen.

Ich werds dann mal so wie hier versuchen:
http://www.pronix.de/comment/site-963/o ... ite-1.html

ps. Das finde ich aber schon insgesamt etwas umständlich.


Danke für die Hilfe.

Weitere Vorschläge sind natürlich immer noch willkommen ;)[/url]
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag von solarix »

Pointer zu qulonglong? Wie bekloppt ist das denn..

Ich würde den in der Doku vorgeschlagenen Weg bevorzugen:

Code: Alles auswählen

MyClass *i = ...
QVariant v = qVariantFromValue<void*>(i);

...
MyClass *i2 =  (MyClass*)qVariantValue<void*>(v); // allenfalls noch mit hübscherem cast (static)

hth..
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Wie speicherst du die Datensätze? QList<Person> ?
Dann pack doch einfach die Position in der QList per setItemData(comboboxindex, QVariant(personenlistenposition), Qt::UserRole ) mit in die Combobox .... solange du nicht in der Liste rumsortierst kannst du mit der Combobox machen was du willst ... willst du den passenden Datensatz wissen reicht ein einfaches personenliste.at(QComboBox::itemData ( currentIndexDerComboBox, Qt::UserRole ).toInt()) . Nix rumpointern. Wenn du die Reihenfolge der Liste änderst, musst du die Combobox neu füllen ... aber solange du nicht den Datencontainer durcheinanderbringst sollte das tun ...

Code: Alles auswählen

QComboBox.clear(); 
for(int i=0;i<personenliste.size();++i) 
{ 
  QComboBox.insert(i,personenliste.at(i).name(),QVariant(i));
}
um sie neu zu füllen...
Zuletzt geändert von padreigh am 8. Oktober 2010 16:00, insgesamt 1-mal geändert.
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
pfid
Beiträge: 535
Registriert: 22. Februar 2008 16:59

Beitrag von pfid »

Mit rumpointern ist die Zeile in der Box aber direkt einem Objekt zugeordnet, und unabhängig von allen anderen Listen, Indices etc. .
skeemo
Beiträge: 39
Registriert: 8. Oktober 2010 09:39

Beitrag von skeemo »

..und genau das ist mein Gedanke. Ich will nicht, dass einfach lose Strings in der Combobox Liste stehen, sondern sich jeder Eintrag direkt einem Objekt zuordnen lässt.

Ich bin halt die komfortablen Data-Bindings aus Flex gewohnt. Mir ist schon klar, dass dort im Grunde auch nichts gross anderes unter der Oberfläche passiert...

@Solarix

Danke das werde ich mal probieren...


ps. Schön, mal in einem Forum auch wirklich Hilfe zu bekommen :)
skeemo
Beiträge: 39
Registriert: 8. Oktober 2010 09:39

Beitrag von skeemo »

So es funktioniert jetzt :)

Falls jemand den Code sehen möchte:

Code: Alles auswählen

// Slot
void MainWindow::createdPerson(Person *p)
{
    QVariant variant = qVariantFromValue<void*>(p);
    personList->addItem(p->nachname(),variant);
    createDlg->clean();
    createDlg->close();
}
.
.
.
// Slot von der Combobox
void MainWindow::personSelected(int index)
{    
    QVariant variant = personList->itemData(index);
    Person *selectedPerson = (Person*)qVariantValue<void*>(variant);
    
    //...Daten anzeigen usw. 
   
}

Zuletzt geändert von skeemo am 8. Oktober 2010 17:53, insgesamt 1-mal geändert.
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Die Lösung von padreigh ist der normale Weg abgesehen von der Tatsache dass die Infos aus einer DB kommen und demnach über eine eindeutige ID anstatt die Listen-Index bestimmt werden.
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
Antworten