2014-12-01 14 views
7

Próbowałem użyć QML TableView, aby wyświetlić QAbstractTableModel. Brakująca część równania wydaje się, że nie jest możliwe posiadanie zmiennej liczby kolumn w TableView, pomimo nadpisania QAbstractItemModel::roleNames, która powinna powiedzieć Qt liczbę i nazwę moich kolumn. Próbowałem testowania to przy użyciu tylko QML:Tabelaryczne QML z dynamiczną liczbą kolumn

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" 
     } 
    } 
} 

Po uruchomieniu tego nie pokazuje niczego mimo trybie TableView „s zawierającego ListElement S z ról określonych w nich.

Jeśli jednak powyższy kod zostanie odkomentowany i zostanie zdefiniowana TableViewColumn, kolumna wyświetli dane dla tej roli zgodnie z oczekiwaniami, ale tabela nadal nie będzie wyświetlać żadnych innych ról. Oczywiście będzie to działać tylko dla statycznie zdefiniowanej liczby kolumn, a nie dla mojego przypadku, w którym liczba kolumn nie jest znana przed uruchomieniem.

Podany przykład jest w zasadzie taki sam jak mój przykład z życia, z tym że mój model jest zdefiniowany w C++.

Wygląda na to, że mogło to być już zadane here, ale nie uzyskało żadnej odpowiedzi.

EDIT: Próbowałem wywołanie funkcji javascript:

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); 
} 

Od C++

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

Ten przynajmniej pozwolił mi dynamicznie dodawać kolumny z C++, choć nie od wewnątrz modelu/Zobacz architekturę. Rozwiązanie Yoanna jest jednak o wiele lepsze.

Odpowiedz

11

Można utworzyć dynamicznie tyle różnych TableViewColumn, ile potrzebujesz, korzystając z właściwości resources swojej TableView.

Będziesz musiał dodać metodę w niestandardowej klasie modelu, która da ci rolename, które chcesz wyświetlić.

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

Doskonała odpowiedź! Musiałem trochę przekopać się przez dokumentację, aby znaleźć właściwość 'resources', a nawet nie wiedziałbym, że można ją wykorzystać w ten sposób. – sjdowling

Powiązane problemy