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. QSortFilterProxyModel not mapping properly
QtWS25 Last Chance

QSortFilterProxyModel not mapping properly

Scheduled Pinned Locked Moved Unsolved General and Desktop
qsorfilterproxyqmodelindexitemmodel
8 Posts 2 Posters 2.2k Views
  • 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.
  • Z Offline
    Z Offline
    zmurphy
    wrote on 19 Feb 2019, 19:54 last edited by
    #1

    I'm having an issue with calls to a QSortFilterProxyModel's mapFromSource function always returning an invalid QModelIndex, regardless of the index provided. In my test case, the model has exactly 1 valid entry, but regardless of what QModelIndex I provide, it always returns invalid. Below is some of the test code I've been using.

                auto src = _sorted_view->sourceModel();
                for (int i = 0; i < src->rowCount(QModelIndex()); ++i) {
                    for (int j = 0; j < src->columnCount(QModelIndex()); ++j) {
                        QModelIndex s = src->index(i, j);
                        QModelIndex m = _meta_model->index(i, j);
                        QModelIndex v = _sorted_view->mapFromSource(s);
                        QModelIndex t = _sorted_view->mapFromSource(m);
    
                        std::string st = src->data(s).toString().toStdString();
                        std::string mt = _meta_model->data(m).toString().toStdString();
                        if (v.isValid()) { //Always invalid
                            std::string vt = _sorted_view->data(v).toString().toStdString();
                        }    
                        if (t.isValid()) { //Always invalid
                            std::string tt = _sorted_view->data(t).toString().toStdString();
                        }    
                    }    
                }
    

    In this case, _sorted_view is the QSortFilterProxyModel and _meta_model is a subclass of QAbstractItemModel. Would anyone with a better understanding of QT's model-view setup be able to tell me why the mapping here is not working? As a note, calls to mapToSource generate perfectly valid QModelIndexes, but trying to go the other way does not.

    1 Reply Last reply
    0
    • S Offline
      S Offline
      SGaist
      Lifetime Qt Champion
      wrote on 19 Feb 2019, 21:33 last edited by
      #2

      Hi and welcome to devnet,

      Why are you using indexes from two different models and map them with _sorted_view ?

      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
      • Z Offline
        Z Offline
        zmurphy
        wrote on 19 Feb 2019, 21:55 last edited by
        #3

        In this case src and _meta_model point to the same object. It's just some leftover from when I was trying to track down the issue and wanted to make sure that the view was using the model I thought it was.

        1 Reply Last reply
        0
        • S Offline
          S Offline
          SGaist
          Lifetime Qt Champion
          wrote on 19 Feb 2019, 21:57 last edited by
          #4

          Are you sure of that ? Because if they point to the same object, then the index returned should be the same. If not, then your custom model does something wrong.

          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
          • Z Offline
            Z Offline
            zmurphy
            wrote on 19 Feb 2019, 22:38 last edited by
            #5

            Yes, the indexes returned from src and _meta_model are the same. The issue is that none of the indexes returned by _sorted_view->mapFromSource are valid even though I know there is 1 valid entry and I'm iterating over every entry.

            1 Reply Last reply
            0
            • S Offline
              S Offline
              SGaist
              Lifetime Qt Champion
              wrote on 19 Feb 2019, 22:48 last edited by
              #6

              Can you show how the source model is implemented ?

              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
              • Z Offline
                Z Offline
                zmurphy
                wrote on 20 Feb 2019, 14:13 last edited by
                #7

                Yes, here's the top level class. There's a handful of subclasses but I don't believe they do interactions with the Model/View aspects.

                class CxFVariableItemModel : public QAbstractItemModel {
                
                public:
                
                    CxFVariableItemModel () : QAbstractItemModel ()
                    {   
                    }   
                    virtual ~CxFVariableItemModel () {}
                
                    const QList <QString> &headers () const { return _headers; }
                
                    virtual const QList <QString> &possibleHeaders () const = 0;
                
                    void setHeaders (const QList <QString> &headers) { 
                        emit layoutAboutToBeChanged (); 
                        _headers = headers; 
                        emit layoutChanged (); 
                    }
                
                    virtual const bool useLabels (int whichSensor) = 0;
                
                    virtual const QList <LabelReturnType> &getUsefulStrings (bool returnLabels, int whichSensor) = 0;
                
                    virtual const char *getVariableName (int whichSensor) = 0;
                
                    virtual const int getWhichRow (const char *name) = 0;
                
                    virtual const int depVarSize (int whichSensor, int i) = 0;
                
                    virtual const char *getRealDependName (const int whichSensor, const int whichDependSensor) = 0;
                
                /// Will return a list of all possible timing variable names
                    virtual const QList <QString> getListOfTimingVariableNames () = 0;
                
                /// Will return a list of all possible variable names
                    virtual const QList <QString> getListOfVariableNames () = 0;
                
                    QModelIndex index (int row, int column, const QModelIndex &parent = QModelIndex ()) const
                    {   
                        if (!hasIndex (row, column, parent)) {
                            return QModelIndex ();
                        }   
                        if (parent == QModelIndex ()) {
                            return createIndex(row, column);
                        }   
                        if (_headers [column] == "Other") {
                            return createIndex (row, column, reinterpret_cast <void *> (parent.row () + 1));
                        }   
                
                        return QModelIndex ();
                    }   
                
                    QModelIndex parent (const QModelIndex &index) const
                    {   
                // We used to have index.parent ().row () but that causes an issue when we only had one variable in the GUI.
                        long parentRow = index.row ();
                        if (parentRow == 0) return QModelIndex ();
                        else {
                            return createIndex (parentRow - 1, 0);
                        }
                    }
                
                    virtual int rowCount (const QModelIndex &parent) const = 0;
                    int columnCount (const QModelIndex &) const { return _headers.size (); }
                
                    virtual QVariant data (const QModelIndex &index, int role = Qt::DisplayRole) const = 0;
                
                    QVariant headerData (int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const
                    {
                        if (role == Qt::DisplayRole) {
                            if (orientation == Qt::Horizontal) {
                                return QVariant (_headers [section]);
                            } else { // vertical
                                return (QVariant (section));
                            }
                        }
                        return (QVariant ());
                    }
                
                protected :
                
                    QList <QString> _headers;
                };
                

                Some of this code is quite old so it may not necessarily be correct according to current Qt Model/View standards which is where I think the problem lies.

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  SGaist
                  Lifetime Qt Champion
                  wrote on 20 Feb 2019, 21:34 last edited by
                  #8

                  You can check you model implementation with the QAbstractItemModelTester. See this wiki entry.

                  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

                  3/8

                  19 Feb 2019, 21:55

                  5 unread
                  • Login

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