15
votes

I want to add signals/slots to a QGraphicsItem so I can reach QGraphicsItemObjects from another thread. There are two options that I know of: use QGraphicsObject or inherit from QObject and QGraphicsItem.

Using QGraphicsObject

This is assumed to be slow. According to this answer on stackoverflow QGraphicsObjects are slow because of their implementation. When I look in the source of QGraphicsObjects I can see a lot of signals being emitted according to changes made to the object. To me this seems a plausible argument for why QGraphicsObjects are slow, but I think this performance hit (if it really is one) can be avoided by the second solution.

Inheriting from QObject and QGraphicsItem.

When constructing a class that inherits from QObject and QGraphicsItem it seems that you get the most interesting feature of QGraphicsObject minus the performance hit: you are able to define slots and emit signals in your class but you don't inherit the default implementation of QGraphicsObject that would constantly emit signals on changes you might not be interested in. You are now able to emit signals but don't have to worry about signals being emitted for things you don't care about (x value that changes emits a signal in QGraphicsObject but not in this solution).

Summary of my question

  • Are QGraphicsObjects really slower than QGraphicsItems?
  • If they are, is it because the implementation emits signals (and emitting signals is a big performance hit)?
  • And if so, does the second solution (multiple inheritance) avoid this penalty?
3
I would try profiling it, and see if the extra emitted signals have any performance impact at all if left unused. As long as they're not connected to a slot, they might as well not be there, right?rubenvb
And what's the fundamental difference (except being more specific here) with this quesiton: stackoverflow.com/questions/2292072/… ?rubenvb
These 2 question cover the same subject but I'm indeed more specific: I specifically am interested if multiple inheritance is the right solution to overcome the problem of the overhead created by QGraphicsObjects.Christophe
Profiling is obviously the right way to check. I'd imagine it is the ownership qualities of QObjects which make them slow when creating or destroying. You may need to consider an option 3 - put a QObject class member inside your QGraphicsItem and attach to that rather than the graphics item itself.xioxox
It should be noted that QGraphicsObject itself also multiply inherits from QObject and QGraphicsItem.Thomas

3 Answers

13
votes

This thread suggests another option: Create a QObject subclass to emit signals on behalf of your QGraphicsItems.

If you have many QGraphicsItems that can share a single QObject, then this will be lighterweight than having each QGraphicsItem inherit QObject.

10
votes

Are QGraphicsObjects really slower than QGraphicsItems?

Yes. Your analysis is correct. QGraphicsObjects are slower because of the signalling they perform. They also have a larger memory overhead because they inherit from QObject, which could significantly impact performance if many QGraphicsObjects are being created.

If they are, is it because the implementation emits signals (and emitting signals is a big performance hit)?

Yes, if the way items are used causes excessive signalling. However, emitting signals may not be as expensive as other operations. In the talk "Qt GraphicsView in Depth", Alexis Menard says calls to itemChange is slow and that it is sometimes better to listen directly for changes. Both QGraphicsItems and QGraphicsObjects would have the penalty from using itemChange.

And if so, does the second solution (multiple inheritance) avoid this penalty?

Yes. Some unnecessary signalling could be avoided by inheriting from both QGraphicsItem and QObject and only emitting signals for what is needed. Of course, the memory overhead from QObject will still occur.

0
votes

You can change your class inheritance like below :

class GraphicalButton : public QObject,public QGraphicsItem

Then add Q_OBJECT at begin of your class.

now you can add signals and slot.

Before running the application clean & run qmake