QAbstractItemModel/TreeView zeigt nichts an

Alles rund um die Programmierung mit Qt
Antworten
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

QAbstractItemModel/TreeView zeigt nichts an

Beitrag von phlox81 »

Hallo,

versuche mich gerade an einer ersten Modelklasse in Qt, ich will einen Dokumentenbaum darstellen, alles eigentlich relativ einfach gestrickt.

Orientieren tue ich mich hierbei an diesem Beispiel:
http://doc.qt.nokia.com/4.6/itemviews-s ... model.html

Jedoch, jetzt wo alles implementiert ist, bleibt der TreeView leer.

Mein Code:

Code: Alles auswählen

DocumentTreeModel::DocumentTreeModel(QObject *parent) :
    QAbstractItemModel(parent)
{
//doc ist die Wurzel des Baumes
    doc = new DocRoot("Root");
}


QModelIndex DocumentTreeModel::index(int row, int column, const QModelIndex &parent) const
 {
    if (!hasIndex(row, column, parent))
        return QModelIndex();
    DocRoot* p = 0;
    if(parent.isValid())
        p = static_cast<DocRoot*>(parent.internalPointer());
    else
        p = doc;
    DocRoot* childItem= p->getByIndex(row);// entweder 0 oder ein DocRoot aus dem Container

    if (childItem)
        return createIndex(row, column, childItem);
    else
        return QModelIndex();
 }

QModelIndex DocumentTreeModel::parent(const QModelIndex &index) const
 {
    if (!index.isValid())
     return QModelIndex();
    DocRoot* p = static_cast<DocRoot*>(index.internalPointer());
    DocRoot* par = p->getParent();
    if(!par || par ==doc)
        return QModelIndex();
    return createIndex(par->row(), 0, par);
 }

int DocumentTreeModel::rowCount(const QModelIndex &parent) const
 {
     if (parent.column() > 0)
         return 0;
     if (!parent.isValid())
         return doc->count();
     return 2;
 }

int DocumentTreeModel::columnCount(const QModelIndex &parent) const
 {
     return 1;
 }

QVariant DocumentTreeModel::data(const QModelIndex &index, int role) const
 {
     if (!index.isValid())
         return QVariant();
     if (role != Qt::DisplayRole)
         return QVariant();
    DocRoot* p = static_cast<DocRoot*>(index.internalPointer());
    if(p && p != doc)
        return QVariant(p->getText());
    return QVariant();
 }

Qt::ItemFlags DocumentTreeModel::flags(const QModelIndex &index) const

void DocumentTreeModel::update()
{
    emit dataChanged(createIndex(0,0,doc->getByIndex(0)),createIndex(doc->count()-1,0,doc->getByIndex(doc->count()-1)));
}
Da gibt es keine großen Unterschiede zu dem Qt Beispiel, getText gibt ein QString zurück, ich weiss nicht, ob QVariant(p->getText()); Evtl. fehl schlägt oder hier nicht korrekte Daten liefert.

Wo anders fülle ich dies dann mit Daten:

Code: Alles auswählen

Document::t_form* form = new Document::t_form;
        form->first = str;
        DocRoot* root = new TreeModelProxy<Document::t_form>(form,str);
        root->addNode(new TreeModelProxy<DiagramScene>(form->second.second,"Landscape"));
        root->addNode(new TreeModelProxy<DiagramScene>(form->second.first,"Portrait"));
        //DocRoot* p = root->getByIndex(0)->getParent();
        doctree.addNode(root);
        doctree.update();
        //ui->treeView->setModel(&doctree);
Insgesamt sieht das alles für mich korrekt aus, aber ich verstehe nicht, warum nichts angezeigt wird...
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Hilfe zur Selbsthilfe:

Beitrag von padreigh »

Code: Alles auswählen

#include <QtDebug>

QVariant DocumentTreeModel::data(const QModelIndex &index, int role) const
 {
     if (!index.isValid())
         return QVariant();
     if (role != Qt::DisplayRole)
         return QVariant();
    DocRoot* p = static_cast<DocRoot*>(index.internalPointer());
    if(p && p != doc)
    {
        qDebug() << p->getText(); // <-----------------------------
        return QVariant(p->getText());
    }
    return QVariant();
 }
Das sollte dir über den Inhalt von p Klarheit verschaffen ... wenn da was ausgegeben wird musst du anderswo Suchen .
Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

Also in Data geht er erst garnicht rein.

Habe jetzt in parent und index sowie rowcount qdebug dazu getan:
Parent
rowCount 1
index
index "test"
Ist dann die Ausgabe nach dem Einfügen eines ersteb elementes.
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag von upsala »

Könnte es sein, daß du ein Problem mit der Lebensdauer deines Models hast?
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

Das ist eine Variable im MainWindow :)
Also eher nicht. Fenster existiert ja.

Nochmal die Ausgabe von qDebug():
Parent
rowCount 1
index "test"
Das ist nach dem einfügen und update() aufruf.
Er geht in den ersten also hinein, bekommt dafür auch ein QModelIndex.
Jetzt frage ich mich, ob es evtl. am View liegt, muss ich da irgend ein flag setzen, das er auch dass korrekt anzeigt?
Das Model macht einen ganz korrekten eindruck, es wäre ja nur die erste Ebene Sichtbar.

Wenn ich was weiteres hinzufüge, wird allerdings nur noch Parent aufgerufen...
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

Habe jetzt das ganze mal als Testprojekt zusammengehackt.
Unter http://codenode.de/TreeModel.zip kann man es sich runterladen.
Oder hier als Attachment.

Hab da keine Ahnung mehr, wieso das nicht klappt. Zu dem genannten Beispielprojekt gibt es keinen großen Unterschied...
Dateianhänge
TreeModel.zip
TestProjekt fürs Model
(11.72 KiB) 178-mal heruntergeladen
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

Niemand eine Idee?
Habe schon fast alles versucht, aber es bleibt ein Rätsel warum er nix anzeigt...
franzf
Beiträge: 3114
Registriert: 31. Mai 2006 11:15

Beitrag von franzf »

Du solltest unbedingt die DisplayRole abfragen... Warum hast du den Teil auskommentiert, und vorher eine QVariant::String zurückgegeben? Du willst nur bei DisplayRole etwas zurückgeben, ansonsten einen nicht-validen QVariant (quasi "no data").
Wenn ich das einfüge

Code: Alles auswählen

    if (role != Qt::DisplayRole)
        return QVariant();
Bekomme ich Daten im TreeView. Ich hab aber so auch noch einiges rumgedoktort, kann also sein, dass noch anderswo Änderungen nötig sind, einfach nochmal nachfragen.
Solltest du auch noch eine Icon (DecorationRole) oder andere Sachen wie Textfarbe setzen können wollen, musst du entsprechende Roles abfragen.
Ansonsten ist dein "columnCount" noch fehlerhaft (hint: DocRoot::count() gibt dir die Anzahl der Kinder).

Dein update() funktioniert auch noch nicht so recht, mal schauen ob wir das noch hinbekommen.
padreigh
Beiträge: 340
Registriert: 13. Mai 2010 10:06

Beitrag von padreigh »

Patrick (QtCreator 1.3.1, Qt 4.6.3)
---
template = subdirs
phlox81
Beiträge: 97
Registriert: 7. Juli 2009 12:30
Kontaktdaten:

Beitrag von phlox81 »

Danke für die Hilfe, bei mir funktionierts jetzt auch, muss noch schauen wo ich dinge ändern muss.
Und vorallem woran es jetzt lag. Das beginInsertRows scheint nicht unwichtig zu sein.

Allerdings wird nun das letzte Element nicht korrekt gezeichnet, es sieht so aus als hänge darunter noch ein Knoten.
Antworten