QT Customdraw in QTreeWidget



  • Hallo,

    zuerst einmal: Ich bin total neu in QT. Die "Einsteigertutorials" habe ich zwar durch, aber mir fehlt es enorm an Grundlagen.

    Mein Problem ist, dass ich derzeit ein Projekt (Delphi) nach C++ (mit QT) portieren möchte. Generell ist natürlich alles neu aber ich stehe gerade vor einem riesengroßen Problem. Und zwar:

    Kleine Vorabinformationen, die hilfreich sind, aber nicht zwingend notwendig zu lesen:

    Ich hatte in Delphi ein TListView mit Viewstyle := vsReport und ein paar Collumns. Dort werden Daten, die eine andere Klasse zur Verfügung steht (Format TList<TMeinDatenTyp>) angezeigt. Jedem Item wird ein Icon zugeordnet, welches durch mein Programm dynamisch in eine TImageList geladen wurde (Icons liegen in Unterordner der Anwendung). Einige Spalten habe ich selbst gezeichnet und zwar diese, die einen Preis beinhalten (http://www.gw2spidy.com/assets/v20150522v1/img/crafting.png <--- Beispiel).

    So nun meine (warscheinlich dummen) Anfängerfragen:

    1. Welche Komponente benutze ich. Meine Recherchen fanden das TreeWidget, aber sicher bin ich mir nicht. Vor allem weiß ich auch nicht, ob ich Modelbased oder Itembased nehmen sollte, auch weil ich keine Ahnung hab, wie ich das alles umsetze.

    2. Wie füge ich der Liste (die ich bei 1. dann gewählt habe) effektiv Items hinzu?

    3. Wie weiße ich einzelnen Items die Icons zu und in welche Struktur kann ich diese laden?

    4. Wie kann ich einzelne Spalten selbst zeichen (so wie in dem Link oben)? Die Icons für die "Geldstücke" sind in den Ressourcen der Anwendung

    Ich bedanke mich schonmal herzlich an den/diejenigen, die sich hier die Mühe machen, mir hier zu helfen. Ich habe mich auch schon viel durch die Dokumentationen gelesen, was mich aber im Endeffekt viel mehr verwirrt hat, als geholfen.

    Ich wäre euch dankbar, wenn ihr mir mithilfe von Beispielcodes zeigen könntet, wie ich das Umsetzen kann.

    Vielen Lieben Dank schon jetzt im Vorraus!



  • 1. Du arbeitest immer "Model-based". Die Item Varianten haben einfach ein vordefiniertes Model dahinter.
    Das QTreeWidget ist von QTreeView abgeleitet und soll etwas "einfacher" zu bedienen sein, wenn man nichts komplexes machen will. Ich würde aber davon abraten. Ich finde das nicht wirklich einfacher zu benutzen, dafür gibts unnötige Einschränkungen.

    2. Entweder ein eigenes Model schreiben oder QStandardItemModel nehmen (und die Doku dazu lesen). Ob sich hier ein eigenes Model anbietet, kann man so nicht sagen. Das bietet sich vielleicht eher an, wenn die Daten dynamisch sind und es einfacher ist, die Daten bei Bedarf bereitzustellen. Wenn du eh schon alle Daten hast, kannst du es erstmal mit dem QStandardItemModel probieren.

    3. Macht alles das Model, Doku lesen.

    4. QStyledItemDelegate, Doku lesen.



  • Okay vielen Dank! Ich werde mir heute abend zu den genannten Begriffen die Doku durchlesen und mich dann bei Rückfragen nochmals melden 🙂



  • So,

    hab mich jetzt mal für den Anfang durch die Doku geklickt und auch etwas geschafft.

    #include "windowmain.h"
    #include "ui_windowmain.h"
    
    #include <QtWidgets>
    
    WindowMain::WindowMain(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::WindowMain)
    {
        ui->setupUi(this);
    
        ui->treeView->setRootIsDecorated(false);
        ui->treeView->setAlternatingRowColors(true);
    
        QStandardItemModel * model = new QStandardItemModel(0,2,ui->treeView);
    
        model->setHeaderData(0,Qt::Horizontal,QObject::tr("Spalte I"));
        model->setHeaderData(1,Qt::Horizontal,QObject::tr("Spalte II"));
    
        model->insertRow(0);
        model->setData(model->index(0,0), "ERste Zeile");
        model->setData(model->index(0,1), "ERste Zeile + Spalte");
    
        model->insertRow(0);
        model->setData(model->index(0,0), "Zste Zeile");
        model->setData(model->index(0,1), "Zste Zeile + Spalte");
    
        ui->treeView->setModel(model);
    }
    
    WindowMain::~WindowMain()
    {
        delete ui;
    }
    

    Dazu jetzt 2 kurze Fragen: Wie kann ich dafür sorgen, dass die neue Zeile hinten und nicht vorne angehängt wird? (model->count gibts nicht).

    Und 2. ich muss jeder Zeile in dem Model (also jedem Datensatz) eine ID zuordnen, damit ich die Zeilen nach Sortieren oder Filtern noch zuordnen kann. Gibt es dafür eine Schnittstelle oder wo kann ich die Daten speichern?



  • model->count gibst schon. Es gibt halt columnCount und rowCount. Brauchst du eine gute IDE mit funktionierender Intellisense?

    insertRow(0) fügt die Zeile immer an erster Position ein. Du könntest stattdessen insertRow(rowCount() - 1) aufrufen, oder einfach appendRow.

    Sortieren macht man meist über ein anderes Model, das drübergelegt wird, z.B. QSortFilterProxyModel. Dann bleiben die Struktur deines Models konstant.
    Eigene Daten kann man aber in der UserRole speichern.

    QStandardItem * item = new QStandardItem(...);
    item->setData(Qt::UserRole, irgendwasWasManAlsQVariantSpeichernKann);



  • Hallo,

    danke für deine Antwort. Bin einfach nicht auf die Idee gekommen, danach zu schaun. Hatte es aber dann auch in der Doku gefunden. Das mit dem "Model drüberlegen" verstehe ich nicht. Ich kann ja mein Model nach Collumns sortieren lassen, wenn ich das möchte. Wie lege ich da jetzt ein Model drüber? Ich muss mich soweit einfach auch entschuldigen, aber QT hat ein ziemlich unterschiedliches Prinzip mit Komponenten umzugehen und wie oben genannt verwirren mich die Dokus derzeit noch mehr als sie mir helfen. Es wäre wirklich super lieb, wenn du mir einfach einen Beispielcode (zB anhand meines Codes) geben könntest, mit dem ich das Problem der Zuordnung der Einträge nach sortieren lösen kann.



  • QSortFilterProxyModel * proxyModel = new QSortFilterProxyModel(parent);
    proxyModel->setSourceModel(model);
    view->setModel(proxyModel);

    D.h., du erstellst ein Proxy Model, übergibst dem ein Sort Model (dein eigentliches Model) und übergibst dem View wiederum das Proxy Model.

    Dein eigentliches Model wird dann beim Sortieren nicht verändert. Das QSortProxyFilterModel verwaltet intern die Zuordnung.


Anmelden zum Antworten