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

QTableView drag and drop crashing program

Scheduled Pinned Locked Moved Solved General and Desktop
9 Posts 4 Posters 1.2k 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