Poor QOpenGLWidget performance on OS X, QOpenGLWindow question
-
Hi!
I have a problem in QOpenGLWidget performance on OS X (MacBook Pro Late 2013 Retina). As I understand QOpenGLWidget have to do full window composition before displaying its content. I have tried using QOpenGLWindow and it works MUCH faster on Mac & Windows. I need to use it embedded inside regular QWidget UI. But its not clear how to forward QOpenGLWindow's events to parent underlaying widget. Underlaying widget actions also aren't working because QOpenGLWindow stealing focus, and there's no way to add an action directly to QOpenGLWindow. Is it possible to use QOpenGLWindow just for displaying content, and make it transparent for all input events? Qt::WindowTransparentForInput flag didn't help.
-
Hi!
The bug says about top level windows, also the window there is translucent, but my window is embedded using QWidget::createWindowContainer (not a top level window) and must be completely opaque for performance reason. I have checkout Windows code and find out that WindowTransparentForInput works only for top level windows:
With WS_EX_TRANSPARENT flag it also use WS_EX_LAYERED which will decrease performance.
UPDATE: I tried to use Win32 API call to enable WS_EX_TRANSPARENT - unfortunately underlaying widget still not getting events.
Andrew.
-
Then you could install an event filter on it and ignore everything keyboard/mouse related.
-
How did you setup the event filter ?
-
I have minized the code. When I click on the left green side (QOpenGLWindow) I get this error on Windows in app's output and also don't get any events from mouse (mousePressEvent, contextMenuEvent, wheelEvent, ...):
requestActivate() called for QOpenGLWindow(0x8f8400f450) which has Qt::WindowDoesNotAcceptFocus set.
On OSX everything seems work fine. Don't know how this works on Linux. Using Qt 5.5.0 open source.
#include <QApplication> #include <QOpenGLWindow> #include <QOpenGLFunctions> #include <QAction> #include <QDebug> class OpenGLWindow : public QOpenGLWindow, protected QOpenGLFunctions { Q_OBJECT public: OpenGLWindow() { setFlags(flags() | Qt::WindowDoesNotAcceptFocus | Qt::WindowTransparentForInput); } void initializeGL() { initializeOpenGLFunctions(); } void paintGL() { glClearColor(0.0f, 1.0f, 0.0f, 1.0f); glClear(GL_COLOR_BUFFER_BIT); } }; class MainWidget : public QWidget { Q_OBJECT OpenGLWindow *openGLWindow; public: MainWidget() : openGLWindow(new OpenGLWindow()) { QWidget *widget = QWidget::createWindowContainer(openGLWindow, this); // widget->setAttribute(Qt::WA_TransparentForMouseEvents); widget->setFixedSize(200, 300); setFocusPolicy(Qt::StrongFocus); setFixedSize(400, 300); QAction *action = new QAction(tr("Some Action"), this); action->setShortcut(QKeySequence(Qt::Key_A)); action->setShortcutContext(Qt::WidgetWithChildrenShortcut); addAction(action); connect(action, SIGNAL(triggered()), this, SLOT(onAction())); } void contextMenuEvent(QContextMenuEvent *e) { qDebug() << "Context menu event"; QWidget::contextMenuEvent(e); } void wheelEvent(QWheelEvent *e) { qDebug() << "Mouse wheel event"; QWidget::wheelEvent(e); } void mousePressEvent(QMouseEvent *e) { qDebug() << "Mouse press event"; QWidget::mousePressEvent(e); } void keyPressEvent(QKeyEvent *e) { qDebug() << "Key press event"; QWidget::keyPressEvent(e); } private slots: void onAction() { qDebug() << "Action event"; } }; int main(int argc, char *argv[]) { QApplication a(argc, argv); MainWidget w; w.show(); return a.exec(); } // Avoid linker error #include "main.moc"
Also please create empty main_p.h to avoid linker error.
-
What setup do you have on Windows ? MultiScreen ? Graphic card ?
-
Indeed, but having a multiple-screen setup might also influence things a bit.