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.
  • X Offline
    X Offline
    xcround
    wrote on last edited by
    #13

    Hi I'm having a similar problem, where I can only select the parent nodes.
    I have the following:
    @
    bool filterAcceptsRow(int sourceRow, const QModelIndex &sourceParent)
    {
    ....
    if (!action.isEmpty())
    {
    QModelIndex index = sourceModel()->index(sourceRow,
    ACTION, sourceParent);

        for (int i = 0; i < sourceModel()->rowCount(sourceParent); i++)
        {
            QModelIndex tmpIndex = sourceModel()->index(i,0,sourceParent);
            if (tmpIndex.isValid())
                hasAcceptedChildren(tmpIndex.row(), tmpIndex);
        }
    
        if (action != sourceModel()->data(index).toString())
            return false;
    }
    

    ....
    }
    @

    Isn't this suppose to be it?
    Thanks.

    1 Reply Last reply
    0
    • 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