Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. onEditingFinished Crash in TableView
Qt 6.11 is out! See what's new in the release blog

onEditingFinished Crash in TableView

Scheduled Pinned Locked Moved Unsolved QML and Qt Quick
4 Posts 2 Posters 1.8k Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • S Offline
    S Offline
    sharethl
    wrote on last edited by
    #1

    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()
                            }
                        }
                    }
                }
            }
        }
    }
    
    
    T 1 Reply Last reply
    0
    • S sharethl

      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()
                              }
                          }
                      }
                  }
              }
          }
      }
      
      
      T Offline
      T Offline
      tarod.net
      wrote on last edited by
      #2

      @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.

      "Individually, we are one drop. Together, we are an ocean."

      S 1 Reply Last reply
      0
      • T tarod.net

        @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.

        S Offline
        S Offline
        sharethl
        wrote on last edited by sharethl
        #3

        @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();
        }
        
        T 1 Reply Last reply
        0
        • S sharethl

          @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();
          }
          
          T Offline
          T Offline
          tarod.net
          wrote on last edited by
          #4

          @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.

          "Individually, we are one drop. Together, we are an ocean."

          1 Reply Last reply
          0

          • Login

          • Login or register to search.
          • First post
            Last post
          0
          • Categories
          • Recent
          • Tags
          • Popular
          • Users
          • Groups
          • Search
          • Get Qt Extensions
          • Unsolved