Seite 1 von 1

Model/View hierarchisch?

Verfasst: 30. März 2011 09:49
von bronko
Hallo,

ich möchte gerne die Model/View einsetzen.
Unter anderem habe ich mir das Beispiel "Editable Tree Model" angesehen und versucht zu verstehen.
Meine Anforderungen sind aber etwas anders...
Folgendes möchte ich machen:
- QTreeView zur Darstellung von hierarchischen Einträgen

- Die Daten sollen sein (Beispiel)
LEBEWESEN
MENSCH{max, tim}
TIER{hasso,wulfi, ...}
PFLANZEN
...
(alles Strings). Dabei hat jedes "Item" noch weitere unterschiedliche Attribute (z.B. Größe, Farbe, ...)
die nicht dargestellt werden sollen, wohl aber im Model sind.

- Einträge werden NICHT alle auf einmal eingefügt, sondern sollen über Methoden des Models eingefügt werden,
sodass der View sich (automatisch) aktualisieren sollte.

Wie entwerfe ich speziell das Model?
1. QAbstractItemModel notwendig obwohl es eingerückte strings sein sollen?
2. Ist es ratsam in der Model Klasse Methoden zur Verfügung zu stellen um von außen das Model mit neuen Daten zu füttern?
3. Wie soll ich diese Daten im Model speichern? Einerseitz sind sie hierarchisch andererseits sind noch weitere unsichtbare Daten vorhanden (wie oben beschrieben), die sich unterscheiden.
Muss es so wie im Beispiel mit parent/child sein? Sicher ist das das eleganteste, ist für mich nicht notwendig, aber für den View?
4. Ich kann keinen Mechanismus sehen, wo das Model dem View sagt "neuer Eintrag zum Darstellen vorhanden"?

Danke u. Gruß
Bronko

Verfasst: 30. März 2011 14:52
von bronko
Ok ich versuchs anders:
Ich nehme das Beispiel "Simple Tree Model Example".

Nun möchte ich es erweitern um eine Methode "appendItem(TreeItem *)".
Diese wird, nachdem das Model mit intialen Daten gefüttert wurde und der View diese dargestellt hat, aufgerufen (per Knopfdruck):

QList<QVariant> a;
a.append(QVariant("1234"));
TreeItem* item = new TreeItem(a);
model->appendItem(item);

Die Methode:

Code: Alles auswählen

void CodeModel::append(TreeItem* child)
{
    rootItem->appendChild(child);
    //parents.last()->appendChild(new TreeItem(columnData, parents.last()));
}
Das kompiliert zwar, stürtz aber ab. Ich habe QVariant leider auch noch nit 100%ig durchschaut.

Kann mir jemand weiterhelfen?

Verfasst: 30. März 2011 21:59
von upsala
Warum fängst du nicht mit einem QStandardItemModel an?

Verfasst: 31. März 2011 10:02
von bronko
Ja, das war ein guter Hinweis. Diese Klasse habe ich übersehen :-(

Da ich pro Eintrag in der Tabelle (hat nur eine Spalte "Name") weitere nichtsichtbare Daten habe, dachte ich mir QStandardItem abzuleiten (nach MeinItem) und dort weitere Daten angelegt (int Größe, QString Farbe, enum Gattung, ...). Desweiteren brauche ich einen Baum aller Daten, sprich in meinem Model ist ein MeinItem* welches die Wurzel ist.
MeinItem hat dann noch
private:
MeinItem* parentItem;
QList<MeinItem*> childItems;

Jetzt muß ich vermutlich data() (vom Model oder vom Item?) reimplementieren und immer den richtigen Namen zurückgeben?

Bin ich auf dem Holzweg oder wie macht man sowas?
Die Tabelle soll readonly sein, jedoch müssen bei klicks auf Felder später Aktionen folgen.

Verfasst: 31. März 2011 17:45
von padreigh
dann schubbs ich dich auch mal in ne Richtung: schau mal da http://doc.qt.nokia.com/4.7-snapshot/qs ... ml#setData dann bauste dit 10 versch userdataids und fertig ;) brauchst du nichtmal ableiten

Verfasst: 1. April 2011 08:18
von bronko
Was meinst du mit "10 verschiedene user IDs"?
Ein paar Details wären nicht schlecht...

Verfasst: 1. April 2011 08:37
von padreigh
Wer APIs liest ist klar im Vorteil:

Code: Alles auswählen

void QStandardItem::setData ( const QVariant & value, int role = Qt::UserRole + 1 )
Stell es dir als PostIts vor, die du an so ein QStandardItem dranpappst.

Code: Alles auswählen

#include <QStandardItem>
#include <QDate>
#include <QVariant>
#include <QDebug>

namespace { enum { postItDichte = Qt::UserRole + 1, postItMasse, postItVolumen, postItPreis, postItGarantie, postItWasWeissIch }; }

int main(int argc, char *argv[])
{
    QStandardItem * it = new QStandardItem("DasIstEinItem");
    {
       it->setData(QVariant(1.234  /*g/cm³*/    ), postItDichte);
       it->setData(QVariant(45      /*kg*/         ), postItMasse);
       it->setData(QVariant(45000 /* ¤ */        ), postItPreis);
       it->setData(QVariant(QDate(2012,12,15)),postItGarantie);
       it->setData(QVariant("Verstanden?")       ,postItWasWeissIch);
    }
    QVariant test0 = it->data(postItWasWeissIch);
    QVariant test1 = it->data(postItGarantie);
    QVariant test2 = it->data(postItMasse);
    QVariant test3 = it->data(postItMasse+100);
    qDebug() << test0 << test1 << test2 << test3;

    delete it;
}

Verfasst: 1. April 2011 12:20
von bronko
Natürlich lese ich die API, aber wenn man QVariant nicht verstanden hat, ist das a bisserl scheisse...
Danke für das Beispiel! Das bringt mich weiter.

Gruß
Bronko

Verfasst: 1. April 2011 12:22
von upsala
Nachdem ohne QVariant beim Qt-MVC ncihts geht würde ich diese Klasse mal ein bischen durchtesten => Kleiner Tip: Es ist eigentliche eine Kapselung von einem union.

Verfasst: 1. April 2011 14:38
von bronko
als C programmierer weiß ich ziemlich genau was eine union ist,
aber in diesem Kontext ist es schon heftig (wenn man bestimmte OOP Aspekte nicht wirklich verstanden hat, so wie ich :oops: )