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. How to sort item names in treeview alphabetically ignorent of the case?
Forum Updated to NodeBB v4.3 + New Features

How to sort item names in treeview alphabetically ignorent of the case?

Scheduled Pinned Locked Moved Unsolved General and Desktop
15 Posts 3 Posters 1.3k 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.
  • M Offline
    M Offline
    MNGL
    wrote on last edited by MNGL
    #3

    Thanks, @JonB

    I tried the option 1, it worked, but it did not work with code in BOLD:
    Is there any way to make the setItemDelegate to work with QSortFilterProxyModel object?

    RegistryTreeView::RegistryTreeView(Registry &inRegistry, QWidget *inParent)
    {
        mModel = new RegistryItemModel;
        mModel->setRegistry(&inRegistry);
    
        QSortFilterProxyModel *ProxyModel = new QSortFilterProxyModel(this);
        ProxyModel->setSourceModel(mModel);
        ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
        ProxyModel->sort(0, Qt::AscendingOrder);
    
        mTreeView = new QTreeView;
        mTreeView->setContextMenuPolicy(Qt::DefaultContextMenu);
        mTreeView->setModel(ProxyModel);
        **mTreeView->setItemDelegate(new RegistryItemDelegate(mModel));** //this line will cause abend.
        mTreeView->installEventFilter(new AutoSelectEventFilter(this));
        
        mainLayout->addWidget(mTreeView);
        
    }
    
    class RegistryItemDelegate : public QStyledItemDelegate
    {
        Q_OBJECT;
    
    public:
    
        RegistryItemDelegate(RegistryItemModel *inModel, QObject *inParent=NULL);
        //RegistryItemDelegate(QSortFilterProxyModel *inModel, QObject *inParent=NULL);
        virtual ~RegistryItemDelegate();
    
    protected:
        virtual void initStyleOption(QStyleOptionViewItem *inOption, const QModelIndex &inIndex) const;
    
    
    private:
        RegistryItemModel *mModel;
    	
        QColor mModifiedColor;
        QIcon mFolderIcon;
    };
    
    B JonBJ 2 Replies Last reply
    0
    • M MNGL

      Thanks, @JonB

      I tried the option 1, it worked, but it did not work with code in BOLD:
      Is there any way to make the setItemDelegate to work with QSortFilterProxyModel object?

      RegistryTreeView::RegistryTreeView(Registry &inRegistry, QWidget *inParent)
      {
          mModel = new RegistryItemModel;
          mModel->setRegistry(&inRegistry);
      
          QSortFilterProxyModel *ProxyModel = new QSortFilterProxyModel(this);
          ProxyModel->setSourceModel(mModel);
          ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
          ProxyModel->sort(0, Qt::AscendingOrder);
      
          mTreeView = new QTreeView;
          mTreeView->setContextMenuPolicy(Qt::DefaultContextMenu);
          mTreeView->setModel(ProxyModel);
          **mTreeView->setItemDelegate(new RegistryItemDelegate(mModel));** //this line will cause abend.
          mTreeView->installEventFilter(new AutoSelectEventFilter(this));
          
          mainLayout->addWidget(mTreeView);
          
      }
      
      class RegistryItemDelegate : public QStyledItemDelegate
      {
          Q_OBJECT;
      
      public:
      
          RegistryItemDelegate(RegistryItemModel *inModel, QObject *inParent=NULL);
          //RegistryItemDelegate(QSortFilterProxyModel *inModel, QObject *inParent=NULL);
          virtual ~RegistryItemDelegate();
      
      protected:
          virtual void initStyleOption(QStyleOptionViewItem *inOption, const QModelIndex &inIndex) const;
      
      
      private:
          RegistryItemModel *mModel;
      	
          QColor mModifiedColor;
          QIcon mFolderIcon;
      };
      
      B Offline
      B Offline
      Bonnie
      wrote on last edited by Bonnie
      #4

      @MNGL What's your RegistryItemModel's base class?
      If it is subclassed from QStandardItemModel, I'd just add one custom role for sorting, something like

      const int sort_role = Qt::UserRole + 1;
      
      RegistryItemModel() {
          ...
          setSortRole(sort_role);
          ...
      }
      

      And save toLower() of the original text in every item's sort_role data

      1 Reply Last reply
      0
      • M MNGL

        Thanks, @JonB

        I tried the option 1, it worked, but it did not work with code in BOLD:
        Is there any way to make the setItemDelegate to work with QSortFilterProxyModel object?

        RegistryTreeView::RegistryTreeView(Registry &inRegistry, QWidget *inParent)
        {
            mModel = new RegistryItemModel;
            mModel->setRegistry(&inRegistry);
        
            QSortFilterProxyModel *ProxyModel = new QSortFilterProxyModel(this);
            ProxyModel->setSourceModel(mModel);
            ProxyModel->setSortCaseSensitivity(Qt::CaseInsensitive);
            ProxyModel->sort(0, Qt::AscendingOrder);
        
            mTreeView = new QTreeView;
            mTreeView->setContextMenuPolicy(Qt::DefaultContextMenu);
            mTreeView->setModel(ProxyModel);
            **mTreeView->setItemDelegate(new RegistryItemDelegate(mModel));** //this line will cause abend.
            mTreeView->installEventFilter(new AutoSelectEventFilter(this));
            
            mainLayout->addWidget(mTreeView);
            
        }
        
        class RegistryItemDelegate : public QStyledItemDelegate
        {
            Q_OBJECT;
        
        public:
        
            RegistryItemDelegate(RegistryItemModel *inModel, QObject *inParent=NULL);
            //RegistryItemDelegate(QSortFilterProxyModel *inModel, QObject *inParent=NULL);
            virtual ~RegistryItemDelegate();
        
        protected:
            virtual void initStyleOption(QStyleOptionViewItem *inOption, const QModelIndex &inIndex) const;
        
        
        private:
            RegistryItemModel *mModel;
        	
            QColor mModifiedColor;
            QIcon mFolderIcon;
        };
        
        JonBJ Online
        JonBJ Online
        JonB
        wrote on last edited by
        #5

        @MNGL said in How to sort item names in treeview alphabetically ignorent of the case?:

        **mTreeView->setItemDelegate(new RegistryItemDelegate(mModel));** //this line will cause abend.

        I don't know what abend means. Find out whether there is a problem with the new RegistryItemDelegate(mModel) or with the mTreeView->setItemDelegate().

        1 Reply Last reply
        0
        • M Offline
          M Offline
          MNGL
          wrote on last edited by
          #6

          class RegistryItemModel : public QAbstractItemModel
          {
          Q_OBJECT;

          public:
          RegistryItemModel(QWidget *parent=NULL);
          virtual ~RegistryItemModel();
          ......
          }

          if I don't comment out following line, the program will crash before the Main Window is launched.

          mTreeView->setItemDelegate(new RegistryItemDelegate(mModel));
          
          JonBJ 1 Reply Last reply
          0
          • M MNGL

            class RegistryItemModel : public QAbstractItemModel
            {
            Q_OBJECT;

            public:
            RegistryItemModel(QWidget *parent=NULL);
            virtual ~RegistryItemModel();
            ......
            }

            if I don't comment out following line, the program will crash before the Main Window is launched.

            mTreeView->setItemDelegate(new RegistryItemDelegate(mModel));
            
            JonBJ Online
            JonBJ Online
            JonB
            wrote on last edited by JonB
            #7

            @MNGL
            Yes, you said that earlier. Already suggested what you should do next. Also you can see the cause of "crashes" from the debugger.

            1 Reply Last reply
            0
            • M Offline
              M Offline
              MNGL
              wrote on last edited by
              #8

              Thanks, @JonB JonB
              QAbstractItemModel does not have a function called setSortRole.

              Here is the crash screenshot:

              abend.JPG abend2.JPG

              JonBJ 1 Reply Last reply
              0
              • M Offline
                M Offline
                MNGL
                wrote on last edited by
                #9

                Does anyone have the code example on how to override the virtual QAbstractItemModel::sort() to implement case-insensitive sorting?

                1 Reply Last reply
                0
                • M MNGL

                  Thanks, @JonB JonB
                  QAbstractItemModel does not have a function called setSortRole.

                  Here is the crash screenshot:

                  abend.JPG abend2.JPG

                  JonBJ Online
                  JonBJ Online
                  JonB
                  wrote on last edited by JonB
                  #10

                  @MNGL said in How to sort item names in treeview alphabetically ignorent of the case?:

                  Thanks, @JonB JonB
                  QAbstractItemModel does not have a function called setSortRole.

                  It was @Bonnie who suggested that, if you had been using QStandardItemModel.

                  Here is the crash screenshot:

                  I'm not sure of the reason. It comes in your RegistryItemDelegate::initStyleOption() override, whose code so far you have steadfastly refused to show. When you create it you pass it mModel (I don't know why, I don't think you should be doing this), which is your source model. But the treeview is attached to the QSortFilterProxyModel model. At a guess, the QModelIndex &inIndex being passed is an index into the proxy model, but you are using it to index into the source model??

                  M 1 Reply Last reply
                  0
                  • JonBJ JonB

                    @MNGL said in How to sort item names in treeview alphabetically ignorent of the case?:

                    Thanks, @JonB JonB
                    QAbstractItemModel does not have a function called setSortRole.

                    It was @Bonnie who suggested that, if you had been using QStandardItemModel.

                    Here is the crash screenshot:

                    I'm not sure of the reason. It comes in your RegistryItemDelegate::initStyleOption() override, whose code so far you have steadfastly refused to show. When you create it you pass it mModel (I don't know why, I don't think you should be doing this), which is your source model. But the treeview is attached to the QSortFilterProxyModel model. At a guess, the QModelIndex &inIndex being passed is an index into the proxy model, but you are using it to index into the source model??

                    M Offline
                    M Offline
                    MNGL
                    wrote on last edited by MNGL
                    #11

                    @JonB

                    class RegistryItemDelegate : public QStyledItemDelegate
                    {
                        Q_OBJECT;
                    
                    public:
                    
                      //RegistryItemDelegate(RegistryItemModel *inModel, QObject *inParent=NULL);
                        RegistryItemDelegate(QSortFilterProxyModel *mModel, QObject *inParent=NULL);
                        virtual ~RegistryItemDelegate();
                    
                    protected:
                        virtual void initStyleOption(QStyleOptionViewItem *inOption, const QModelIndex &inIndex) const;
                    
                    
                    private:
                      //RegistryItemModel *mModel;
                        QSortFilterProxyModel *mModel;
                        QColor mModifiedColor;
                        QIcon mFolderIcon;
                    };
                    
                    void RegistryItemDelegate::initStyleOption(QStyleOptionViewItem *inOption, const QModelIndex &inIndex) const
                    {
                        QStyledItemDelegate::initStyleOption(inOption, inIndex);
                    
                        const Node *node = mModel->node(inIndex); //error C2039: 'node' : is not a member of 'QSortFilterProxyModel'
                        if(node == NULL)
                            return;
                    
                        if(!node->isDefault())
                            inOption->palette.setColor(QPalette::Text, mModifiedColor);
                    
                        if(node->nodeType() == eRegDir && inOption->version == 4)
                        { 
                            ((QStyleOptionViewItemV4*)inOption)->features |= QStyleOptionViewItemV2::HasDecoration;
                            ((QStyleOptionViewItemV4*)inOption)->icon = mFolderIcon;
                        }
                    }
                    

                    if I change the type of mModel from RegistryItemModel to QSortFilterProxyModel, I got following error:

                    error C2039: 'node' : is not a member of 'QSortFilterProxyModel'

                    JonBJ 1 Reply Last reply
                    0
                    • M MNGL

                      @JonB

                      class RegistryItemDelegate : public QStyledItemDelegate
                      {
                          Q_OBJECT;
                      
                      public:
                      
                        //RegistryItemDelegate(RegistryItemModel *inModel, QObject *inParent=NULL);
                          RegistryItemDelegate(QSortFilterProxyModel *mModel, QObject *inParent=NULL);
                          virtual ~RegistryItemDelegate();
                      
                      protected:
                          virtual void initStyleOption(QStyleOptionViewItem *inOption, const QModelIndex &inIndex) const;
                      
                      
                      private:
                        //RegistryItemModel *mModel;
                          QSortFilterProxyModel *mModel;
                          QColor mModifiedColor;
                          QIcon mFolderIcon;
                      };
                      
                      void RegistryItemDelegate::initStyleOption(QStyleOptionViewItem *inOption, const QModelIndex &inIndex) const
                      {
                          QStyledItemDelegate::initStyleOption(inOption, inIndex);
                      
                          const Node *node = mModel->node(inIndex); //error C2039: 'node' : is not a member of 'QSortFilterProxyModel'
                          if(node == NULL)
                              return;
                      
                          if(!node->isDefault())
                              inOption->palette.setColor(QPalette::Text, mModifiedColor);
                      
                          if(node->nodeType() == eRegDir && inOption->version == 4)
                          { 
                              ((QStyleOptionViewItemV4*)inOption)->features |= QStyleOptionViewItemV2::HasDecoration;
                              ((QStyleOptionViewItemV4*)inOption)->icon = mFolderIcon;
                          }
                      }
                      

                      if I change the type of mModel from RegistryItemModel to QSortFilterProxyModel, I got following error:

                      error C2039: 'node' : is not a member of 'QSortFilterProxyModel'

                      JonBJ Online
                      JonBJ Online
                      JonB
                      wrote on last edited by JonB
                      #12

                      @MNGL
                      OK. But I still don't know why you pass a mModel parameter to your delegate. I would be getting the model from the QModelIndex &inIndex() passed to initStyleOption().

                      If your screenshot shows it is crashing on the node->isDefault() line, what is a Node, how does mModel->node(inIndex) work, what is Node::isDefault()? Have you compiled for Debug with no code optimizations? Just in case the line is misleading, Q_ASSERT(mModel). Otherwise it looks like node is 0/nullptr for the exception at 0x00000000, though you test for that, so presumably it can't be....

                      BTW, you have not said, but are you still using Qt4 (it looks like you are), not Qt5/6??

                      M 2 Replies Last reply
                      0
                      • JonBJ JonB

                        @MNGL
                        OK. But I still don't know why you pass a mModel parameter to your delegate. I would be getting the model from the QModelIndex &inIndex() passed to initStyleOption().

                        If your screenshot shows it is crashing on the node->isDefault() line, what is a Node, how does mModel->node(inIndex) work, what is Node::isDefault()? Have you compiled for Debug with no code optimizations? Just in case the line is misleading, Q_ASSERT(mModel). Otherwise it looks like node is 0/nullptr for the exception at 0x00000000, though you test for that, so presumably it can't be....

                        BTW, you have not said, but are you still using Qt4 (it looks like you are), not Qt5/6??

                        M Offline
                        M Offline
                        MNGL
                        wrote on last edited by
                        #13
                        This post is deleted!
                        1 Reply Last reply
                        0
                        • JonBJ JonB

                          @MNGL
                          OK. But I still don't know why you pass a mModel parameter to your delegate. I would be getting the model from the QModelIndex &inIndex() passed to initStyleOption().

                          If your screenshot shows it is crashing on the node->isDefault() line, what is a Node, how does mModel->node(inIndex) work, what is Node::isDefault()? Have you compiled for Debug with no code optimizations? Just in case the line is misleading, Q_ASSERT(mModel). Otherwise it looks like node is 0/nullptr for the exception at 0x00000000, though you test for that, so presumably it can't be....

                          BTW, you have not said, but are you still using Qt4 (it looks like you are), not Qt5/6??

                          M Offline
                          M Offline
                          MNGL
                          wrote on last edited by
                          #14

                          @JonB strikethrough text

                          it's obviously that object of QSortFilterProxyModel cannot replace the mModel of RegistryItemModel.
                          I'm using Qt 4.8.7, and what about override the QAbstractItemModel::sort() to implement your own case-insensitive sorting, where can find a code example?

                          1 Reply Last reply
                          0
                          • M Offline
                            M Offline
                            MNGL
                            wrote on last edited by MNGL
                            #15

                            Here is the code change that fixed the crash:

                            void RegistryItemDelegate::initStyleOption(QStyleOptionViewItem *inOption, const QModelIndex &inIndex) const
                            {
                                QStyledItemDelegate::initStyleOption(inOption, inIndex);
                            
                                //const Node *node = mModel->node(inIndex);
                                const Node* node = nullptr;  //code change start
                            
                                QModelIndex sourceIndex = inIndex;
                                auto proxyModel = dynamic_cast<const QAbstractProxyModel*>(sourceIndex.model());
                                //We map the index back to its source as many times as needed.
                                //We expect to do it once for now but that may change in the future.
                                while (proxyModel) {
                                      sourceIndex = proxyModel->mapToSource(sourceIndex);
                                      proxyModel = dynamic_cast<const QAbstractProxyModel*>(sourceIndex.model());
                                }
                               
                                auto regModel = dynamic_cast<const RegistryItemModel*>(sourceIndex.model()) ;
                                if (regModel)
                                node = regModel->node(sourceIndex);  //code change end
                            	
                                if(node == NULL)
                                    return;
                            
                                if(!node->isDefault())
                                    inOption->palette.setColor(QPalette::Text, mModifiedColor);
                            
                                if(node->nodeType() == eRegDir && inOption->version == 4)
                                { 
                                    ((QStyleOptionViewItemV4*)inOption)->features |= QStyleOptionViewItemV2::HasDecoration;
                                    ((QStyleOptionViewItemV4*)inOption)->icon = mFolderIcon;
                                }
                            }
                            
                            1 Reply Last reply
                            1

                            • Login

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