QOpenGLWidget update and grab in thread
-
How to do it correctly?
- Create Thread
- Create in thread object based on QOpenGLWidget
- in Thread call grab() and take correct picture
I open example hellogl2 and add this sample code in main.cpp before
return app.exec();QShortcut *shortcutF4 = new QShortcut(QKeySequence(Qt::Key_F4), &mainWindow, nullptr, nullptr, Qt::ApplicationShortcut); QObject::connect(shortcutF4, &QShortcut::activated, &mainWindow, [&]() { qDebug() << "F4"; auto *t = new std::thread([]() { GLWidget glWidget; glWidget.resize(400,400); glWidget.grab().save("grab_hellogl2_in_thread_01.png"); // change something glWidget.setXRotation(60*3); glWidget.grab().save("grab_hellogl2_in_thread_02.png"); // change something glWidget.setYRotation(75*4); glWidget.grab().save("grab_hellogl2_in_thread_03.png"); }); t->join(); }); return app.exec();But I see warning "Attempting to create QWindow-based QOffscreenSurface outside the gui thread. Expect failures."
How to do it correctly?
-
How to do it correctly?
- Create Thread
- Create in thread object based on QOpenGLWidget
- in Thread call grab() and take correct picture
I open example hellogl2 and add this sample code in main.cpp before
return app.exec();QShortcut *shortcutF4 = new QShortcut(QKeySequence(Qt::Key_F4), &mainWindow, nullptr, nullptr, Qt::ApplicationShortcut); QObject::connect(shortcutF4, &QShortcut::activated, &mainWindow, [&]() { qDebug() << "F4"; auto *t = new std::thread([]() { GLWidget glWidget; glWidget.resize(400,400); glWidget.grab().save("grab_hellogl2_in_thread_01.png"); // change something glWidget.setXRotation(60*3); glWidget.grab().save("grab_hellogl2_in_thread_02.png"); // change something glWidget.setYRotation(75*4); glWidget.grab().save("grab_hellogl2_in_thread_03.png"); }); t->join(); }); return app.exec();But I see warning "Attempting to create QWindow-based QOffscreenSurface outside the gui thread. Expect failures."
How to do it correctly?
@MfromOlsztyn All the GUI stuff must be done into main thread.
-
@MfromOlsztyn All the GUI stuff must be done into main thread.
@ollarch
I don't want to show anything in the GUII want render off-screen, it is possible in openGL.
-
@ollarch
I don't want to show anything in the GUII want render off-screen, it is possible in openGL.
@MfromOlsztyn said in QOpenGLWidget update and grab in thread:
I don't want to show anything in the GUI
But GLWidget is a widget and therefore needs to be created and access in the main thread as corectly told you already by @ollarch .
-
@ollarch
I don't want to show anything in the GUII want render off-screen, it is possible in openGL.
@MfromOlsztyn You can't touch a widget from a secondary thread. The goal just isn't correct. There is no way to do that correctly. Widgets are always "GUI" even if it isn't shown.
Threaded OpenGL is potentially a complex topic, but you'll need an offscreen surface that isn't a widget.
-
@MfromOlsztyn You can't touch a widget from a secondary thread. The goal just isn't correct. There is no way to do that correctly. Widgets are always "GUI" even if it isn't shown.
Threaded OpenGL is potentially a complex topic, but you'll need an offscreen surface that isn't a widget.
@wrosecrans I look at https://doc.qt.io/qt-6/qopenglwidget.html#threading
*Performing offscreen rendering on worker threads, for example to generate textures that are then used in the GUI/main thread in paintGL(), are supported by exposing the widget's QOpenGLContext so that additional contexts sharing with it can be created on each thread.*I don't want to touch main from background thread ,
and I don't want to touch background thread from main.
Two independent threads, no interactionAnother way: create second process without GUI and use QOpenGLWidget in invisible APP, is it possible ?
I'm looking for a starting example
A lot of people ask, but I don't see a solution -
@wrosecrans I look at https://doc.qt.io/qt-6/qopenglwidget.html#threading
*Performing offscreen rendering on worker threads, for example to generate textures that are then used in the GUI/main thread in paintGL(), are supported by exposing the widget's QOpenGLContext so that additional contexts sharing with it can be created on each thread.*I don't want to touch main from background thread ,
and I don't want to touch background thread from main.
Two independent threads, no interactionAnother way: create second process without GUI and use QOpenGLWidget in invisible APP, is it possible ?
I'm looking for a starting example
A lot of people ask, but I don't see a solution@MfromOlsztyn As others said you can't render to a widget in any thread but main. For rendering in another thread use QOffscreenSurface instead of QOpenGLWidget, which creates a windowless surface and is specifically designed for this purpose.