Qt5.6: high DPI support and OpenGL (OpenSceneGraph)

后端 未结 1 787
你的背包
你的背包 2021-01-12 22:24

I have a minimal application which uses QOpenGLWidget that integrates an OpenGL wrapper library (OpenSceneGraph). I am trying to figure out how to correctly use

相关标签:
1条回答
  • 2021-01-12 23:10

    Is there a way to know to what size the scaling will be performed so that to do resizeGL() correctly?

    First, detect the monitor:

            // relative to widget
            int screenNum = QApplication::desktop()->screenNumber(pWidget);
    

    or maybe

            // relative to global screen position
            int screenNum = QApplication::desktop()->screenNumber(pWidget->topLeft());
    

    and that gives us pointer to QScreen:

            QScreen* pScreen = QApplication::desktop()->screen(screenNum);
    

    from which you can read many screen characteristics, including "physical dot per inch" which makes us able to judge how many pixels there per inch:

            qreal pxPerInch = pScreen->physicalDotsPerInch();
    

    Having pixels per inch you will be able to programmatically scale your drawing code. Detect how much is 'normal' density and then scale proportionally against the density detected on physical device. Of course that approach is more suitable for accurate graphics. Be aware of both physicalDotPerInch() and devicePixelRatio(), though.

            qreal scaleFactor = pScreen->physicalDotsPerInch() / normalPxPerInch;
    

    Or what is the correct way to deal with the problem?

    However, with widgets and normal GUI drawing it is often easier to let Qt / system to scale the entire UI. Qt Documentation: High DPI Displays.

    If the OS Windows at least Vista or higher and tuning Qt for high DPI sounds complicated then there is a shortcut that I take and it helps me, though Qt complains in the log: "SetProcessDpiAwareness failed: "COM error 0xffffffff80070005 (Unknown error 0x0ffffffff80070005)" ". I call this function from main() before the event loop: SetProcessDPIAware() and then all the UI looks alike no matter what monitor density is. I use it with Qt 5.5, though. There is also SetProcessDpiAwareness() function, explore. I use SetProcessDPIAware because it is available since Windows Vista but SetProcessDpiAwareness is only available since Windows 8.1. So, the decision may depend on potential clients systems.

    A 'shortcut' approach:

    int main(int argc, char** argv)
    {
        // DPI support is on
        // QApplication::setAttribute(Qt::AA_EnableHighDpiScaling);
    
         // on Windows?
        ::SetProcessDPIAware();
        // MSDN suggests not to use SetProcessDPIAware() as it is obsolete and may not be available.
        // But it works with widgets.
    
        QApplication app(argc, argv);
        QMainWindow window;
    
        // QOpenGLWidget with OpenSceneGraph content
        QtOSGWidget* widget = new QtOSGWidget();
    
        window.setCentralWidget(widget);
        window.show();
        return app.exec();
    }
    
    0 讨论(0)
提交回复
热议问题