0

Can QSGNode inherit QObject and connect to signals and slots? I have tried but the slot is only called when rendering is done.

I had a matrix of cells. I was using QML to display them on a bi dimensional ListView (a ListView the had in each delegate a ListView). This lacked performance so I changed to SceneGraph. The problem is the data model. I'm now a passing a QList, where column has a QList. Each row has cells the have signals. This cells change. I want to notify render updates on those signals. My solution until I have a better one is to make each cell trigger a changed signal on the respective column which by it's turn will turn the update flag on the main QQuickItem implementing the scene.

Ideas?

Nuno Santos
  • 1,476
  • 3
  • 17
  • 34
  • What are you trying to do? It seems a bit weird to attach signals and slots to a QSGNode. – peppe Nov 10 '14 at 22:31
  • I had a matrix of cells. I was using QML to display them on a bi dimensional ListView (a ListView the had in each delegate a ListView). This lacked performance so I changed to SceneGraph. The problem is the data model. I'm now a passing a QList, where column has a QList. Each row has cells the have signals. This cells change. I want to notify render updates on those signals. My solution until I have a better one is to make each cell trigger a changed signal on the respective column which by it's turn will turn the update flag on the main QQuickItem implementing the scene. Ideas? – Nuno Santos Nov 10 '14 at 23:10
  • 1
    @NunoSantos I think you should add that comment to your question. – Jonathan Mee Nov 11 '14 at 00:56

2 Answers2

1

You should connect the signals from your model to the QQuickItem that handles the QSGNode instead of directly connecting to the QSGNode. QSGNode objects are supposed to be handled only inside the QSGRenderingThread.

QObjects 'live' in only one thread. This is the thread where they emit and receive signals. By making your QSGNode a QObject, you must pay attention to the emitting and receiving threads otherwise you'll get symptoms like the ones you describe. Unless you specify Qt::DirectConnection when you make a connection, if the signal is emitted from one thread and received from an object living in another thread, the signal is converted to a message and will be dispatched later using the QEventLoop.

A good practice is to have a structure like the ones provided in the Qt examples :

QQuickItem handles signal connections and stores properties. Depending on what has changed, QQuickItem sends commands to the QSGNode to recalculate certain parts of its geometry. This is done only through QQuickItem::updatePaintNode()

0

A QSGNode cannot support signals and slots natively. But if you wanted to you could do double inheritance.

#include <QObject>
#include <QSGNode>

class Foo : public QObject, public QSGNode    {
     Q_OBJECT
     // Your additional implementation here
};
Jonathan Mee
  • 37,899
  • 23
  • 129
  • 288
  • 1
    I have done that. It happens that the signals/slots were only being fired on the next rendered frame. Imagine that you would had to resize the window to have the signals/slots fired. – Nuno Santos Nov 11 '14 at 09:49
  • @NunoSantos Again, I think that needs to be part of your question. Can you list all the causes for the SceneGraph resize? (For example window resize would be one cause.) If you can enumerate all these causes, it seems like you want to `signal` on the enumerated causes, _not_ `signal` from the `QSGNode`. – Jonathan Mee Nov 11 '14 at 12:37
  • 1
    when inheriting from both `QObject` and another class, `QObject` should always be the first class to be inherited. (From the Qt docs) – Konstantinos Gaitanis May 30 '15 at 21:58