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. Forwarding signals from QSortFilterProxyModel to source model

Forwarding signals from QSortFilterProxyModel to source model

Scheduled Pinned Locked Moved General and Desktop
8 Posts 3 Posters 4.2k 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.
  • S Offline
    S Offline
    stevenhurd
    wrote on last edited by
    #1

    I have code where a source model (QAbstractListModel) implements its public add/remove/modify interface through slots. I'm trying to add a QSortFilterProxyModel between the view (which is in QML if it matters) and the source model. Obviously I still need to be able to add, remove, and modify items through the slot interface. Clearly the view should have no idea whether the underlying model is a proxy model or not so it seems the only solution is to subclass QSortFilterProxyModel and reimplement the public interface for QAbstractListModel. This is fine but I'm working with a whole model hierarchy which expose slightly different interfaces so each one will probably need its own subclassed proxy model.

    All this is certainly doable but I just can't help but shake the feeling that I'm missing a much simpler way of doing this. If any one has any suggestions I'd appreciate it.

    1 Reply Last reply
    0
    • JeroentjehomeJ Offline
      JeroentjehomeJ Offline
      Jeroentjehome
      wrote on last edited by
      #2

      Hi,
      The view normally has absolutely no idea if a derived QAbstractListModel or QSortFilterProxy is attached! When implementing the QSortFilter this will be placed between the view and the model. There is a good Model/View doc on this site, it's explains the proper functioning of the QSortFilter.
      No problem with using slots as normal member functions as well! It's the same, only Qt did some slot implementation. C++ execution is the same!
      So if the QSortFilterProxy is calling the virtual functions it will be the same as you calling them via signal/slot method from other parts of your program.
      I might misinterpreted you? Or maybe helped a lot ;-)
      Greetz

      Greetz, Jeroen

      1 Reply Last reply
      0
      • S Offline
        S Offline
        stevenhurd
        wrote on last edited by
        #3

        Right, I realize that I can always just forward function calls to the source model. That much is fine. The issue is that it seems like a bit of a maintenance issue if you have to subclass a QSortFilterProxyModel for every model class just to present the same interface to the view (the original model derived classes might have an interface that expands on the virtual base class interface, for example). It seems like there would be an easier way to forward all signals directed at one object to another object but maybe this isn't true.

        Something like:
        @
        connect_all(&proxyModel, &sourceModel)
        @

        1 Reply Last reply
        0
        • 8 Offline
          8 Offline
          8majkel8
          wrote on last edited by
          #4

          you don't have to subclass all proxies. Instead write some function to return proper (and already casted) model from view.

          @template<typename T> T * GET_MODEL(QAbstractItemView * ui)
          {
          QAbstractProxyModel * model
          = qobject_cast<QAbstractProxyModel*>(ui->model());
          T * theModel = 0;
          if (model) //we know that proxy is between model and view
          theModel = qobject_cast<T*>(model->sourceModel());
          else //we know that model is directly connected to view
          theModel = qobject_cast<T*>(ui->model());
          return theModel;
          }

          MyModel * model = GET_MODEL<MyModel>(ui->someView);
          if (model) {
          model->insert(...);
          }
          @

          1 Reply Last reply
          0
          • S Offline
            S Offline
            stevenhurd
            wrote on last edited by
            #5

            That's a very intriguing idea....it doesn't allow the concept of possibly stacking n-number of proxy models in front of the source model, but it seems like that could be easily corrected by a recursive call when the model->sourceModel() result is another QAbstractProxyModel.

            The other issue I just discovered is that (in the case of editing an existing item, for example) if an index from the proxy model is provided, the proxy model needs to be used to map the proxy index to the source index.

            My main point in asking this question is basically trying to figure out if the method of using slots in a source model to provide this type of interface is correct. It seems to be pretty standard for QML-based views but it seems like it could result in code duplication when models are stacked (if you do, in fact, have to forward the whole interface through proxy models).

            1 Reply Last reply
            0
            • 8 Offline
              8 Offline
              8majkel8
              wrote on last edited by
              #6

              I think it's better to keep pointer to original model somewhere and manipulate on it. The other thinks like views and proxy models are just for presentation and should not be used to manipulate data.

              1 Reply Last reply
              0
              • JeroentjehomeJ Offline
                JeroentjehomeJ Offline
                Jeroentjehome
                wrote on last edited by
                #7

                The proxy should NEVER be used (derived) to alter the underlying model data if you ask me. You can add multiple proxies to the same model and any signal it emits will be used by all connected proxies.
                Sorry, just don't get the point here. Sorry, might just be me.

                Greetz, Jeroen

                1 Reply Last reply
                0
                • S Offline
                  S Offline
                  stevenhurd
                  wrote on last edited by
                  #8

                  I will provide a very simple example. Let's say you have the following setup:

                  View <------> ProxyModel <-------> SourceModel

                  Now in the View/UI a user selects an item in the view and wants to edit a string that is presented in the view. How would you do that? The index presented in the view is not guaranteed to match the index from the source model (because of the proxy model). So from my perspective you can do a couple things:

                  1. You can emit an edit signal from the view for example:
                    @
                    signal edit(int index, string newString)
                    @
                    This is the scenario I'm facing right now. The index ISN'T a source model index so the signal CAN'T just be passed to the source model, the proxy model has to translate it.

                  2. You can assign each list item some sort of unique id (a UUID for example) that the view can use to reference the edited item rather than the index and emit a signal:
                    @
                    signal edit(UUID id, string newString)
                    @
                    The downside to this is that you still need some sort of intermediary object that knows to forward the received signal to the source model and bypass the proxy model.

                  My issue is more that I just don't see how this problem is usually addressed. This must be a common scenario when using views and models in Qt, so it seems there must be a common pattern for dealing with this.

                  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