Removing an element from ListModel produces Type error
-
I'm working on a TableView which contains not only text, but some control elements and some other elements which are defined using delegates. When I'm adding rows using append() or insert() methods to fill ListModel everything works fine, but when I delete rows using remove() method I see triple warning "TypeError: Type error" in console.
I extracted this fragment and here's the working code:
import QtQuick 2.0 import QtQuick.Controls 1.0 Item { width: 600 height: 400 Row { ListModel { id: dataModel ListElement { name: "Line 1"; active: true } ListElement { name: "Line 2"; active: false } } TableView { id: table model: dataModel TableViewColumn { title: "Name" role: "name" } TableViewColumn { title: "Active" delegate: CheckBox { checked: model.active } } } Button { text: "Delete" onClicked: { dataModel.remove(table.currentRow) } } } }
One oddity which I noticed: if I select some row and press "Delete" button, the row is still deleted, but I see the mentioned warnings. But if I tick checkbox in "Active" column of the selected row beforehand and then press "Delete" button, the row is deleted without any warning. Is it some bug or I'm missing something here?
-
model.active doesn't exist I think. Why it is able to get the correct value is kind of beyond me. But when you click the CheckBox you immediately break the binding to model.active. So when you delete there is no error.
Look at the docs for the delegate. You can get the value in the model with styleData.value:
TableViewColumn { title: "Active" role: "active" delegate: CheckBox { checked: styleData.value } }
I don't know how you are supposed to edit the value though. Not sure how to use TableView for that. Probably use the index and modify directly using commands on ListModel.
-
I was wrong. model.active does exist. Use it to modify the value, but use styleData.value to read:
import QtQuick 2.15 import QtQuick.Controls 1.6 import QtQuick.Window 2.15 Window { width: 640 height: 480 visible: true title: qsTr("Hello World") Item { width: 600 height: 400 Row { ListModel { id: dataModel ListElement { name: "Line 1"; active: true } ListElement { name: "Line 2"; active: false } } TableView { id: table width: 275 model: dataModel TableViewColumn { title: "Name" role: "name" } TableViewColumn { title: "Active" role: "active" delegate: CheckBox { //checked: styleData.value onCheckedChanged: model.active = checked Component.onCompleted: checked = styleData.value } } } TableView { id: table2 width: 275 model: dataModel TableViewColumn { title: "Name" role: "name" } TableViewColumn { title: "Active" role: "active" } } Button { text: "Delete" onClicked: { dataModel.remove(table.currentRow) } } } } }
I think there is some sort of lifetime issue with "model" when a row is deleted.
-
Indeed. In my case the value is modified in the Dialog along with other values of the row. But the main idea is absolutely correct: role should be set for this item and its value should be accessed using styleData.value.
I fixed my code for another TableViewColumn which draws rectangles of different colors which are stored in the same model, now the rows are deleted without errors.
Thanks for your help!
-
Qt Quick Controls 1 have been deprecated a long time ago, and in QQC1 the TableView was especially bad regarding the performances, due to it being quite a hacky solution.
I would recommend to stay away from it and use the Qt Quick Controls 2 TableView instead.
-
There's no TableView in Qt Quick Controls 2, there's one in Qt Quick. As far as I understand it relies more on C++ models rather than on QML ones. QML model proposed in the documentation [https://doc.qt.io/qt-5/qml-qtquick-tableview.html] looks much more complex than ListModel which I use with QQC1 currently.
This TableView which I am implementing is used in plasmoid configuration window, so performance is the least concern, as it will be shown not very often. And Qt Quick TableView looks more intimidating so it will be harder for me to implement.