Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • Users
  • Groups
  • Search
  • Get Qt Extensions
  • Unsolved
Collapse
Brand Logo
  1. Home
  2. Qt Development
  3. QML and Qt Quick
  4. [Solved] Nested QtQuick delegates based on C++ model
QtWS25 Last Chance

[Solved] Nested QtQuick delegates based on C++ model

Scheduled Pinned Locked Moved QML and Qt Quick
qmlqtquickc++delegatesnested
2 Posts 1 Posters 1.9k 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.
  • P Offline
    P Offline
    psimona
    wrote on last edited by psimona
    #1

    Hello everyone! I have developed an application in QML/QtQuick and I see that I need a more complex C++ based model.

    I have successfully transitioned many views/delegates to base upon the C++ model but this one delegate which contains another delegate causes some issues. The situation is as follows.

    There are 2 cpp based models: Model_A and Model_B
    There are 2 corresponding delegates which render the entries of the above models: Delegate_A and Delegate_B

    Delegate_A something like this:

    Rectangle {
       // some rendering of Model_A
       Repeater {
           delegate: Delegate_B{}
           model: {
               // some logic in JS which filters Model_B to get an entry
           }    
        }
    }
    

    The idea here is to recycle Delegate_B and if there are changes to change only this delegate to affect the whole visualization.

    Porting Model_B to C++ (QStandardItemModel derived) the filtering code broke. That is ok in the sense that QStandardItemModel and QML::ListModel have different manipulation interfaces an this can be addressed with some custom code.

    The real problem is how to have a Q_INVOKABLE method that returns something that QML can use as a model in the repeater. Ideally it would also be changed if a change to Model_B happens.

    Thanks in advance

    1 Reply Last reply
    0
    • P Offline
      P Offline
      psimona
      wrote on last edited by
      #2

      I eventually found a solution/workaround to the problem. I am posting it here if anybody ever needs it.

      The main issue it seems is wanting to filter the C++ model in QML/JavaScript. Getting elements out of the C++ model into QML seems to be possible as a returning a QVariantMap maps to a JS object in the QML engine. Using this returned object as a model proved not to work directly. This might work with further effort but due to time constraints this approach was abandoned.

      The new approach was to create a C++ model derived from QAbstractItemModel and reimplementing the necessary functions. This model is essentially a filtering proxy for Model_A and Model_B.

      The filtering is implemented in QAbstractItemModel::getData() and the elements are exposed through a reimplementation of QAbstractItemModel::roleNames().

      For this filtering proxy to change state when the underlying data changes the dataChanged() signals of the underlying models was connected to a method in the proxy model computing the correct index invoking emit dataChanged(index).

      The QML delegate reuse was then implemented as follows:

      Rectangle {
         // some rendering of Model_A
         Repeater {
             delegate: Delegate_B{}
             model: 
               Item{
                  property var propertyDelegateB: model.propertyDelegateB
                  // mulitple properties possible
                }    
          }
      }
      

      This worked for my use case as I needed only one element in the model. For multiple elements this approach might not be ideal.

      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