Unsolved onEditingFinished Crash in TableView
-
Why the following code crashes when click next cell in the name column?
- double click a name cell to type some text,
- double click another name cell, it would crash.
If I commented out onEditingFinished in qml, then can edit all cells in name column, but have to press enter key to summit changes.
I have uploaded the project, the link is here.
Samplereferences:
http://stackoverflow.com/questions/23856114/in-qml-tableview-when-clicked-edit-a-data-like-excel
http://stackoverflow.com/questions/27230818/qml-tableview-with-dynamic-number-of-columnsimport QtQuick 2.5 import QtQuick.Window 2.2 import QtQuick.Controls 1.4 import QtQuick.Layouts 1.1 //import EditableTableView 1.0 Window { visible: true width: 800 height: 600 Column { anchors.fill: parent Row{ Button{ text: "Add" onClicked: contactModel.add() } } TableView{ id: tableView anchors.left: parent.left anchors.right: parent.right model: contactModel TableViewColumn{ role: "name" title: "name" delegate: nameEditableDelegate } Component.onCompleted: { var roles = contactModel.userRoleNames; for (var i = 1; i< roles.length; i++){ var role = roles[i] tableView.addColumn(columnComponent.createObject(tableView, { "role": role, "title": role})) } } } } Component { id: columnComponent TableViewColumn { width: 80 } } Component{ id: nameEditableDelegate Item{ Text { width: parent.width anchors.margins: 4 anchors.left: parent.left anchors.verticalCenter: parent.verticalCenter elide: styleData.elideMode text: styleData.value !== undefined ? styleData.value : "" color: styleData.textColor visible: !styleData.selected } Loader { id: loaderEditor anchors.fill: parent anchors.margins: 4 Connections { target: loaderEditor.item onAccepted: { contactModel.setData(styleData.row, styleData.column, loaderEditor.item.text) } onEditingFinished: { contactModel.setData(styleData.row, styleData.column, loaderEditor.item.text) console.log(loaderEditor.item) } } sourceComponent: styleData.selected ? editor : null Component { id: editor TextInput { id: textinput color: styleData.textColor text: styleData.value MouseArea { id: mouseArea anchors.fill: parent hoverEnabled: true onClicked: textinput.forceActiveFocus() } } } } } } }
-
@sharethl I think the problem is
styleData.row
is -1 when you leave the row, so in theonEditingFinished
handler the row doesn't exist when this happens. -
@tarod.net
Hi, Tarod,
I have changed the onEditingFinished handler to return when row = -1, and guarded the backend, still have this problem. it happens when emitting layoutChangedonEditingFinished: { if(styleData.row < 0){ return; } contactModel.setData(styleData.row, styleData.column, loaderEditor.item.text) console.log(loaderEditor.item) }
void ContactModel::setData(int row, int col, const QVariant &value) { qDebug() << "setting data"; if(row < 0 || col < 0) return ; // this->beginResetModel(); auto item = _contacts.at(row); if(col == 0){ item->setName(value.toString()); } else{ item->setItem(col-1, value.toString()); } // this->endResetModel(); emit layoutChanged(); }
-
@sharethl Hi!
Sorry... two days ago I couldn't see your whole code and I didn't check the solution I gave you.
I don't know why you are using
layoutChanged()
to notify changes. According to the documentation, this signal is emitted whenever the layout of items exposed by the model has changed, and in your case you are changing the data, not the layout.Working with the project, sometimes I see the next warning before the application crashes:
QML FocusScope: Binding loop detected for property "itemSelected"`
So I guess the problem is related to changes in the layout (false indeed) which Qt is not properly controlling. Because you are not changing the layout, I think the best way of solving this is using the right signal:
void QAbstractItemModel::dataChanged(const QModelIndex & topLeft, const QModelIndex & bottomRight)
Change
emit layoutChanged();
for something likeemit dataChanged(index(0), index(row));
and this should do the trick.