1

so I know there are quite a lot of similar questions on here but none really gets to the specific point I am interested in.

I want to implement custom selection behavior of a QGraphicsItems (e.g. change its color on selection). Apparently this is handled by the items themselves so one needs to make an own class extending QGraphicsItem. There, I am really missing something, like an onSelectionToggled method (slot) that one could override. But I finally figured out that one has to override the mousePressEvent method (after all "selection" is just a more concrete term for the abstract concept of a left-click).

So if in this method I call:

  setPen( QPen( QColor( "orange" ) ) );
  update();

The color actually changes when I click a single item. But not when the selection happens via the rubber band of the scene. Since there is no onSelectionToggled, I imagined the scene would "simulate" a respective mouse event for the intersected items.

Since this is not the case, my question is: "How can I react to such a selection via rubber band?" Ideally in a "unified" way (no extra code for individual selection by mouse click).

Also, I wonder how I can prevent the dotted bounding rectangle to be drawn on selection. I don't want it and was hoping to get rid of it automatically when subclassing QGraphicsItem.

Angie Quijano
  • 4,167
  • 3
  • 25
  • 30
Chris K
  • 1,376
  • 1
  • 14
  • 18
  • Not for the big question, but for the dotted rectangle, I am afraid you will have to reimplement `QStyle::drawPrimitive`... – IAmInPLS Mar 25 '16 at 13:58
  • @AlexisP. Seriously? Because QStyle is an abstract class with many derived classes which all can be used in QGraphicsScene::setStyle.To me this looks like I have to either sublclass all these classes, overriding the drawPrimitive method. Or I pick only one subclass of QStyle but then I loose the scene's ability to adapt to the style of e.g. KDE, Mac OS or Windows (for which QStyle is actually for, as far as I can see). – Chris K Mar 29 '16 at 12:21

1 Answers1

1

The QGraphicsItem class is the base class for all graphical items in a QGraphicsScene. It is the QGraphicsScene class that contains all the functionality for handling QGraphicsItem selection. If you catch the signal QGraphicsScene::selectionChanged() you should be able to find the selected items through

`QList<QGraphicsItem *> QGraphicsScene::selectedItems()`

you can then change the pen for those items and redraw.

Of course since you want the items to turn back to their original colour once they are unselected, perhaps a better approach is to iterate over all items (QList<QGraphicsItem *> QGraphicsScene::items()) and check their isSelected() state to change their pen into the appropriate colour.

Tim Smit
  • 155
  • 7
  • Thanks for this useful answer. The iteration over all items and checking if they are selected individually was indeed the right approach for me (since I also wanted to handle "de-selection" events). In the spirit of the MVC pattern, I have put the code in a controller class that has a pointer to the QGraphicsscne (as the model) and the QGraphicsView (as the view). Still feels a little bit awkward as the Qt docu explicitly tells you to implement dynamic behavior in the items … – Chris K Mar 29 '16 at 11:50