2014-12-01 12 views
7

Ich habe versucht, eine QML TableView zu verwenden, um eine QAbstractTableModel anzuzeigen. Der fehlende Teil der Gleichung scheint zu sein, dass es nicht möglich ist, eine variable Anzahl von Spalten in der TableView zu haben, trotz des Überschreibens QAbstractItemModel::roleNames, was Qt die Anzahl und den Namen meiner Spalten mitteilen sollte. Ich habe versucht zu testen dies nur QML mit aus:QML TableView mit dynamischer Anzahl von Spalten

import QtQuick 2.0 
import QtQuick.Controls 1.1 

Rectangle { 
    anchors.fill: parent 
    property real showImage: 1.0 
    width: 500 
    TableView { 
     id: myTable 
     model: myModel 
     //  TableViewColumn { 
     //   role: "title"; title: "Name"; width: 200 
     //  } 
    } 

    ListModel { 
     id: myModel 
     ListElement { 
      title: "item one" 
     } 
     ListElement { 
      title: "item two" 
     } 
    } 
} 

Sobald er ausgeführt wird dies zeigt nichts trotz der TableView ‚s-Modus enthält ListElement s mit in ihnen definierten Rollen.

Wenn jedoch der obige Code unkommentiert ist und TableViewColumn definiert ist, zeigt die Spalte Daten für diese Rolle wie erwartet an, aber die Tabelle zeigt weiterhin keine anderen Rollen an. Offensichtlich funktioniert das nur für eine statisch definierte Anzahl von Spalten und nicht für den Fall, dass die Anzahl der Spalten erst zur Laufzeit bekannt ist.

Das angegebene Beispiel ist im Grunde genommen dasselbe wie in meinem realen Beispiel, außer dass mein Modell in C++ definiert ist.

Es scheint, als ob das bereits here gefragt worden wäre, aber es hat keine Antwort erhalten.

EDIT: hatte ich versucht, eine Javascript-Funktion aufrufen:

function addColumnToTable(roleName) { 
    var columnString = 'import QtQuick 2.3; import QtQuick.Controls 1.2; TableViewColumn {role: "' 
      + roleName + '"; title: "' + roleName + '"; width: 40}'; 
    var column = Qt.createQmlObject(
       columnString 
       , myTable 
       , "dynamicSnippet1") 
    myTable.addColumn(column); 
} 

Von C++:

QVariant roleName = "name"; 
QObject *root = view->rootObject(); 
QMetaObject::invokeMethod(root, "addColumnToTable", Q_ARG(QVariant, roleName)); 

Das zumindest konnte ich Spalten von C++, obwohl dynamisch hinzuzufügen, nicht aus dem Modell/Architektur ansehen. Yoanns Lösung ist jedoch weit besser.

Antwort

11

Sie könnten dynamisch so viele TableViewColumn wie Sie benötigen, mit der resources Eigenschaft Ihrer TableView.

Sie müssen eine Methode in Ihrer benutzerdefinierten Modellklasse hinzufügen, die Ihnen die RolleNamen gibt, die Sie anzeigen möchten.

QML:

Component 
{ 
    id: columnComponent 
    TableViewColumn{width: 100 } 
} 

TableView { 
    id: view 
    anchors.fill: parent 
    resources: 
    { 
     var roleList = myModel.customRoleNames 
     var temp = [] 
     for(var i=0; i<roleList.length; i++) 
     { 
      var role = roleList[i] 
      temp.push(columnComponent.createObject(view, { "role": role, "title": role})) 
     } 
     return temp 
    } 

    model: myModel 

MyModel.h:

class MyModel: public QAbstractListModel 
{ 
    Q_OBJECT 
    Q_PROPERTY(QStringList userRoleNames READ userRoleNames CONSTANT) 

public: 
    explicit MyModel(QObject *parent = 0); 

    enum MyModelRoles { 
     UserRole1 = Qt::UserRole + 1, 
     UserRole2, 
     ... 
    }; 

    QStringList userRoleNames(); 
    int rowCount(const QModelIndex & parent = QModelIndex()) const; 
    QVariant data(const QModelIndex & index, int role = Qt::DisplayRole) const; 
    ... 

private: 
    QHash<int, QByteArray> roleNames() const; 
    ... 

}; 

MyModel.cpp:

... 
... 

QHash<int, QByteArray> MyModel::roleNames() const { 
    QHash<int, QByteArray> roles = QAbstractListModel::roleNames(); 
    roles[UserRole1] = "whatever"; 
    roles[UserRole2] = "youwant"; 
    return roles; 
} 

QStringList MyModel::userRoleNames() // Return ordered List of user-defined roles 
{ 
    QMap<int, QString> res; 
    QHashIterator<int, QByteArray> i(roleNames()); 
    while (i.hasNext()) { 
     i.next(); 
     if(i.key() > Qt::UserRole) 
      res[i.key()] = i.value(); 
    } 
    return res.values(); 
} 

... 
... 
+2

Ausgezeichnete Antwort! Ich musste die Dokumentation ein wenig durchforsten, nur um die "Ressourcen" -Eigenschaft zu finden, und sogar davon hätte ich nicht gewusst, dass sie auf diese Weise verwendet werden könnte. – sjdowling

Verwandte Themen