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. Support for QStandardItem proxies?
Forum Updated to NodeBB v4.3 + New Features

Support for QStandardItem proxies?

Scheduled Pinned Locked Moved Unsolved General and Desktop
qstandarditemcustom datadata modelsproxyadapter
27 Posts 3 Posters 8.2k 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.
  • V Offline
    V Offline
    VRonin
    wrote on 27 Sept 2018, 10:23 last edited by
    #2

    I guess you could use a QIdentityProxyModel subclass that reimplements data() but I still think the delegate solution proposed here is the preferred way. Especially if you plan to make the data editable

    "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

    E 2 Replies Last reply 27 Sept 2018, 11:23
    2
    • V VRonin
      27 Sept 2018, 10:23

      I guess you could use a QIdentityProxyModel subclass that reimplements data() but I still think the delegate solution proposed here is the preferred way. Especially if you plan to make the data editable

      E Offline
      E Offline
      elfring
      wrote on 27 Sept 2018, 11:23 last edited by
      #3

      I guess you could use a QIdentityProxyModel subclass …

      You can choose between involved places for desired data format conversions.

      • Data models
      • Views
      1 Reply Last reply
      0
      • V Offline
        V Offline
        VRonin
        wrote on 27 Sept 2018, 11:34 last edited by
        #4

        Views do not deal with individual item data. That's the delegate's job

        "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

        E 1 Reply Last reply 27 Sept 2018, 12:00
        1
        • V VRonin
          27 Sept 2018, 11:34

          Views do not deal with individual item data. That's the delegate's job

          E Offline
          E Offline
          elfring
          wrote on 27 Sept 2018, 12:00 last edited by
          #5

          Views do not deal with individual item data.

          • They try to display something and delegate edit attempts.
          • Items are connected with their data models.
          1 Reply Last reply
          0
          • V VRonin
            27 Sept 2018, 10:23

            I guess you could use a QIdentityProxyModel subclass that reimplements data() but I still think the delegate solution proposed here is the preferred way. Especially if you plan to make the data editable

            E Offline
            E Offline
            elfring
            wrote on 27 Sept 2018, 13:36 last edited by
            #6

            I have tried out to append a text by a QIdentityProxyModel subclass to a member variable of a custom data structure.
            Unfortunately, the display of one view from my test program indicates that the function “QVariant::canConvert” did not provide the result which I expected here.
            Would you like to clarify any affected implementation details?

            1 Reply Last reply
            0
            • V Offline
              V Offline
              VRonin
              wrote on 27 Sept 2018, 14:48 last edited by
              #7

              They try to display something and delegate edit attempts.

              I disagree, or at least it's not 100% accurate.

              Items are connected with their data models.

              Anything said above actually applies to any data model (QAbstractItemModel subclass), regardless of the implementation

              the display of one view from my test program

              can you post your code?

              "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

              E 2 Replies Last reply 28 Sept 2018, 11:25
              0
              • V VRonin
                27 Sept 2018, 14:48

                They try to display something and delegate edit attempts.

                I disagree, or at least it's not 100% accurate.

                Items are connected with their data models.

                Anything said above actually applies to any data model (QAbstractItemModel subclass), regardless of the implementation

                the display of one view from my test program

                can you post your code?

                E Offline
                E Offline
                elfring
                wrote on 28 Sept 2018, 11:25 last edited by
                #8

                can you post your code?

                • I am curious on how a code review will evolve for my test program.
                • The forum software gave me the information “Uploading 100%” and “You do not have enough privileges for this action.”.
                1 Reply Last reply
                0
                • V VRonin
                  27 Sept 2018, 14:48

                  They try to display something and delegate edit attempts.

                  I disagree, or at least it's not 100% accurate.

                  Items are connected with their data models.

                  Anything said above actually applies to any data model (QAbstractItemModel subclass), regardless of the implementation

                  the display of one view from my test program

                  can you post your code?

                  E Offline
                  E Offline
                  elfring
                  wrote on 28 Sept 2018, 12:14 last edited by
                  #9

                  Another try for a possible code review …

                  main.cpp:

                  #include <QApplication>
                  #include <QtUiTools/QUiLoader>
                  #include <QFile>
                  #include <QString>
                  #include <QWidget>
                  #include <QListView>
                  #include <QStandardItemModel>
                  #include <QIdentityProxyModel>
                  #include <QMetaType>
                  #include <iostream>
                  #include <stdexcept>
                  #include <cstdio>
                  #include <cstdlib>
                  
                  struct my_message
                  {
                      QString text;
                  
                      my_message(char const * s = "ABC")
                      : text(s)
                      { }
                  
                      my_message(my_message const& s)
                      : text(s.text)
                      { }
                  
                      ~my_message()
                      { }
                  };
                  Q_DECLARE_METATYPE(my_message);
                  
                  class my_item : public QStandardItem
                  {
                  public:
                      my_item(my_message const mm)
                      { setData(QVariant::fromValue(mm), Qt::DisplayRole); }
                  };
                  
                  class my_proxy : public QIdentityProxyModel
                  {
                      QVariant data(QModelIndex const & index, int role) const override
                      {
                          if (role != Qt::DisplayRole)
                              return QIdentityProxyModel::data(index, role);
                  
                          auto x(sourceModel()->data(index));
                          if (x.canConvert<my_message>())
                          {
                              my_message mm(x.value<my_message>());
                              mm.text.append("||");
                              return QVariant::fromValue(mm);
                          }
                          else
                          {
                              return "***";
                          }
                      }
                  };
                  
                  struct my_views : public QWidget
                  {
                      Q_OBJECT
                      QListView* v1;
                      QListView* v2;
                  
                  public:
                      explicit my_views(QWidget* parent = nullptr)
                      : QWidget(parent)
                      {
                  //         QFile f(":/form.ui");
                          QFile f("/home/elfring/Projekte/view-test2/form.ui");
                          if (!f.open(QFile::ReadOnly))
                              throw std::runtime_error(tr("UI file could not be opened.").toStdString());
                  
                          QUiLoader l;
                          QWidget* w = l.load(&f, this);
                          if (!w)
                              throw std::runtime_error(l.errorString().toStdString());
                  
                          f.close();
                  
                          v1 = findChild<QListView*>("V1");
                          if (!v1)
                              throw std::runtime_error(tr("First view was not found.").toStdString());
                  
                          v2 = findChild<QListView*>("V2");
                          if (!v2)
                              throw std::runtime_error(tr("Second view was not found.").toStdString());
                  
                          auto i1(new QStandardItem("abc"));
                          auto i2(new my_item("XYZ"));
                          auto m1(new QStandardItemModel);
                          auto m2(new QStandardItemModel);
                          auto mp(new my_proxy);
                          m1->appendRow(i1);
                          m2->appendRow(i2);
                          mp->setSourceModel(m2);
                          v1->setModel(m1);
                          v2->setModel(mp);
                      }
                  };
                  
                  #include "main.moc"
                  
                  int main(int argc, char** argv)
                  {
                      try
                      {
                          QApplication app(argc, argv);
                          qRegisterMetaType<my_message>("my_message");
                          my_views mv;
                          mv.show();
                          return app.exec();
                      }
                      catch (std::bad_alloc const& b)
                      {
                          (void) std::fputs("out of memory\n", stderr);
                          return EXIT_FAILURE;
                      }
                      catch (std::exception const& x)
                      {
                          (void) std::fprintf(stderr, "A kind of standard%s\n%s\n", " exception was caught.", x.what());
                          return EXIT_FAILURE;
                      }
                      catch (...)
                      {
                          (void) std::fprintf(stderr, "An unknown%s\n", " exception was caught.");
                          throw;
                      }
                  }
                  

                  CMakeLists.txt:

                  cmake_minimum_required(VERSION 3.1)
                  project(view-test CXX)
                  set(CMAKE_AUTOMOC ON)
                  find_package(Qt5 COMPONENTS Core Widgets UiTools REQUIRED)
                  include_directories(${Qt5Widgets_INCLUDE_DIRS} ${Qt5Core_INCLUDE_DIRS} ${Qt5UiTools_INCLUDE_DIRS})
                  add_executable(test1 main.cpp)
                  target_link_libraries(test1 Qt5::Widgets Qt5::Core Qt5::UiTools)
                  

                  form.ui:

                  <?xml version="1.0" encoding="UTF-8"?>
                  <ui version="4.0">
                   <class>my_views</class>
                   <widget class="QWidget" name="my_views">
                    <property name="geometry">
                     <rect>
                      <x>0</x>
                      <y>0</y>
                      <width>282</width>
                      <height>228</height>
                     </rect>
                    </property>
                    <property name="windowTitle">
                     <string>Display test</string>
                    </property>
                    <widget class="QListView" name="V1">
                     <property name="geometry">
                      <rect>
                       <x>10</x>
                       <y>10</y>
                       <width>256</width>
                       <height>91</height>
                      </rect>
                     </property>
                     <property name="uniformItemSizes">
                      <bool>true</bool>
                     </property>
                    </widget>
                    <widget class="Line" name="L1">
                     <property name="geometry">
                      <rect>
                       <x>10</x>
                       <y>100</y>
                       <width>241</width>
                       <height>20</height>
                      </rect>
                     </property>
                     <property name="lineWidth">
                      <number>9</number>
                     </property>
                     <property name="orientation">
                      <enum>Qt::Horizontal</enum>
                     </property>
                    </widget>
                    <widget class="QListView" name="V2">
                     <property name="geometry">
                      <rect>
                       <x>10</x>
                       <y>120</y>
                       <width>256</width>
                       <height>91</height>
                      </rect>
                     </property>
                     <property name="uniformItemSizes">
                      <bool>true</bool>
                     </property>
                    </widget>
                   </widget>
                   <resources/>
                   <connections/>
                  </ui>
                  
                  1 Reply Last reply
                  0
                  • V Offline
                    V Offline
                    VRonin
                    wrote on 28 Sept 2018, 12:33 last edited by
                    #10
                    1. does if (x.canConvert<my_message>()) return false?
                    2. what is your intention in this code snippet?
                    my_message mm(x.value<my_message>());
                    mm.text.append("||");
                    return QVariant::fromValue(mm);
                    
                    1. You are leaking all 3 of the models. The view does not own the model

                    "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

                    E 2 Replies Last reply 28 Sept 2018, 13:00
                    0
                    • V VRonin
                      28 Sept 2018, 12:33
                      1. does if (x.canConvert<my_message>()) return false?
                      2. what is your intention in this code snippet?
                      my_message mm(x.value<my_message>());
                      mm.text.append("||");
                      return QVariant::fromValue(mm);
                      
                      1. You are leaking all 3 of the models. The view does not own the model
                      E Offline
                      E Offline
                      elfring
                      wrote on 28 Sept 2018, 13:00 last edited by
                      #11

                      does if (x.canConvert<my_message>()) return false?

                      I get this impression after I see three asterisks in the display from my test widget on the screen.

                      what is your intention in this code snippet?

                      I am trying also to get more familiar with the provided programming interfaces around models and views.

                      You are leaking all 3 of the models.

                      I do not really need my own clean-up for this software experiment at the moment.

                      The view does not own the model

                      Thanks for your reminder.

                      Do you spot any other suspicious implementation details?

                      1 Reply Last reply
                      0
                      • V VRonin
                        28 Sept 2018, 12:33
                        1. does if (x.canConvert<my_message>()) return false?
                        2. what is your intention in this code snippet?
                        my_message mm(x.value<my_message>());
                        mm.text.append("||");
                        return QVariant::fromValue(mm);
                        
                        1. You are leaking all 3 of the models. The view does not own the model
                        E Offline
                        E Offline
                        elfring
                        wrote on 2 Oct 2018, 18:06 last edited by
                        #12

                        does `if (x.canConvert<my_message>()) return false?

                        I have added a test output for my local variable “x”. The programming interface “qDebug()” provides the information “QVariant(Invalid)” then so far.

                        • Would you like to help with finding an explanation for this software behaviour?
                        • How can a source model work here?
                        1 Reply Last reply
                        0
                        • C Online
                          C Online
                          Christian Ehrlicher
                          Lifetime Qt Champion
                          wrote on 2 Oct 2018, 18:38 last edited by
                          #13

                          @elfring said in Support for QStandardItem proxies?:

                          auto x(sourceModel()->data(index));

                          How should this work at all? http://doc.qt.io/qt-5/qidentityproxymodel.html#mapToSource

                          Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                          Visit the Qt Academy at https://academy.qt.io/catalog

                          V 1 Reply Last reply 2 Oct 2018, 19:28
                          1
                          • C Christian Ehrlicher
                            2 Oct 2018, 18:38

                            @elfring said in Support for QStandardItem proxies?:

                            auto x(sourceModel()->data(index));

                            How should this work at all? http://doc.qt.io/qt-5/qidentityproxymodel.html#mapToSource

                            V Offline
                            V Offline
                            VRonin
                            wrote on 2 Oct 2018, 19:28 last edited by
                            #14

                            Good spot, I'm surprised it didn't just assert. I got shouted at in code review for having models that didn't assert when index.model()!=this

                            @elfring replace auto x(sourceModel()->data(index)); with auto x=QIdentityProxyModel::data(index, role);

                            "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

                            E 2 Replies Last reply 2 Oct 2018, 20:15
                            0
                            • C Online
                              C Online
                              Christian Ehrlicher
                              Lifetime Qt Champion
                              wrote on 2 Oct 2018, 20:04 last edited by
                              #15

                              @VRonin said in Support for QStandardItem proxies?:

                              I'm surprised it didn't just assert

                              Maybe because Qt was not compiled in debug mode. Or there is no assert and the new index check stuff is not yet used there - feel free to add it ;)

                              Qt Online Installer direct download: https://download.qt.io/official_releases/online_installers/
                              Visit the Qt Academy at https://academy.qt.io/catalog

                              1 Reply Last reply
                              0
                              • V VRonin
                                2 Oct 2018, 19:28

                                Good spot, I'm surprised it didn't just assert. I got shouted at in code review for having models that didn't assert when index.model()!=this

                                @elfring replace auto x(sourceModel()->data(index)); with auto x=QIdentityProxyModel::data(index, role);

                                E Offline
                                E Offline
                                elfring
                                wrote on 2 Oct 2018, 20:15 last edited by
                                #16

                                replace auto x(sourceModel()->data(index)); with auto x=QIdentityProxyModel::data(index, role);

                                Thanks for this suggestion.

                                • Unfortunately, I selected a questionable member function call combination before.
                                • The test case is working as expected together with the statement “return mm.text;” now.
                                1 Reply Last reply
                                0
                                • V VRonin
                                  2 Oct 2018, 19:28

                                  Good spot, I'm surprised it didn't just assert. I got shouted at in code review for having models that didn't assert when index.model()!=this

                                  @elfring replace auto x(sourceModel()->data(index)); with auto x=QIdentityProxyModel::data(index, role);

                                  E Offline
                                  E Offline
                                  elfring
                                  wrote on 5 Oct 2018, 10:56 last edited by
                                  #17

                                  Good spot, I'm surprised it didn't just assert.

                                  • Did I try the usage of model indexes out in appropriate way for my test case?
                                  • Do indexes need to be different for proxy and source models?
                                  V 1 Reply Last reply 5 Oct 2018, 11:04
                                  0
                                  • E elfring
                                    5 Oct 2018, 10:56

                                    Good spot, I'm surprised it didn't just assert.

                                    • Did I try the usage of model indexes out in appropriate way for my test case?
                                    • Do indexes need to be different for proxy and source models?
                                    V Offline
                                    V Offline
                                    VRonin
                                    wrote on 5 Oct 2018, 11:04 last edited by
                                    #18

                                    @elfring said in Support for QStandardItem proxies?:

                                    Did I try the usage of model indexes out in appropriate way for my test case?

                                    Usually you'd want a Q_ASSERT that uses checkIndex()

                                    Do indexes need to be different for proxy and source models?

                                    Yes, obviously

                                    "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

                                    E 1 Reply Last reply 5 Oct 2018, 11:53
                                    0
                                    • V VRonin
                                      5 Oct 2018, 11:04

                                      @elfring said in Support for QStandardItem proxies?:

                                      Did I try the usage of model indexes out in appropriate way for my test case?

                                      Usually you'd want a Q_ASSERT that uses checkIndex()

                                      Do indexes need to be different for proxy and source models?

                                      Yes, obviously

                                      E Offline
                                      E Offline
                                      elfring
                                      wrote on 5 Oct 2018, 11:53 last edited by
                                      #19

                                      Yes, obviously

                                      • Should the difference between indexes for proxy and source models be better described in the Qt documentation?
                                      • How do you think about the introduction of a class like QProxyModelIndex then?
                                      V 1 Reply Last reply 5 Oct 2018, 12:29
                                      0
                                      • E elfring
                                        5 Oct 2018, 11:53

                                        Yes, obviously

                                        • Should the difference between indexes for proxy and source models be better described in the Qt documentation?
                                        • How do you think about the introduction of a class like QProxyModelIndex then?
                                        V Offline
                                        V Offline
                                        VRonin
                                        wrote on 5 Oct 2018, 12:29 last edited by
                                        #20

                                        @elfring said in Support for QStandardItem proxies?:

                                        How do you think about the introduction of a class like QProxyModelIndex then?

                                        QAbstractPorxyModel::mapToSource/QAbstractPorxyModel::mapFromSource already do everything that class would do so I see no gain in introducing it

                                        Should the difference between indexes for proxy and source models be better described in the Qt documentation?

                                        A proxy model is still a model, the docs say "Note that it's undefined behavior to pass illegal indices to item models" so I feel it is documented already

                                        "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

                                        E 1 Reply Last reply 5 Oct 2018, 13:01
                                        1
                                        • V VRonin
                                          5 Oct 2018, 12:29

                                          @elfring said in Support for QStandardItem proxies?:

                                          How do you think about the introduction of a class like QProxyModelIndex then?

                                          QAbstractPorxyModel::mapToSource/QAbstractPorxyModel::mapFromSource already do everything that class would do so I see no gain in introducing it

                                          Should the difference between indexes for proxy and source models be better described in the Qt documentation?

                                          A proxy model is still a model, the docs say "Note that it's undefined behavior to pass illegal indices to item models" so I feel it is documented already

                                          E Offline
                                          E Offline
                                          elfring
                                          wrote on 5 Oct 2018, 13:01 last edited by
                                          #21

                                          A proxy model is still a model,

                                          This information is generally appropriate.

                                          the docs say "Note that it's undefined behavior to pass illegal indices to item models"

                                          A constraint is mentioned.

                                          so I feel it is documented already

                                          Now I imagine that a better class design can prevent the passing of inappropriate indexes a bit more.
                                          How are the chances to specify that QAbstractProxyModel-like objects need to work with QProxyModelIndex objects instead?

                                          V 1 Reply Last reply 5 Oct 2018, 13:06
                                          0

                                          11/27

                                          28 Sept 2018, 13:00

                                          • Login

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