Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

onEditingFinished Crash in TableView



  • Why the following code crashes when click next cell in the name column?

    1. double click a name cell to type some text,
    2. 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.
    Sample

    references:
    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-columns

    import 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 the onEditingFinished 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 layoutChanged

    onEditingFinished: {
    	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 like emit dataChanged(index(0), index(row));and this should do the trick.


Log in to reply