Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. General and Desktop
  4. QTableView drag and drop crashing program
Forum Updated to NodeBB v4.3 + New Features

QTableView drag and drop crashing program

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 1.1k Views 2 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.
  • R Offline
    R Offline
    Rodrigo B.
    wrote on last edited by
    #1

    I've created a minimal QTableView example using QAbstractTableModel with drag and drop.

    It works fine except that dragging a selection to the area surrounding the table crashes the program:

    alt text

    Any idea of why this is happening?

    I list my implementation of QAbstractTableModel below. The full project is at GitHub.

    #include "mainwindow.h"
    
    #include <QAbstractTableModel>
    #include <qabstractitemmodel.h>
    #include "tablemodel.h"
    
    using std::vector;
    
    
    QModelIndex TableModel::index(int row, int column, const QModelIndex &parent) const {
        Q_UNUSED(parent);
        return createIndex(row, column);
    }
    
    QModelIndex TableModel::parent(const QModelIndex &child) const {
        Q_UNUSED(child);
        return QModelIndex();
    }
    
    QVariant TableModel::data(const QModelIndex &index, int role) const {
        if (role == Qt::DisplayRole)
            return dataList[index.row()][index.column()];
        return QVariant();
    }
    
    bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
        Q_UNUSED(role);
        dataList[index.row()][index.column()] = value;
        emit dataChanged(index, index);
        return true;
    }
    
    int TableModel::rowCount(const QModelIndex &parent) const {
        Q_UNUSED(parent);
        return dataList.size();
    }
    
    int TableModel::columnCount(const QModelIndex &parent) const {
        Q_UNUSED(parent);
        return 3;
    }
    
    Qt::ItemFlags TableModel::flags(const QModelIndex &index) const {
        Q_UNUSED(index);
        return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
    }
    
    Qt::DropActions TableModel::supportedDropActions() const {
        return Qt::CopyAction | Qt::MoveAction;
    }
    
    bool TableModel::insertRows(int row, int count, const QModelIndex &parent) {
        if (count > 0) {
            beginInsertRows(parent, row, row + count + 1);
            for (int i = 0; i != count; i++)
                dataList.emplace(dataList.begin() + row, columnCount());
            endInsertRows();
            emit dataChanged(index(row, 0), index(row + count - 1, columnCount()));
            emit layoutChanged();
            return true;
        }
        else {
            return false;
        }
    }
    
    bool TableModel::removeRows(int row, int count, const QModelIndex &parent) {
        if (count > 0) {
            beginRemoveRows(parent, row, row + count + 1);
            dataList.erase(dataList.begin() + row, dataList.begin() + row + count);
            endRemoveRows();
            emit dataChanged(index(row, 0), index(row + count - 1, columnCount()));
            emit layoutChanged();
            return true;
        }
        else {
            return false;
        }
    }
    
    JonBJ 1 Reply Last reply
    0
    • mrjjM Offline
      mrjjM Offline
      mrjj
      Lifetime Qt Champion
      wrote on last edited by mrjj
      #3

      Hi
      Good call with a runnable project. makes it more appealing to look into.

      It seems to crash in emplace as row is -1 when you drop outside the rows and
      datalist.begin() -1 will then point to something invalid.

      alt text

      Also in the base class
      void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last)
      {
      Q_ASSERT(first >= 0);

      which is also shown when run. ( as row is -1 so first is not > 0)

      So it seems thats the issue. as

      bool TableModel::insertRows(int row, int count, const QModelIndex &parent) {
      
      if (row < 0)  return false; ////<<<<< skip if minus
      
          if (count > 0) {
              beginInsertRows(parent, row, row + count + 1);
              for (int i = 0; i != count; i++)
                  dataList.emplace(dataList.begin() + row, columnCount());
              endInsertRows();
              emit dataChanged(index(row, 0), index(row + count - 1, columnCount()));
              emit layoutChanged();
              return true;
          }
          else {
              return false;
          }
      }
      

      makes it not crash when dragging there so i think you just need to handle that case and append it to your data list.

      R 1 Reply Last reply
      2
      • R Rodrigo B.

        I've created a minimal QTableView example using QAbstractTableModel with drag and drop.

        It works fine except that dragging a selection to the area surrounding the table crashes the program:

        alt text

        Any idea of why this is happening?

        I list my implementation of QAbstractTableModel below. The full project is at GitHub.

        #include "mainwindow.h"
        
        #include <QAbstractTableModel>
        #include <qabstractitemmodel.h>
        #include "tablemodel.h"
        
        using std::vector;
        
        
        QModelIndex TableModel::index(int row, int column, const QModelIndex &parent) const {
            Q_UNUSED(parent);
            return createIndex(row, column);
        }
        
        QModelIndex TableModel::parent(const QModelIndex &child) const {
            Q_UNUSED(child);
            return QModelIndex();
        }
        
        QVariant TableModel::data(const QModelIndex &index, int role) const {
            if (role == Qt::DisplayRole)
                return dataList[index.row()][index.column()];
            return QVariant();
        }
        
        bool TableModel::setData(const QModelIndex &index, const QVariant &value, int role) {
            Q_UNUSED(role);
            dataList[index.row()][index.column()] = value;
            emit dataChanged(index, index);
            return true;
        }
        
        int TableModel::rowCount(const QModelIndex &parent) const {
            Q_UNUSED(parent);
            return dataList.size();
        }
        
        int TableModel::columnCount(const QModelIndex &parent) const {
            Q_UNUSED(parent);
            return 3;
        }
        
        Qt::ItemFlags TableModel::flags(const QModelIndex &index) const {
            Q_UNUSED(index);
            return Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled | Qt::ItemIsDragEnabled | Qt::ItemIsDropEnabled;
        }
        
        Qt::DropActions TableModel::supportedDropActions() const {
            return Qt::CopyAction | Qt::MoveAction;
        }
        
        bool TableModel::insertRows(int row, int count, const QModelIndex &parent) {
            if (count > 0) {
                beginInsertRows(parent, row, row + count + 1);
                for (int i = 0; i != count; i++)
                    dataList.emplace(dataList.begin() + row, columnCount());
                endInsertRows();
                emit dataChanged(index(row, 0), index(row + count - 1, columnCount()));
                emit layoutChanged();
                return true;
            }
            else {
                return false;
            }
        }
        
        bool TableModel::removeRows(int row, int count, const QModelIndex &parent) {
            if (count > 0) {
                beginRemoveRows(parent, row, row + count + 1);
                dataList.erase(dataList.begin() + row, dataList.begin() + row + count);
                endRemoveRows();
                emit dataChanged(index(row, 0), index(row + count - 1, columnCount()));
                emit layoutChanged();
                return true;
            }
            else {
                return false;
            }
        }
        
        JonBJ Offline
        JonBJ Offline
        JonB
        wrote on last edited by
        #2

        @Rodrigo-B
        Does the stack trace when it crashes reveal anything?

        R 1 Reply Last reply
        1
        • mrjjM Offline
          mrjjM Offline
          mrjj
          Lifetime Qt Champion
          wrote on last edited by mrjj
          #3

          Hi
          Good call with a runnable project. makes it more appealing to look into.

          It seems to crash in emplace as row is -1 when you drop outside the rows and
          datalist.begin() -1 will then point to something invalid.

          alt text

          Also in the base class
          void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last)
          {
          Q_ASSERT(first >= 0);

          which is also shown when run. ( as row is -1 so first is not > 0)

          So it seems thats the issue. as

          bool TableModel::insertRows(int row, int count, const QModelIndex &parent) {
          
          if (row < 0)  return false; ////<<<<< skip if minus
          
              if (count > 0) {
                  beginInsertRows(parent, row, row + count + 1);
                  for (int i = 0; i != count; i++)
                      dataList.emplace(dataList.begin() + row, columnCount());
                  endInsertRows();
                  emit dataChanged(index(row, 0), index(row + count - 1, columnCount()));
                  emit layoutChanged();
                  return true;
              }
              else {
                  return false;
              }
          }
          

          makes it not crash when dragging there so i think you just need to handle that case and append it to your data list.

          R 1 Reply Last reply
          2
          • Christian EhrlicherC Offline
            Christian EhrlicherC Offline
            Christian Ehrlicher
            Lifetime Qt Champion
            wrote on last edited by
            #4

            @mrjj said in QTableView drag and drop crashing program:

            beginInsertRows(parent, row, row + count + 1);

            This is wrong: https://doc.qt.io/qt-5/qabstractitemmodel.html#beginInsertRows

            Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
            Visit the Qt Academy at https://academy.qt.io/catalog

            R 1 Reply Last reply
            1
            • JonBJ JonB

              @Rodrigo-B
              Does the stack trace when it crashes reveal anything?

              R Offline
              R Offline
              Rodrigo B.
              wrote on last edited by Rodrigo B.
              #5

              @JonB ,
              It seems @mrjj figured it out, but to answer your question, I only see the information below. Perhaps there is a way to configure Qt Creator to show more but I haven't seen it (I am a newbie with it):

              12:34:28: Starting /Users/rodrigobraz/Documents/Qt Projects/build-tabledraganddrop-Desktop_Qt_5_15_2_clang_64bit-Debug/qtableviewdraganddrop.app/Contents/MacOS/qtableviewdraganddrop ...
              12:34:32: The program has unexpectedly finished.
              12:34:32: The process was ended forcefully.
              12:34:32: /Users/rodrigobraz/Documents/Qt Projects/build-tabledraganddrop-Desktop_Qt_5_15_2_clang_64bit-Debug/qtableviewdraganddrop.app/Contents/MacOS/qtableviewdraganddrop crashed.
              
              JonBJ 1 Reply Last reply
              0
              • R Rodrigo B.

                @JonB ,
                It seems @mrjj figured it out, but to answer your question, I only see the information below. Perhaps there is a way to configure Qt Creator to show more but I haven't seen it (I am a newbie with it):

                12:34:28: Starting /Users/rodrigobraz/Documents/Qt Projects/build-tabledraganddrop-Desktop_Qt_5_15_2_clang_64bit-Debug/qtableviewdraganddrop.app/Contents/MacOS/qtableviewdraganddrop ...
                12:34:32: The program has unexpectedly finished.
                12:34:32: The process was ended forcefully.
                12:34:32: /Users/rodrigobraz/Documents/Qt Projects/build-tabledraganddrop-Desktop_Qt_5_15_2_clang_64bit-Debug/qtableviewdraganddrop.app/Contents/MacOS/qtableviewdraganddrop crashed.
                
                JonBJ Offline
                JonBJ Offline
                JonB
                wrote on last edited by
                #6

                @Rodrigo-B
                For next time: you are supposed to run your code via Debug in Creator. Running under a debugger, it should stop when it crashed, and allow you to view where in your code the problem emanated.

                R 1 Reply Last reply
                0
                • mrjjM mrjj

                  Hi
                  Good call with a runnable project. makes it more appealing to look into.

                  It seems to crash in emplace as row is -1 when you drop outside the rows and
                  datalist.begin() -1 will then point to something invalid.

                  alt text

                  Also in the base class
                  void QAbstractItemModel::beginInsertRows(const QModelIndex &parent, int first, int last)
                  {
                  Q_ASSERT(first >= 0);

                  which is also shown when run. ( as row is -1 so first is not > 0)

                  So it seems thats the issue. as

                  bool TableModel::insertRows(int row, int count, const QModelIndex &parent) {
                  
                  if (row < 0)  return false; ////<<<<< skip if minus
                  
                      if (count > 0) {
                          beginInsertRows(parent, row, row + count + 1);
                          for (int i = 0; i != count; i++)
                              dataList.emplace(dataList.begin() + row, columnCount());
                          endInsertRows();
                          emit dataChanged(index(row, 0), index(row + count - 1, columnCount()));
                          emit layoutChanged();
                          return true;
                      }
                      else {
                          return false;
                      }
                  }
                  

                  makes it not crash when dragging there so i think you just need to handle that case and append it to your data list.

                  R Offline
                  R Offline
                  Rodrigo B.
                  wrote on last edited by
                  #7

                  @mrjj That's a great answer, thank you very much!

                  And of course I now see I could have debugged just like you did... lesson learned! :-)

                  1 Reply Last reply
                  0
                  • Christian EhrlicherC Christian Ehrlicher

                    @mrjj said in QTableView drag and drop crashing program:

                    beginInsertRows(parent, row, row + count + 1);

                    This is wrong: https://doc.qt.io/qt-5/qabstractitemmodel.html#beginInsertRows

                    R Offline
                    R Offline
                    Rodrigo B.
                    wrote on last edited by
                    #8

                    @Christian-Ehrlicher Thank you, you're right! I had meant to type "-1".

                    1 Reply Last reply
                    0
                    • JonBJ JonB

                      @Rodrigo-B
                      For next time: you are supposed to run your code via Debug in Creator. Running under a debugger, it should stop when it crashed, and allow you to view where in your code the problem emanated.

                      R Offline
                      R Offline
                      Rodrigo B.
                      wrote on last edited by
                      #9

                      Great tip, thank you, @JonB!

                      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