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. Connect model to different views with different display roles

Connect model to different views with different display roles

Scheduled Pinned Locked Moved Unsolved General and Desktop
5 Posts 3 Posters 1.7k 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.
  • D Offline
    D Offline
    Dagginio
    wrote on last edited by
    #1

    Hello,

    I created my own class derived from QAbstractItemModel for displaying data in a tree view. Additionally I used a qsortfilterproxymodel for sorting and filtering. Now I want to display parts of the data in a comboBox as well, but the display role must be different, as I want to show something else there. The source model should be the same for both widgets but of course I can create a new proxy model just for the comboBox. Can I somehow tell the comboBox or the proxymodel, that it should take another user defined role for displaying the data? I have already overwritten the roleNames method of my proxymodel, but without success. I even do not know if this would be the right approach. Furthermore, I want to show in the comboBox all the data of the top level nodes, but also of the children of the top level nodes (not the children of the children...). How to achieve that? The question is more general and therefore I do not think that it is necessary to post my code here. I would be very happy to get some hints.

    Thanks a lot.
    Daniel

    raven-worxR VRoninV 2 Replies Last reply
    0
    • D Dagginio

      Hello,

      I created my own class derived from QAbstractItemModel for displaying data in a tree view. Additionally I used a qsortfilterproxymodel for sorting and filtering. Now I want to display parts of the data in a comboBox as well, but the display role must be different, as I want to show something else there. The source model should be the same for both widgets but of course I can create a new proxy model just for the comboBox. Can I somehow tell the comboBox or the proxymodel, that it should take another user defined role for displaying the data? I have already overwritten the roleNames method of my proxymodel, but without success. I even do not know if this would be the right approach. Furthermore, I want to show in the comboBox all the data of the top level nodes, but also of the children of the top level nodes (not the children of the children...). How to achieve that? The question is more general and therefore I do not think that it is necessary to post my code here. I would be very happy to get some hints.

      Thanks a lot.
      Daniel

      raven-worxR Offline
      raven-worxR Offline
      raven-worx
      Moderators
      wrote on last edited by raven-worx
      #2

      @Dagginio said in Connect model to different views with different display roles:

      Can I somehow tell the comboBox or the proxymodel, that it should take another user defined role for displaying the data?

      subclass QIdentityProxyModel
      Then you can add a property to your custom proxymodel subclass to tell which Role to use instead of the source model's Qt::DisplayRole

      --- SUPPORT REQUESTS VIA CHAT WILL BE IGNORED ---
      If you have a question please use the forum so others can benefit from the solution in the future

      D 1 Reply Last reply
      2
      • raven-worxR raven-worx

        @Dagginio said in Connect model to different views with different display roles:

        Can I somehow tell the comboBox or the proxymodel, that it should take another user defined role for displaying the data?

        subclass QIdentityProxyModel
        Then you can add a property to your custom proxymodel subclass to tell which Role to use instead of the source model's Qt::DisplayRole

        D Offline
        D Offline
        Dagginio
        wrote on last edited by
        #3

        @raven-worx
        Thanks for the fast reply. I think that helps already. Will try and let you know.

        Daniel

        1 Reply Last reply
        0
        • D Dagginio

          Hello,

          I created my own class derived from QAbstractItemModel for displaying data in a tree view. Additionally I used a qsortfilterproxymodel for sorting and filtering. Now I want to display parts of the data in a comboBox as well, but the display role must be different, as I want to show something else there. The source model should be the same for both widgets but of course I can create a new proxy model just for the comboBox. Can I somehow tell the comboBox or the proxymodel, that it should take another user defined role for displaying the data? I have already overwritten the roleNames method of my proxymodel, but without success. I even do not know if this would be the right approach. Furthermore, I want to show in the comboBox all the data of the top level nodes, but also of the children of the top level nodes (not the children of the children...). How to achieve that? The question is more general and therefore I do not think that it is necessary to post my code here. I would be very happy to get some hints.

          Thanks a lot.
          Daniel

          VRoninV Offline
          VRoninV Offline
          VRonin
          wrote on last edited by VRonin
          #4
          
          class ComboProxy : public QIdentityProxyModel
          {
              Q_OBJECT
              Q_PROPERTY(int displayRole READ displayRole WRITE setDisplayRole NOTIFY displayRoleChanged)
              Q_DISABLE_COPY(ComboProxy)
          public:
              ComboProxy(QObject* parent = Q_NULLPTR)
                  :QIdentityProxyModel(parent)
                  , m_displayRole(Qt::DisplayRole)
              {}
              QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE{
                  if (role == Qt::DisplayRole) role = m_displayRole;
                  return QIdentityProxyModel::data(index, role);
              }
                  // The next two are to only display top level and 1st generation children
              bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE{
                  if (parent.parent().parent().isValid()) return false;
                  return QIdentityProxyModel::hasChildren(parent);
              }
              int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE{
                  if (parent.parent().parent().isValid()) return 0;
                  return QIdentityProxyModel::hasChildren(parent);
              }
              int displayRole() const { return m_displayRole; }
              Q_SIGNAL void displayRoleChanged(int role);
              void setDisplayRole(int role)
              {
                  if (role == m_displayRole) return;
                  m_displayRole = role;
                  displayRoleChanged(role);
                  emitAllDataChanged();
              }
          private:
              void emitAllDataChanged(const QModelIndex& parent = QModelIndex())
              {
                  const int rows = rowCount(parent);
                  const int columns = columnCount(parent);
                  dataChanged(index(0, 0, parent), index(rows - 1, columns - 1, parent), QVector<int>() << Qt::DisplayRole);
                  for (int i = 0; i < rows; ++i) {
                      for (int j = 0; j < columns; ++j) {
                          const QModelIndex currIdx = index(i, j, parent);
                          if (hasChildren(currIdx))
                              emitAllDataChanged(currIdx);
                      }
                  }
              }
              int m_displayRole;
          };
          

          You'll then have to call QCombobox::setView to set a treeview.
          If, instead, you want the 1st generation child to be displayed in a list at the same level as top level items just put a KDescendantsProxyModel inbetween

          "La mort n'est rien, mais vivre vaincu et sans gloire, c'est mourir tous les jours"
          ~Napoleon Bonaparte

          On a crusade to banish setIndexWidget() from the holy land of Qt

          D 1 Reply Last reply
          2
          • VRoninV VRonin
            
            class ComboProxy : public QIdentityProxyModel
            {
                Q_OBJECT
                Q_PROPERTY(int displayRole READ displayRole WRITE setDisplayRole NOTIFY displayRoleChanged)
                Q_DISABLE_COPY(ComboProxy)
            public:
                ComboProxy(QObject* parent = Q_NULLPTR)
                    :QIdentityProxyModel(parent)
                    , m_displayRole(Qt::DisplayRole)
                {}
                QVariant data(const QModelIndex &index, int role = Qt::DisplayRole) const Q_DECL_OVERRIDE{
                    if (role == Qt::DisplayRole) role = m_displayRole;
                    return QIdentityProxyModel::data(index, role);
                }
                    // The next two are to only display top level and 1st generation children
                bool hasChildren(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE{
                    if (parent.parent().parent().isValid()) return false;
                    return QIdentityProxyModel::hasChildren(parent);
                }
                int rowCount(const QModelIndex &parent = QModelIndex()) const Q_DECL_OVERRIDE{
                    if (parent.parent().parent().isValid()) return 0;
                    return QIdentityProxyModel::hasChildren(parent);
                }
                int displayRole() const { return m_displayRole; }
                Q_SIGNAL void displayRoleChanged(int role);
                void setDisplayRole(int role)
                {
                    if (role == m_displayRole) return;
                    m_displayRole = role;
                    displayRoleChanged(role);
                    emitAllDataChanged();
                }
            private:
                void emitAllDataChanged(const QModelIndex& parent = QModelIndex())
                {
                    const int rows = rowCount(parent);
                    const int columns = columnCount(parent);
                    dataChanged(index(0, 0, parent), index(rows - 1, columns - 1, parent), QVector<int>() << Qt::DisplayRole);
                    for (int i = 0; i < rows; ++i) {
                        for (int j = 0; j < columns; ++j) {
                            const QModelIndex currIdx = index(i, j, parent);
                            if (hasChildren(currIdx))
                                emitAllDataChanged(currIdx);
                        }
                    }
                }
                int m_displayRole;
            };
            

            You'll then have to call QCombobox::setView to set a treeview.
            If, instead, you want the 1st generation child to be displayed in a list at the same level as top level items just put a KDescendantsProxyModel inbetween

            D Offline
            D Offline
            Dagginio
            wrote on last edited by
            #5

            @VRonin said in Connect model to different views with different display roles:

            KDescendantsProxyModel

            Hey,

            thanks a lot. Using another displayRole in the combo is working fine. However I am still stucking with the data of the top level's children. Since I am using PyQt, I think I cannot use KDE. The last update of PyKDE was in 2013 and I do not find an appropriate wheel for installation. Is there another way with pure Qt (PyQt) components?

            Thanks
            Daniel

            1 Reply Last reply
            0

            • Login

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