Results 1 to 8 of 8

Thread: Synchronizing behaviour between QListView and QGraphicsScene

  1. #1
    Join Date
    May 2009
    Posts
    16
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Synchronizing behaviour between QListView and QGraphicsScene

    Hello,
    I am aiming to replicate a Photoshop-like selection behaviour between a QGraphicsScene/QGraphicsView and a QTreeView/QStandardItemModel.

    Specifically, a QTreeView shows the names of QGraphicsItems and their children contained within a QGraphicsScene (children will be linked with a parent so they move together). When an item is selected in the QTreeView, the corresponding QGraphicsItem is selected in the scene and vice versa.

    I was considering making a class which inherits from both QStandardItem and QGraphicsItem (or some subclass... probably QGraphicsPixmapItem) so that a single pointer could be inserted into either the scene or the tree view without having to keep track of all kinds of cross-references. This way I should be able to set up signals so that a change in selection in the tree view or graphics view can signal a selection change in the other.

    However, I am still learning about all the Qt classes and their functionality so I don't want to make a big design mistake out of ignorance which ends up haunting me later on.

    Any suggestions on ways or best-practices on how something like what I've described might be accomplished? Any help would be greatly appreciated! Thanks.

  2. #2
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Synchronizing behaviour between QListView and QGraphicsScene

    If there is always a 1 to 1 relationship between the tree item and graphics scene item, consider using boost::bimap where the two "sides" of the map are a pointer to the QStandardItem and a pointer to a QGraphicsItem, respectively. Looking up using one as a key gives you the other, and vice versa.

    Mixing up QStandardItem and QGraphicsItem by multiple inheritance seems like a good way to lock yourself into an inflexible design, and it would be a weird class - sometimes it behaves like a car, sometimes it behaves like a banana, so to speak.

    It might be feasible to inherit from bimap to create a QObject that could act as the intermediary between the item model and the scene; catch signals from the model or scene, then map those into new signals emitted by the bimap and received by the other partner. This way, neither the scene nor the tree view know anything about each other - all communication is through the bimap.

    Note that you can use two std::map instances instead of the bimap if you don't want the overhead of another library and learning curve. However, you have to be very careful that changes in one map's key or value get propagated to the map that works in the opposite direction so that things stay in sync.

    In any case, my rule of thumb (and Qt's as well) is to decouple objects as much as possible. That's the purpose of signals and slots. No object instance knows who is listening to its signals, and no object instance knows who is calling its slots - the signal/slot pair is all that matters.

  3. #3
    Join Date
    May 2009
    Posts
    16
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Synchronizing behaviour between QListView and QGraphicsScene

    Thank you very much for the reply, d_stranz.

    What you've said makes a lot of sense! It adheres to both minimal coupling and also the Model-View-Controller design pattern that Qt enables & encourages. While I was trying to simplify the bookkeeping involved with my idea of inheriting from both QStandardItem and QGraphicsItem, it would have strongly coupled model & controller behaviour. I was hoping for a simpler/more elegant method of keeping track of pointers other than two hash maps, but I suppose it could be worse

  4. #4
    Join Date
    May 2009
    Posts
    16
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Synchronizing behaviour between QListView and QGraphicsScene

    What about using the same QStandardItemModel and QItemSelectionModel for both the QGraphicsView and QTreeView?

    I was just examining the Chart Example and this seems to be how they achieve synchronization between the two views... Although I think I would have to have a much better understanding of how to insert/remove from the model and how QVariants work... Worth it?

    Edit: Upon closer examination, the above idea won't work because QGraphicsView does not use a model like QAbstractItemView.
    Last edited by russdot; 24th April 2012 at 02:09.

  5. #5
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Synchronizing behaviour between QListView and QGraphicsScene

    What about using the same QStandardItemModel and QItemSelectionModel for both the QGraphicsView and QTreeView?
    As you say, since QGraphicsView does not use a model, you might have to invent some "glue" to accomplish that. But if you think about the idea of using a 2-way map between QStandardItem and QGraphicsItem, the synchronization problem is resolved pretty easily. When the user selects items from the tree, you retrieve the list of selected QStandardItems, look them up in the map, and set the matching QGraphicsItem to selected. Likewise, when the user selects items in the graphics view, you do the reverse lookup and set the QStandardItem as selected.

  6. #6
    Join Date
    May 2009
    Posts
    16
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Synchronizing behaviour between QListView and QGraphicsScene

    But if you think about the idea of using a 2-way map between QStandardItem and QGraphicsItem, the synchronization problem is resolved pretty easily. When the user selects items from the tree, you retrieve the list of selected QStandardItems, look them up in the map, and set the matching QGraphicsItem to selected. Likewise, when the user selects items in the graphics view, you do the reverse lookup and set the QStandardItem as selected.
    Exactly. The solution I came up with is a templated bi-directional hash map:
    Qt Code:
    1. template <class U, class V>
    2. class BidirectionalHashMap
    3. {
    4. public:
    5. U find(V v) { return mapVU.find(v).value(); }
    6. V find(U u) { return mapUV.find(u).value(); }
    7. void insert(U u, V v) { mapUV.insert(u,v); mapVU.insert(v,u); }
    8.  
    9. private:
    10. QHash<U, V> mapUV;
    11. QHash<V, U> mapVU;
    12. };
    To copy to clipboard, switch view to plain text mode 

    It works great for what I needed to accomplish.

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Synchronizing behaviour between QListView and QGraphicsScene

    It works great for what I needed to accomplish.
    At least as long as either of the QHash::find() calls in your two find() methods doesn't return QHash::end(). Then the following call to QHash::iterator::value() will assert. If your code guarantees that you will never try to find() a key that isn't in the map, this won't be a problem.

  8. #8
    Join Date
    May 2009
    Posts
    16
    Qt products
    Qt4
    Platforms
    Unix/X11 Windows

    Default Re: Synchronizing behaviour between QListView and QGraphicsScene

    Ah, good point. Yes, I don't see any case where I would be trying to find a key that isn't in the bi-map.

Similar Threads

  1. Strange behaviour in QGraphicsScene
    By yagabey in forum Qt Programming
    Replies: 1
    Last Post: 20th July 2011, 02:01
  2. synchronizing events
    By zaphod.b in forum Qt Programming
    Replies: 0
    Last Post: 14th July 2009, 16:29
  3. Synchronizing QFtp
    By arun_vj in forum Qt Programming
    Replies: 0
    Last Post: 5th November 2008, 12:31
  4. Synchronizing two GraphicsScenes
    By manojmka in forum Qt Programming
    Replies: 13
    Last Post: 3rd December 2007, 09:59

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.