Solved Scene Graph Drawing on background of QML
-
Hi,
my problem is that the scene graph is drawing on background of my QML Quick application.
So in my case i have to draw my scene graph after the QML QuickWindow draws its window.
I found this signal void QQuickWindow::afterRendering() and it says that could be use to render raw OpenGL on top of qml.
My scene graph is exactly the same as the Qt example project "/scenegraph/graph".
So i went in the graph constructor and add:#include "graph.h" #include "noisynode.h" #include "gridnode.h" #include "linenode.h" #include <QtQuick/qquickwindow.h> Graph::Graph() : m_samplesChanged(false) , m_geometryChanged(false) { setFlag(ItemHasContents, true); connect(window(), SIGNAL(QQuickWindow::afterRendering), this, SLOT(renderScene()), Qt::DirectConnection); }
So when i try to use this signal to connect to my "slot" i get this output message:
QObject::connect: Cannot connect (null)::QQuickWindow::afterRendering to Graph::renderScene()My slot should update the scene:
void Graph::renderScene() { m_geometryChanged=true; update(); }
Any idea?
-
Please makse sure
window()
returns a valid pointer.my problem is that the scene graph is drawing on background of my QML Quick application.
Can you explain a in a bit more details what your are trying to achieve and what is happening instead? I can't get it from that description. QtQuick is drawn using scene graph - that is the underlying technology used to draw any Qt Quick apps. So I don't quite follow how scene graph could be drawing on background of your application (which is already using scene graph to draw...).
-
@sierdzio Yes you are right.
What i want to do is explain here:The QQuickWindow::afterRendering() signal is emitted. Applications can make direct connections (using Qt::DirectConnection) to this signal to use custom OpenGL calls which will then stack visually over the QML scene.
My Graph is draw before the QML Scene has been rendered. In other words, my graph is drawing on the background of my QML Application. I know that because once i press any button on my application, the scene graph will draw on top afterwards.
I am now able to get a valid window when i make the connection here:
QSGNode *Graph::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *) { GraphNode * n= static_cast<GraphNode *>(oldNode); QRectF rect = boundingRect(); if (rect.isEmpty()) { delete n; return 0; } if (!n) { connect(window(), SIGNAL(afterRendering()), this, SLOT(renderScene()), Qt::DirectConnection); ....
So once the signal is emitted, it gets in my slot.
But now i am facing the next issue:void Graph::renderScene() { m_geometryChanged=true; update(); <---------------------------Here is my Problem }
Updates can only be scheduled from GUI thread or from QQuickItem::updatePaintNode()
How can i update my painter?(Same as Graph Qt project)
-
Hm, a direct connection should ensure that execution happens in the same thread already.
I've checked the examples - are we talking about this one? If yes, then you are using it wrong.
graph.h defines a QQuickItem - that is, it is a QML component, which you can use in your QML code, just like any other component (Rectangle, SwipeView, Button etc.).
On the other hand, QQuickWindow::afterRendering() should be used to draw raw OpenGL, not a QQuickItem.
-
So how do i bring my scene graph on front of QML then?
I have two many points which are drawn like lines_strips and they are appearing on the graph.
Once i add 2 more lines afterwards, they dont appear on my graph. Only if i press anything on the QML application the appear with the first ones.Since the scene graph is a QML component why is it not been draw?
-
@michaelL said in Scene Graph Drawing on background of QML:
Since the scene graph is a QML component why is it not been draw?
Because you inject it after QML has finished painting. As said, you need to use it as normal QML component. Add it in your QML code. See the docs: http://doc.qt.io/qt-5/qtqml-cppintegration-definetypes.html
-
The openglunderqml example is also a QML component and here it can use QQuickWindow to draw on top of QML
Drawing from QML Component it works thanks for the help.