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 -filterAcceptsRow()- filter parent Node and child Node
Forum Updated to NodeBB v4.3 + New Features

QSortFilterProxyModel -filterAcceptsRow()- filter parent Node and child Node

Scheduled Pinned Locked Moved General and Desktop
28 Posts 8 Posters 32.5k Views 1 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.
  • M Offline
    M Offline
    ManasQt
    wrote on last edited by
    #14

    Hi xcround,

         I am not clear , are you trying to filter parent as well as child?  
    

    I have accomplished this and here is the logic,

    @def filterAcceptsRow(self,sourceRow,sourceParent):
    if super(MySortFilterProxyModel,self).filterAcceptsRow(sourceRow,sourceParent):
    return True
    return self.hasAcceptedChildren(sourceRow,sourceParent)

    def hasAcceptedChildren(self,sourceRow,sourceParent):
    model=self.sourceModel()
    sourceIndex=model.index(sourceRow,0,sourceParent)
    if not sourceIndex.isValid():
    return False
    indexes=model.rowCount(sourceIndex)
    for i in range(indexes):
    if self.filterAcceptsRow(i,sourceIndex):
    return True
    return False

    @

    1 Reply Last reply
    0
    • X Offline
      X Offline
      xcround
      wrote on last edited by
      #15

      Yes, I would like to filter both parent and child.
      Also I forgot to mention, I have a return true in the end of the function.
      Thanks

      1 Reply Last reply
      0
      • X Offline
        X Offline
        xcround
        wrote on last edited by
        #16

        Here is the what I have now, but still is not filtering the parents and child.
        @
        bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent)
        {
        ....
        if (!action.isEmpty())
        {

            QModelIndex index = sourceModel()->index(sourceRow,
                                                     ACTION, sourceParent);
        
            if (hasAcceptedChildren(sourceRow, sourceParent))
                return true;
        
            if (action != sourceModel()->data(index).toString())
                return false;
        }
        return true;
        

        }
        bool TableProxy::filterAcceptsRowItself(int sourceRow, const QModelIndex &sourceParent) const
        {
        return QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent);
        }

        bool TableProxy::hasAcceptedChildren(int source_row, const QModelIndex &source_parent) const
        {
        QModelIndex item = source_parent;
        if (!item.isValid())
        {
        qDebug() << "item invalid" << source_parent.data().toString() << source_row;
        return false;
        }
        int childCount = item.model()->rowCount(item);

        if (childCount == 0)
            return false;
        
        for (int i = 0; i < childCount; ++i)
        {
            if (filterAcceptsRowItself(i, item))
                return true;
            //recursive call
            if (hasAcceptedChildren(i, item))
                return true;
        }
        
        return false;
        

        }
        @
        Thanks for the help

        1 Reply Last reply
        0
        • M Offline
          M Offline
          ManasQt
          wrote on last edited by
          #17

          Hi xcround,
          please make changes in your code according this python code and i am sure it will filter parent as well as child .
          @
          def filterAcceptsRow(self,sourceRow,sourceParent):
          if super(MySortFilterProxyModel,self).filterAcceptsRow(sourceRow,sourceParent):
          return True
          return self.hasAcceptedChildren(sourceRow,sourceParent)

          def hasAcceptedChildren(self,sourceRow,sourceParent):
          model=self.sourceModel()
          sourceIndex=model.index(sourceRow,0,sourceParent)
          if not sourceIndex.isValid():
          return False
          indexes=model.rowCount(sourceIndex)
          for i in range(indexes):
          if self.filterAcceptsRow(i,sourceIndex):
          return True
          return False@

          1 Reply Last reply
          0
          • M Offline
            M Offline
            ManasQt
            wrote on last edited by
            #18

            Hi xcround,
            I think in your case it would be some thing like this needs to be......
            ( i am not a c/c++ guy)
            @
            bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent)
            {
            ....
            if (!action.isEmpty())
            {
            if (QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent))
            {
            return true
            }
            return hasAcceptedChildren(sourceRow, sourceParent)
            }
            .........
            }

            bool TableProxy::hasAcceptedChildren(int source_row, const QModelIndex &source_parent) const
            {
            QModelIndex item = source_parent;
            if (!item.isValid())
            {
            qDebug() << "item invalid" << source_parent.data().toString() << source_row;
            return false;
            }
            int childCount = item.model()->rowCount(item);

            if (childCount == 0)
                return false;
            
            for (int i = 0; i < childCount; ++i)
            {
                if (filterAcceptsRow(i, item))
                    return true;
            }
            
            return false;
            

            }@

            1 Reply Last reply
            0
            • X Offline
              X Offline
              xcround
              wrote on last edited by
              #19

              Sorry but from mine understanding I first need to check if the string matches the one I'm looking for.
              So that's why I have the first if statement, and then I do what you said in the previous post.
              @
              f (!action.isEmpty())
              {
              QModelIndex index = sourceModel()->index(sourceRow,
              ACTION, sourceParent);

                      if (action != sourceModel()->data(index).toString())
                          return false;
              
                      if ((QSortFilterProxyModel::filterAcceptsRow(sourceRow, sourceParent)))
                          return true;
              
                      return hasAcceptedChildren(sourceRow, sourceParent);
                  }
              

              @
              Still trying to understand whats going wrong.

              1 Reply Last reply
              0
              • B Offline
                B Offline
                burgerking
                wrote on last edited by
                #20

                Hi qties,

                at the first time I read the post from André I was so happy to find the solution I am searching for.
                But unfortunately I am to stupid to get it work. Maybe you can help me.

                If I use the standard QSortFilterProxyModel everything works good except the search at textChanged Signal.
                But if I use the LeafFilterProxyModel (exactly as André has post it) an error occurs and I do not know what it means.

                I hope somebady can help me.
                Thank you.

                @
                LeafFilterProxyModel m_oProxyModel;
                //QSortFilterProxyModel m_oProxyModel;
                QStandardItemModel m_oItemModel; // manualy filled

                m_oProxyModel.setSourceModel(&m_oItemModel);
                m_tvDBC->setModel(&m_oProxyModel); // TreeView
                m_lvDBC->setModel(&m_oStringModel); // ListView
                @

                @
                void cClass::textChanged(QString text)
                {
                QRegExp::PatternSyntax pSyntax = QRegExp::PatternSyntax(QRegExp::FixedString);
                QRegExp regExp(text, Qt::CaseInsensitive, pSyntax);

                m_oProxyModel.setFilterRegExp(regExp);
                m_oProxyModel.setFilterKeyColumn(-1);
                }
                @

                @
                Error 1 error LNK2001: unresolved external symbol "public: __thiscall
                LeafFilterProxyModel::LeafFilterProxyModel(class QObject *)"
                ??0LeafFilterProxyModel@@QAE@PAVQObject@@@Z) myobject.obj
                @

                1 Reply Last reply
                0
                • A Offline
                  A Offline
                  andre
                  wrote on last edited by
                  #21

                  Sounds like you forgot to add the .h file to your HEADERS section in your .pro file, and the .cpp file to the SOURCES section?

                  1 Reply Last reply
                  0
                  • R Offline
                    R Offline
                    Ruzik
                    wrote on last edited by
                    #22

                    What does _parent type in this string?
                    @bool filterAcceptsRow(int source_row, const QModelIndex &source;_parent) const;@
                    And wath does this argument do?
                    And second question:
                    source_parent is source->parent()?
                    And in advance sorry for stupid questions)

                    1 Reply Last reply
                    0
                    • A Offline
                      A Offline
                      andre
                      wrote on last edited by
                      #23

                      There was an unfortunate bug at the time in DevNet, that sometimes inserted ; at the wrong places in code sections. The code listing I posted suffered from this. The argument is supposed to be a single argument source_parent. I'll try to fixup the original posting. Thanks for noticing.

                      1 Reply Last reply
                      0
                      • R Offline
                        R Offline
                        Ruzik
                        wrote on last edited by
                        #24

                        It is clear.
                        One more thank you for your help!

                        1 Reply Last reply
                        0
                        • F Offline
                          F Offline
                          frankiefrank
                          wrote on last edited by
                          #25

                          Thank you - this thread has been really helpful!

                          "Roads? Where we're going, we don't need roads."

                          1 Reply Last reply
                          0
                          • B Offline
                            B Offline
                            bycross028
                            wrote on last edited by
                            #26

                            Esta implementación recorre todo los sub-Nodos del padre buscando que el filterRegExp coincida con el Qt::DisplayRole del sub-Nodo.

                            El algoritmo no utiliza recursividad :D

                            @bool SortFilterProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
                            {
                            QList<QModelIndex> children;
                            children << sourceModel()->index(source_row, 0, source_parent);

                            bool show = false;
                            for(int i = 0; i < children.length(); i++)
                            {
                                if(show) break;
                            
                                // Add sub Nodos
                                //
                                for(int c = 0; c < sourceModel()->rowCount(children[i]) ;c++)
                                    children.append(children[i].child(c,0));
                            
                                QString type = sourceModel()->data(children[i], Qt::DisplayRole).toString();
                                show = type.contains(filterRegExp());        
                            }
                            return show;
                            

                            }@

                            1 Reply Last reply
                            0
                            • A Offline
                              A Offline
                              andre
                              wrote on last edited by
                              #27

                              Could you keep posts to English in this forum please? There are specialized sub-forums for other languages.

                              1 Reply Last reply
                              0
                              • A Offline
                                A Offline
                                andre
                                wrote on last edited by
                                #28

                                Could you keep posts to English in this forum please? There are specialized sub-forums for other languages.

                                1 Reply Last reply
                                0
                                • P pchar2 referenced this topic on
                                • P pchar2 referenced this topic on

                                • Login

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