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. Items disappear from QComboBox when a QSortFilterProxyModel is set as the model
Forum Updated to NodeBB v4.3 + New Features

Items disappear from QComboBox when a QSortFilterProxyModel is set as the model

Scheduled Pinned Locked Moved Solved General and Desktop
3 Posts 2 Posters 669 Views 2 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.
  • D Offline
    D Offline
    DavidLobron
    wrote on last edited by
    #1

    I have a QComboBox, and I want to sort the items with a custom sort class. I read the docs for QSortFilterProxyModel, and implemented a subclass as suggested (code is below). However, when I set my QSortFilterProxyModel as the model for my QComboBox, all of the items I've added disappear!

    My QSortFilterProxyModel subclass looks like this:

    class FactorSortBySourceNodeFilterProxyModel : public QSortFilterProxyModel {
      Q_OBJECT
    
     public:
      FactorSortBySourceNodeFilterProxyModel(QObject* parent = nullptr);
      void AddFactorSourceIdPair(int factor_id,int node_id);
    
     protected:
      bool lessThan(const QModelIndex& left, const QModelIndex& right) const override;
    
     private:
      std::unordered_map<int,int> factor_source_node_id_;
    };
    

    The above class has a custom lessThan method that looks up items by factor_id and sorts by the corresponding node_id.

    I'm using it like this (here, this is a QObject subclass, and factor_browser_ is a QComboBox ):

      factor_browser_ = new QComboBox(widget_);
      FactorSortBySourceNodeFilterProxyModel* proxy_model =
          new FactorSortBySourceNodeFilterProxyModel(this);
      proxy_model->setSourceModel(factor_browser_->model());
      factor_browser_->setModel(proxy_model);
      for (const auto& factor_ptr : all_factors) {
        const QString factor_id_string = "custom-string-here"
        QVariant factor_id_data;
        factor_id_data.setValue(factor_ptr->GetFactorId());
        factor_browser_->addItem(factor_id_string, factor_id_data);
        proxy_model->AddFactorSourceIdPair(factor_ptr->GetFactorId(),
                                           factor_ptr->->GetNodeId());
      }
      factor_browser_->model()->sort(0);
    

    I added some print statements to the AddFactorSourceIdPair method, and confirmed that it's called as expected. But when sort is called, the model contains no items, even though I'm adding several items with the addItem call in the loop! I printed factor_browser_->model()->rowCount(), and it's zero. I'd welcome any hints as to what I'm doing wrong here. Thanks!

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

      Hi and welcome to devnet,

      What if you return always true for testing lessThan ?

      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
      • D Offline
        D Offline
        DavidLobron
        wrote on last edited by DavidLobron
        #3

        Thank you for the reply! I actually just solved this, with the help of this StackOverflow post. The problem was that the setModel call was deleting the QComboBox's internal model. The key is to create a new QStandardItemModel, set it as the source model for the proxy, add data to that model, and sort it. Then, in the last step, set the proxy as the container's model with setModel. Rough outline:

        QStandardItemModel* model = new QStandardItemModel(this);
         FactorSortBySourceNodeFilterProxyModel* proxy_model =
              new FactorSortBySourceNodeFilterProxyModel(this);
        proxy_model->setSourceModel(model);
        

        In the code above, FactorSortBySourceNodeFilterProxyModel is a subclass of QSortFilterProxyModel.

        Then, in a loop, I call model->appendRow(new QStandardItem(my-data-here)); repeatedly. Lastly, I do this:

          proxy_model->sort(0);
          factor_browser_->setModel(proxy_model);
        

        Here, factor_browser_ is my QComboBox. The items are now sorted with the custom lessThan that my FactorSortBySourceNodeFilterProxyModel implements.

        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