QML Выходная матрица

У меня есть матрица

QVector<QVector<double>> A;

что я хочу вывести и отредактировать. В QWidgets я поместил эту матрицу в подкласс QAbstractTableModel и установил ее в качестве модели для QTableView. В qml это, похоже, не работает с TableView.

Как я понял, для матриц фиксированного размера я могу явно написать роли для каждого столбца:

TableViewColumn {
        role: "first" // "second", "third" etc.
}

И затем для каждой роли возвращают соответствующий столбец из QAbstractTableModel::data(...).

Но что, если размеры матрицы вычисляются во время выполнения? Как лучше всего работать с такими матрицами в qml?

1 ответ

Примечание: может быть хак, но работает

Я не работал с QAbstractTableModel и до сих пор QML, но, насколько я понимаю, QML не заботится о столбцах, поэтому ListModel должно быть достаточной заменой для примера:

import QtQuick 2.7
import QtQml 2.2
import QtQuick.Controls 1.4

ApplicationWindow {
    id: myWindow
    visible: true
    width: 600
    height: 600
    color: 'white'

    ListModel {
        id: lv
        property var roleNames: ['role1', 'role2']
        ListElement { role1: 'a'; role2: 'b' }
    }

    ListModel {
        id: tm
        property var roleNames: [ 'myID', 'age', 'name']
        ListElement { myID:  1; name: 'Egon';    age: 15 }
        ListElement { myID:  2; name: 'Herbert'; age: 21 }
        ListElement { myID:  3; name: 'Jan';     age: 11 }
        ListElement { myID:  4; name: 'Dieter';  age: 23 }
        ListElement { myID:  5; name: 'Ulrich';  age:  6 }
        ListElement { myID:  6; name: 'Hans';    age: 45 }
        ListElement { myID:  7; name: 'Frieder'; age: 31 }
        ListElement { myID:  8; name: 'Gerd';    age: 28 }
    }

    TableView {
        id: tv
        model: lv
        anchors.fill: parent
        Instantiator {
            model: tv.model ? tv.model.roleNames : 0
            delegate: TableViewColumn {
                title: modelData
                role: modelData
                Component.onCompleted: tv.addColumn(this)
                Component.onDestruction: tv.removeColumn(0)
            }
        }
    }

    MouseArea {
        anchors.fill: parent
        onClicked: tv.model = (tv.model === lv ? tm : lv)
    }
}

Добавляя вторую модель, я создаю достаточное и соответственно настроенное количество TableViewColumnс, что я тогда добавлю к TableView используя Instantiator (как TableViewColumn нет Item как это выглядит).

Проблема, которая возникает здесь, состоит в том, что я не могу найти способ доступа к индексу столбца, мне нужно позвонить tv.removeColumn с правильным индексом. Но в этом случае, когда я всегда заменяю всю модель, это не проблема, поскольку я удаляю все столбцы один за другим, всегда удаляя первый с tv.removeColumn(0), Я все равно получу ошибку

Error: Invalid attempt to destroy() an indestructible object

как этот метод пытается вызвать destroy() на объекте, который не создан с помощью JS, но это не проблема. Instantiator удалит его сразу после.

Итак: хотя есть сообщение об ошибке, это будет работать, пока вы полностью сбросите модель Instantiator каждый раз, когда есть изменение.

Другие вопросы по тегам