title: Plugging a QSortFilterProxyModel on a QTableView unexpectdly crashed
body: <p>I wrote a small Qt prototype which consists in a <code>QTreeView</code> on which I plugged <code>QStandardItemModel</code>. From there, I would like to be able to view the last level of my tree in a <code>QTableView</code> which I would like to be sortable and, why not, filterable. That seems to be the perfect scenario for the use of <code>QSortFilterProxyModel</code>. After implementation, the global view looks like what I want with the <code>QTreeView</code> on the left side and the <code>QTableView</code> on the right side(see image attached).<a href="https://i.stack.imgur.com/h4nB5.png" rel="nofollow noreferrer"><img src="https://i.stack.imgur.com/h4nB5.png" alt="enter image description here"></a></p>
  
  <p>However, I face two issues:</p>
  
  <ul>
  <li>only the first column is sortable</li>
  <li>worse, if I select an item which is not in the first column and then click on one of the horizontal header the application crashes unexpectedly without any debugging backtrace in any of my implemented methods.</li>
  </ul>
  
  <p>I may have misunderstood something regarding the use of Qt proxy model but do not know what and I can not find any clear hint on stack or elsewhere.</p>
  
  <p>Here is my prototype cpp file:</p>
  
  <pre><code>#include &lt;string&gt;
  #include &lt;vector&gt;
  
  #include &lt;QDebug&gt;
  #include &lt;QAbstractProxyModel&gt;
  #include &lt;QSortFilterProxyModel&gt;
  #include &lt;QStandardItem&gt;
  #include &lt;QStandardItemModel&gt;
  
  #include "mainwindow.h"
  #include "ui_mainwindow.h"
  
  struct Peak {
      Peak(const std::string&amp; name, int index, double qx, double qy, double qz);
  
      std::string _name;
  
      int _index;
  
      double _qx;
      double _qy;
      double _qz;
  
  };
  
  Peak::Peak(const std::string&amp; name, int index, double qx, double qy, double qz)
  : _name(name),
    _index(index),
    _qx(qx),
    _qy(qy),
    _qz(qz)
  {
  
  }
  
  struct PeakItem : public QStandardItem
  {
      PeakItem(const Peak&amp; peak);
  
      Peak _peak;
  
  };
  
  PeakItem::PeakItem(const Peak&amp; peak)
  : _peak(peak)
  {
      setText(QString::fromStdString(_peak._name));
  
      appendRow(new QStandardItem(QString::number(_peak._index)));
      appendRow(new QStandardItem(QString::number(_peak._qx)));
      appendRow(new QStandardItem(QString::number(_peak._qy)));
      appendRow(new QStandardItem(QString::number(_peak._qz)));
  }
  
  struct PeakListItem : public QStandardItem
  {
      PeakListItem(const std::vector&lt;Peak&gt;&amp; peaks);
  
      std::vector&lt;Peak&gt; _peaks;
  };
  
  PeakListItem::PeakListItem(const std::vector&lt;Peak&gt;&amp; peaks)
  : _peaks(peaks)
  {
      setText("Peaks");
      setCheckable(true);
  
      for (size_t r=0; r &lt; _peaks.size(); ++r) {
          auto item = new PeakItem(_peaks[r]);
          appendRow(item);
      }
  }
  
  struct PeakListProxyModel : public QSortFilterProxyModel {
  
      PeakListProxyModel(PeakListItem* peak_list_item);
  
      virtual QModelIndex mapFromSource(const QModelIndex &amp;) const override;
      virtual QModelIndex mapToSource(const QModelIndex &amp;) const override;
  
      virtual QModelIndex parent(const QModelIndex &amp;) const override;
      virtual QModelIndex index(int, int, const QModelIndex &amp; p = QModelIndex()) const override;
  
      virtual int rowCount(const QModelIndex &amp; p = QModelIndex()) const override;
      virtual int columnCount(const QModelIndex &amp; p = QModelIndex()) const override;
  
      virtual void sort(int column, Qt::SortOrder order) override;
  
      PeakListItem* _peak_list_item;
  
  };
  
  PeakListProxyModel::PeakListProxyModel(PeakListItem* peak_list_item)
  : _peak_list_item(peak_list_item)
  {
  }
  
  QModelIndex PeakListProxyModel::parent(const QModelIndex &amp;) const
  {
      return QModelIndex();
  }
  
  QModelIndex PeakListProxyModel::index(int row, int column, const QModelIndex&amp; index) const
  {
  //    qDebug()&lt;&lt;"create index "&lt;&lt;row&lt;&lt;" --- "&lt;&lt;column&lt;&lt;" --- "&lt;&lt;index;
      return createIndex(row, column);
  }
  
  void PeakListProxyModel::sort(int column, Qt::SortOrder order)
  {
      qDebug()&lt;&lt;"sort "&lt;&lt;column;
      QAbstractProxyModel::sort(column,order);
      layoutChanged();
  }
  
  QModelIndex PeakListProxyModel::mapFromSource(const QModelIndex&amp; source_index) const
  {
      if (!source_index.isValid()) {
          return QModelIndex();
      }
  
      auto model = dynamic_cast&lt;QStandardItemModel*&gt;(sourceModel());
      auto item = model-&gt;itemFromIndex(source_index);
      auto parent_item = item-&gt;parent();
  
      auto p = dynamic_cast&lt;PeakItem*&gt;(parent_item);
  
      if (!p) {
          return QModelIndex();
      }
  
      auto proxy_index = createIndex(parent_item-&gt;index().row(),item-&gt;index().row());
      qDebug()&lt;&lt;"map from source --- "&lt;&lt;source_index&lt;&lt;" --- "&lt;&lt;proxy_index;
  
      return proxy_index;
  }
  
  QModelIndex PeakListProxyModel::mapToSource(const QModelIndex&amp; proxy_index) const
  {
      if (!proxy_index.isValid()) {
          return QModelIndex();
      }
  
      auto peak_item = _peak_list_item-&gt;child(proxy_index.row());
  
      auto prop_item = peak_item-&gt;child(proxy_index.column());
  
      auto source_index = prop_item-&gt;index();
  
  //    qDebug()&lt;&lt;"map to source "&lt;&lt;proxy_index&lt;&lt;"  ---  "&lt;&lt;source_index&lt;&lt;" ---- "&lt;&lt;prop_item;
  
      return source_index;
  }
  
  int PeakListProxyModel::rowCount(const QModelIndex&amp; proxy_index) const
  {
      if (proxy_index.isValid()) {
          return 0;
      } else {
          return _peak_list_item-&gt;rowCount();
      }
  }
  
  int PeakListProxyModel::columnCount(const QModelIndex&amp; proxy_index) const
  {
      if (proxy_index.isValid()) {
          return 0;
      } else {
          return 4;
      }
  }
  
  
  MainWindow::MainWindow(QWidget *parent) :
      QMainWindow(parent),
      ui(new Ui::MainWindow)
  {
      ui-&gt;setupUi(this);
  
      QStandardItemModel* model = new  QStandardItemModel();
  
      QStandardItem* experiment = new QStandardItem("Experiment");
  
      QStandardItem* peaks_item = new QStandardItem("Peaks");
  
      std::vector&lt;Peak&gt; peaks;
      peaks.reserve(4);
      for (int i = 0; i &lt; 4; ++i) {
          peaks.emplace_back("Peak"+std::to_string(i),i,i,i,i);
      }
  
  //    PeakListItem* peak_list_item1 = new PeakListItem(peaks);
  //    peaks_item-&gt;appendRow(peak_list_item1);
  
      PeakListItem* peak_list_item2 = new PeakListItem(peaks);
      peaks_item-&gt;appendRow(peak_list_item2);
  
      experiment-&gt;appendRow(peaks_item);
  
      model-&gt;appendRow(experiment);
  
      ui-&gt;treeView-&gt;setModel(model);
  
      PeakListProxyModel* proxy_model = new PeakListProxyModel(peak_list_item2);
      proxy_model-&gt;setSourceModel(model);
  
      ui-&gt;tableView-&gt;setModel(proxy_model);
      ui-&gt;tableView-&gt;setSortingEnabled(true);
  
      for (int i = 0; i &lt; peaks.size(); ++i) {
  //        ui-&gt;treeView-&gt;setRowHidden(i,peak_list_item1-&gt;index(),true);
  //        ui-&gt;treeView-&gt;setRowHidden(i,peak_list_item2-&gt;index(),true);
      }
  }
  
  MainWindow::~MainWindow()
  {
      delete ui;
  }
  </code></pre>