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
каждый раз, когда есть изменение.