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. [Solved]QSortFilterProxyModel Crashes
Qt 6.11 is out! See what's new in the release blog

[Solved]QSortFilterProxyModel Crashes

Scheduled Pinned Locked Moved General and Desktop
13 Posts 3 Posters 12.7k Views 3 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 sharethl
    #1

    I have Data->QAbstractTableModel->QSortFilterProxyModel->QTableView.
    But if I show then hide a column, click a cell, QSortFilterProxyModel crashes on mapToSource().
    Could anyone help, please?

    Thanks

    #include <QAbstractItemModel>
    ProxyModel::ProxyModel(QObject *parent) : QSortFilterProxyModel(parent)
    {
    }
    
    bool ProxyModel::isMaxMinShown() const
    {
        return _isMaxMinShown;
    }
    
    void ProxyModel::setIsMaxMinShown(bool isMaxMinShown)
    {
    
        _isMaxMinShown = isMaxMinShown;
    }
    
    bool ProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
    {
        return true;
    }
    
    bool ProxyModel::filterAcceptsColumn(int source_column, const QModelIndex &source_parent) const
    {
        if(source_column==1){
            return _isMaxMinShown;
        }
        return true;
    }
    
    

    TableModel

    Vm::Vm(QObject *parent) : QAbstractTableModel(parent)
    {
    
    }
    
    int Vm::rowCount(const QModelIndex &parent) const
    {
        return 20;
    }
    
    int Vm::columnCount(const QModelIndex &parent) const
    {
        return 5;
    }
    
    QVariant Vm::data(const QModelIndex &index, int role) const
    {
        if (!index.isValid())
            return QVariant();
        if (role == Qt::DisplayRole) {
            switch(index.column()){
            case 0: // name
                return QString::number(index.row());
            case 1: // min
                return 0.1;
            case 2: // percentage
                return 0.2;
            case 3: // max
                return 0.3;
            case 4: // LOD or sigma
                return 0.4;
            }
        }
        // back ground
    
        if(role == Qt::TextAlignmentRole){
            return Qt::AlignCenter;
        }
        return QVariant();
    }
    
    QVariant Vm::headerData(int section, Qt::Orientation orientation, int role) const
    {
        if(role == Qt::DisplayRole && orientation == Qt::Horizontal){
            switch(section){
            case 0:
                return tr("A");
            case 1:
                return tr("B");
            case 2:
                return tr("C");
            case 3:
                return tr("D");
            case 4:
                return "E";
            }
        }
        return QVariant::Invalid;
    }
    
    Qt::ItemFlags Vm::flags(const QModelIndex &index) const
    {
        if(index.isValid()){
            return Qt::ItemIsEnabled;
        }
        return Qt::NoItemFlags;
    }
    

    MainWindow

    MainWindow::MainWindow(QWidget *parent) :
        QMainWindow(parent),
        ui(new Ui::MainWindow)
    {
        ui->setupUi(this);
        _proxyModel = new ProxyModel(this);
        _vm = new Vm(this);
        _proxyModel->setSourceModel(_vm);
        ui->tableView->setModel(_proxyModel);
        //QScroller::grabGesture(ui->tableView, QScroller::LeftMouseButtonGesture);
    }
    
    MainWindow::~MainWindow()
    {
        delete ui;
    }
    
    void MainWindow::on_pushButton_clicked()
    {
        _proxyModel->setIsMaxMinShown(!_proxyModel->isMaxMinShown());
        emit _vm->layoutChanged();
    }
    
    1 Reply Last reply
    0
    • SGaistS Offline
      SGaistS Offline
      SGaist
      Lifetime Qt Champion
      wrote on last edited by
      #2

      Hi,

      You should run your application through the debugger, it will show you the exact point of crash.

      Note that you are doing something wrong: you are trying to emit a signal from another class.

      Interested in AI ? www.idiap.ch
      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

      S 2 Replies Last reply
      0
      • SGaistS SGaist

        Hi,

        You should run your application through the debugger, it will show you the exact point of crash.

        Note that you are doing something wrong: you are trying to emit a signal from another class.

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

        @SGaist
        Depends on mouse click cell first or show/hide column first, I got this two stack.
        And disassember shows, don't know how to show code yet.
        And here is the project if anyone could try it.
        Tested with (Qt 5.3 linux, qt5.5 linux, qt5.5 windows)
        Sometimes crash on parent();
        0 QSortFilterProxyModel::parent(QModelIndex const&) const 0x7ffff70f9ced
        1 QPersistentModelIndex::parent() const 0x7ffff70d8d73

        Sometimes crash on here,
        0 QSortFilterProxyModelPrivate::index_to_iterator D:/Qt/5.5/mingw492_32/bin/Qt5Cored.dll 187 0x114d743
        1 QSortFilterProxyModelPrivate::proxy_to_source D:/Qt/5.5/mingw492_32/bin/Qt5Cored.dll 376 0xfb3536
        2 QSortFilterProxyModel::mapToSource D:/Qt/5.5/mingw492_32/bin/Qt5Cored.dll 2718 0xfbab5f
        3 QSortFilterProxyModel::flags D:/Qt/5.5/mingw492_32/bin/Qt5Cored.dll 2200 0xfb9ae1

        1 Reply Last reply
        0
        • SGaistS SGaist

          Hi,

          You should run your application through the debugger, it will show you the exact point of crash.

          Note that you are doing something wrong: you are trying to emit a signal from another class.

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

          @SGaist
          Found a work around.
          Clear proxy model first, then set source model again.

              _proxyModel->clear();
              _proxyModel->setIsMaxMinShown(!_proxyModel->isMaxMinShown());
              _proxyModel->setSourceModel(_vm);
              emit _vm->layoutChanged(); // change this to emit from vm class.
          
          
          S 1 Reply Last reply
          0
          • S sharethl

            @SGaist
            Found a work around.
            Clear proxy model first, then set source model again.

                _proxyModel->clear();
                _proxyModel->setIsMaxMinShown(!_proxyModel->isMaxMinShown());
                _proxyModel->setSourceModel(_vm);
                emit _vm->layoutChanged(); // change this to emit from vm class.
            
            
            S Offline
            S Offline
            sharethl
            wrote on last edited by
            #5

            @sharethl
            Clear and set source model again still have chances to crash.....

            S 1 Reply Last reply
            0
            • S sharethl

              @sharethl
              Clear and set source model again still have chances to crash.....

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

              @sharethl
              Remove this line working
              emit _vm->layoutChanged(); // change this to emit from vm class.

              1 Reply Last reply
              0
              • K Offline
                K Offline
                karlheinzreichel
                wrote on last edited by
                #7

                to update your table, you better use
                emit dataChanged(modelIndexFrom, modelIndexTo);

                1 Reply Last reply
                0
                • SGaistS Offline
                  SGaistS Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on last edited by
                  #8

                  Are you sure _vm is not null ? And again, don't call emit on other classes like that, it feels like your doing some bad design.

                  Interested in AI ? www.idiap.ch
                  Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                  S 1 Reply Last reply
                  0
                  • K Offline
                    K Offline
                    karlheinzreichel
                    wrote on last edited by
                    #9

                    You have to emit layoutAboutToBeChanged() before you change your model
                    and emit layoutChanged after your model changes to reflect the changes to the ui
                    (see documentation void QAbstractItemModel::layoutChanged())

                    some code

                    void MainWindow::on_pushButton_clicked()
                    {
                       _vm->tellLayoutAboutToBeChanged();
                        _proxyModel->setIsMaxMinShown(!_proxyModel->isMaxMinShown());
                        _vm->tellLayoutChanged();
                    }
                    
                    void Vm::tellLayoutChanged()
                    {
                       emit layoutChanged();
                    }
                    
                    void Vm::tellLayoutAboutToBeChanged()
                    {
                       emit layoutAboutToBeChanged();
                    }
                    
                    1 Reply Last reply
                    0
                    • SGaistS Offline
                      SGaistS Offline
                      SGaist
                      Lifetime Qt Champion
                      wrote on last edited by
                      #10

                      That design is completely wrong. It's the responsibility of the model to know when to emit anything. The proxy will make the signals follow. It's not the role of MainWindow at all to call these functions.

                      Interested in AI ? www.idiap.ch
                      Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                      K 1 Reply Last reply
                      0
                      • SGaistS SGaist

                        Are you sure _vm is not null ? And again, don't call emit on other classes like that, it feels like your doing some bad design.

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

                        @SGaist Yes, bad design, will correct this.

                        1 Reply Last reply
                        0
                        • SGaistS SGaist

                          That design is completely wrong. It's the responsibility of the model to know when to emit anything. The proxy will make the signals follow. It's not the role of MainWindow at all to call these functions.

                          K Offline
                          K Offline
                          karlheinzreichel
                          wrote on last edited by
                          #12

                          @SGaist
                          You are absolutely right.
                          But the question was for the reason the application crashes.

                          The reason for the crash is not the architecture but the missing layoutAboutToBeChanged()

                          1 Reply Last reply
                          0
                          • SGaistS Offline
                            SGaistS Offline
                            SGaist
                            Lifetime Qt Champion
                            wrote on last edited by
                            #13

                            Still, that call is not done at the right place, so you're currently just lucky it works.

                            Interested in AI ? www.idiap.ch
                            Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

                            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