【问题标题】:QML TableView with dynamic number of columns具有动态列数的 QML TableView
【发布时间】:2014-12-01 14:42:49
【问题描述】:

我一直在尝试使用 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 的模式包含ListElements 并在其中定义了角色,但运行时它不会显示任何内容。

但是,如果取消注释上述代码并且定义了 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 的解决方案远比这要好。

【问题讨论】:

    标签: c++ qt qml qtquick2


    【解决方案1】:

    您可以使用TableViewresources 属性,根据需要动态创建任意数量的TableViewColumn

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

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

    【讨论】:

    • 优秀的答案!为了找到resources 属性,我不得不深入研究文档,即使这样我也不知道它可以以这种方式使用。
    【解决方案2】:

    资源解决方案对我不起作用(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)
                }
            }
        }
    }
    

    }

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-08-09
      • 2015-07-16
      • 1970-01-01
      • 2013-12-02
      • 2016-01-04
      • 2021-08-03
      • 1970-01-01
      • 2020-10-08
      相关资源
      最近更新 更多