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. QAbstractItemModelReplica data issue
Forum Updated to NodeBB v4.3 + New Features

QAbstractItemModelReplica data issue

Scheduled Pinned Locked Moved Unsolved General and Desktop
3 Posts 1 Posters 293 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.
  • rincewindR Offline
    rincewindR Offline
    rincewind
    wrote on last edited by
    #1

    I've created a remote object with a model property. The .rep file is of the form:

    class ServiceTest
    {
        PROP(QString name="default");
        MODEL testModel(name, description, timestamp);
    }
    

    In the client, I can access the name property, and if it is changed by the server, I get a signal and the updated value. The problem is with the model. I can get the QAbstractItemModelReplica, and once I receive the initialized signal, the rowCount reflects the correct number of rows in the model. However, when I iterate over the cells the hasData function returns false and if I call the data function, it returns an invalid QVariant. The rolesNames function returns the correct role names.

    1 Reply Last reply
    0
    • rincewindR Offline
      rincewindR Offline
      rincewind
      wrote on last edited by rincewind
      #2

      Here is a minimal example. Instead of using a custom model, I've used a QStringListModel to keep the code simpler.

      First the .rep file

      class Service
      {
          PROP(bool isOn=false);
          PROP(QString name="default");
          MODEL textModel(display);
      };
      

      The server:

      #include "rep_Service_source.h"
      #include <QCoreApplication>
      #include <QRemoteObjectHost>
      #include <QStringListModel>
      #include <QTimer>
      
      class Service : public ServiceSimpleSource
      {
          Q_OBJECT
      
      public:
          Service()
          {
              _textModel.setStringList({"A", "B", "C", "D"});
              setName("First value");
              setTextModel(&_textModel);
              connect(&_changeTimer, &QTimer::timeout, this, [this]() {
                  setName(QString("Name #%1").arg(_counter++));
              });
              _changeTimer.start(4000);
          }
      
          void logModel()
          {
              for (int i{}; i < _textModel.rowCount(); ++i)
                  qDebug() << _textModel.data(_textModel.index(i, 0));
          }
      
      private:
          QStringListModel _textModel;
          QTimer _changeTimer;
          int _counter{1};
      };
      
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
      
          QRemoteObjectHost node(QUrl(QStringLiteral("local:switch")));
      
          Service service;
          node.enableRemoting(&service, QStringLiteral("MyService"));
      
          QObject::connect(&service, &Service::nameChanged, [](QString name) {
              qDebug() << "Service name changed to" << name;
          });
      
          return a.exec();
      }
      
      #include "main.moc"
      

      The client:

      #include "rep_Service_replica.h"
      #include <QCoreApplication>
      #include <QLoggingCategory>
      #include <QRemoteObjectNode>
      
      int main(int argc, char *argv[])
      {
          QCoreApplication a(argc, argv);
      
          QRemoteObjectNode node(QUrl(QStringLiteral("local:switch")));
          node.setHeartbeatInterval(1000);
      
          std::unique_ptr<ServiceReplica> replica(node.acquire<ServiceReplica>("MyService"));
          if (!replica->waitForSource() || !replica->isInitialized())
              qDebug() << "Replica not valid!";
      
          qDebug() << "replica->isReplicaValid():" << replica->isReplicaValid();
          qDebug() << "replica->name:" << replica->name();
      
          auto r = QObject::connect(replica.get(), &ServiceReplica::nameChanged, [](QString name) {
              qDebug() << QString("replica->name changed to '%1'").arg(name);
          });
      
          QObject::connect(replica->textModel(), &QAbstractItemModelReplica::initialized, [&replica]() {
              qDebug() << "textModel.rowCount:" << replica->textModel()->rowCount();
              for (int i{}; i < replica->textModel()->rowCount(); ++i)
                  qDebug() << replica->textModel()->data(replica->textModel()->index(i, 0));
          });
      
          return a.exec();
      }
      

      The model replica contains the correct number of rows, but the data is not available!

      If I enable logging in the client, It looks like the data is available in the replica:

      qt.remoteobjects.models: void fillRow(CacheData*, const QtPrivate::IndexValuePair&, const QAbstractItemModel*, const QList<int>&) row= 0 column= 0
      qt.remoteobjects.models: void fillRow(CacheData*, const QtPrivate::IndexValuePair&, const QAbstractItemModel*, const QList<int>&) existed= false
      qt.remoteobjects.models: void fillCacheEntry(CacheEntry*, const QtPrivate::IndexValuePair&, const QList<int>&) data.size= 1
      qt.remoteobjects.models: void fillCacheEntry(CacheEntry*, const QtPrivate::IndexValuePair&, const QList<int>&) role= 0 data= QVariant(QString, "A")
      qt.remoteobjects.models: void fillRow(CacheData*, const QtPrivate::IndexValuePair&, const QAbstractItemModel*, const QList<int>&) row= 1 column= 0
      qt.remoteobjects.models: void fillRow(CacheData*, const QtPrivate::IndexValuePair&, const QAbstractItemModel*, const QList<int>&) existed= false
      qt.remoteobjects.models: void fillCacheEntry(CacheEntry*, const QtPrivate::IndexValuePair&, const QList<int>&) data.size= 1
      qt.remoteobjects.models: void fillCacheEntry(CacheEntry*, const QtPrivate::IndexValuePair&, const QList<int>&) role= 0 data= QVariant(QString, "B")
      qt.remoteobjects.models: void fillRow(CacheData*, const QtPrivate::IndexValuePair&, const QAbstractItemModel*, const QList<int>&) row= 2 column= 0
      qt.remoteobjects.models: void fillRow(CacheData*, const QtPrivate::IndexValuePair&, const QAbstractItemModel*, const QList<int>&) existed= false
      qt.remoteobjects.models: void fillCacheEntry(CacheEntry*, const QtPrivate::IndexValuePair&, const QList<int>&) data.size= 1
      qt.remoteobjects.models: void fillCacheEntry(CacheEntry*, const QtPrivate::IndexValuePair&, const QList<int>&) role= 0 data= QVariant(QString, "C")
      qt.remoteobjects.models: void fillRow(CacheData*, const QtPrivate::IndexValuePair&, const QAbstractItemModel*, const QList<int>&) row= 3 column= 0
      qt.remoteobjects.models: void fillRow(CacheData*, const QtPrivate::IndexValuePair&, const QAbstractItemModel*, const QList<int>&) existed= false
      qt.remoteobjects.models: void fillCacheEntry(CacheEntry*, const QtPrivate::IndexValuePair&, const QList<int>&) data.size= 1
      qt.remoteobjects.models: void fillCacheEntry(CacheEntry*, const QtPrivate::IndexValuePair&, const QList<int>&) role= 0 data= QVariant(QString, "D")
      

      However, when I call the data function on the model replica, I get an invalid QVariant!

      textModel.rowCount: 4
      QVariant(Invalid)
      QVariant(Invalid)
      QVariant(Invalid)
      QVariant(Invalid)
      
      1 Reply Last reply
      1
      • rincewindR Offline
        rincewindR Offline
        rincewind
        wrote on last edited by
        #3

        The only workaround I can find at the moment is to wait for a second or two before trying to read the data from the model. It seems the data is only "fetched" later, but no model signals are emitted once the data is fetched. So, supplying the model to a view doesn't work as the view doesn't get notified to refresh once the data is fetched.

        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