QML TableView具有动态列数

时间:2014-12-01 14:42:50

标签: c++ qt qml qtquick2

我一直在尝试使用QML TableView来显示QAbstractTableModel。等式中缺少的部分似乎是TableView中不可能有一个可变数量的列,尽管重写QAbstractItemModel::roleNames应该告诉Qt我的列的数量和名称。我尝试仅使用QML进行测试:

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

运行时,尽管TableView的模式包含ListElement并且其中定义了角色,但这并未显示任何内容。

但是,如果上述代码已取消注释并且定义了TableViewColumn,则该列将按预期显示该角色的数据,但该表仍将不显示任何其他角色。显然,这只适用于静态定义的列数,而不适用于直到运行时才知道列数的情况。

给出的示例与我的现实生活示例基本相同,只是我的模型是用C ++定义的。

好像这可能已被问过here,但它没有得到任何回复。

编辑:我曾尝试调用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);
}

来自C ++:

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

这至少允许我从C ++中动态添加列,尽管不是从模型/视图架构中添加。虽然Yoann的解决方案远比这更好。

2 个答案:

答案 0 :(得分:11)

您可以使用TableViewColumn的{​​{1}}属性动态创建所需数量resources

您必须在自定义模型类中添加一个方法,该方法将为您提供要显示的roleNames。

<强> QML:

TableView

<强> MyModel.h:

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.cpp:

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;
    ...

};

答案 1 :(得分:1)

有资源的解决方案对我不起作用(Qt 5.6)。 TableView未更新。

这对我有用:

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

TableView {
    id: tableView
    model: listModel
    property var titles: somethingDynamic
    property var curTitles: {
        var t=[]
        for(var i=0;i<columnCount;i++){
            t.push(getColumn(i).title)
        }
        return t
    }
    onTitlesChanged:{
        for(var i=0;i<titles.length;i++){
            if(curTitles.indexOf(titles[i])==-1){
                var column = addColumn(columnComponent) 
                column.title=titles[i]
                column.role=titles[i]                   
            }
        }
        for(var i=curTitles.length-1;i>=0;i--){
            if(titles.indexOf(curTitles[i])==-1){
                removeColumn(i)
            }
        }
    }
}

}

它还可以正确更新拖放重新排序的列。