What's New in Qt 5: The QScreen Class

Jeff Tranter

Jeff Tranter


Jeff Tranter is a Qt Consulting Manager at ICS. Jeff oversees the architectural and high-level design of software systems for clients. Jeff’s leadership organizes global teams of developers on desktop and embedded applications.

By Jeff Tranter | Monday, February 11, 2013

QScreen is a new class introduced in Qt 5.0.0 that returns information about screen properties, where screen here refers to a display, such as a monitor or LCD panel.

[Update: It was pointed out that Qt 4 has a class named QScreen. However, the QScreenclass in Qt 4 was entirely different from the one in Qt 5 with different APIs and used for a different purpose. So I really consider them to be different classes.]

It can be used to allow your application to handle different screen sizes, multiple screens, or calculate the physical size of items on the screen.

In Qt 4 you could get some of this information from the QX11Info and QDesktopWidgetclasses.

The QScreen class has 20 properties and a number of methods and signals. It is a subclass of QObject.

The QGuiApplication class (new in Qt 5) provides methods that will return the primary screen or a list of all screens as QScreen pointers.

The QWindow class can return the screen it was created on or let you set the screen it appears on using a method or in the constructor.

I'll show here a very simple text-based Qt example program that lists information for the display screens. While it is a non-graphical application, we do need to create aQGuiApplication object since it needs to exist in order to get the information about the screens.

Here is sample output on one system I ran it on:

Number of screens: 2 
Primary screen: "VGA-0" 
Information for screen: "VGA-0" 
  Available geometry: 0 0 1920 x 1165 
  Available size: 1920 x 1165 
  Available virtual geometry: 0 0 3520 x 1165 
  Available virtual size: 3520 x 1165 
  Depth: 24 bits 
  Geometry: 0 0 1920 x 1200 
  Logical DPI: 94.1432 
  Logical DPI X: 93.0364 
  Logical DPI Y: 95.25 
  Orientation: "Landscape" 
  Physical DPI: 94.1104 
  Physical DPI X: 94.1467 
  Physical DPI Y: 94.0741 
  Physical size: 518 x 324 mm 
  Primary orientation: "Landscape" 
  Refresh rate: 72 Hz 
  Size: 1920 x 1200 
  Virtual geometry: 0 0 3520 x 1200 
  Virtual size: 3520 x 1200 
Information for screen: "LVDS-0" 
  Available geometry: 1920 0 1600 x 900 
  Available size: 1600 x 900 
  Available virtual geometry: 0 0 3520 x 1165 
  Available virtual size: 3520 x 1165 
  Depth: 24 bits 
  Geometry: 1920 0 1600 x 900 
  Logical DPI: 94.1432 
  Logical DPI X: 93.0364 
  Logical DPI Y: 95.25 
  Orientation: "Landscape" 
  Physical DPI: 117.987 
  Physical DPI X: 118.14 
  Physical DPI Y: 117.835 
  Physical size: 344 x 194 mm 
  Primary orientation: "Landscape" 
  Refresh rate: 72 Hz 
  Size: 1600 x 900 
  Virtual geometry: 0 0 3520 x 1200 
  Virtual size: 3520 x 1200 

Here is the complete source code for the example:

#include <QGuiApplication>
#include <QScreen>
#include <QDebug>

/*
  Example of using Qt 5 QScreen class.
*/

// Helper function to return display orientation as a string.
QString Orientation(Qt::ScreenOrientation orientation)
{
    switch (orientation) {
        case Qt::PrimaryOrientation           : return "Primary";
        case Qt::LandscapeOrientation         : return "Landscape";
        case Qt::PortraitOrientation          : return "Portrait";
        case Qt::InvertedLandscapeOrientation : return "Inverted landscape";
        case Qt::InvertedPortraitOrientation  : return "Inverted portrait";
        default                               : return "Unknown";
    }
}

int main(int argc, char *argv[])
{
    QGuiApplication a(argc, argv);

    qDebug() << "Number of screens:" << QGuiApplication::screens().size();

    qDebug() << "Primary screen:" << QGuiApplication::primaryScreen()->name();

    foreach (QScreen *screen, QGuiApplication::screens()) {
        qDebug() << "Information for screen:" << screen->name();
        qDebug() << "  Available geometry:" << screen->availableGeometry().x() << screen->availableGeometry().y() << screen->availableGeometry().width() << "x" << screen->availableGeometry().height();
        qDebug() << "  Available size:" << screen->availableSize().width() << "x" << screen->availableSize().height();
        qDebug() << "  Available virtual geometry:" << screen->availableVirtualGeometry().x() << screen->availableVirtualGeometry().y() << screen->availableVirtualGeometry().width() << "x" << screen->availableVirtualGeometry().height();
        qDebug() << "  Available virtual size:" << screen->availableVirtualSize().width() << "x" << screen->availableVirtualSize().height();
        qDebug() << "  Depth:" << screen->depth() << "bits";
        qDebug() << "  Geometry:" << screen->geometry().x() << screen->geometry().y() << screen->geometry().width() << "x" << screen->geometry().height();
        qDebug() << "  Logical DPI:" << screen->logicalDotsPerInch();
        qDebug() << "  Logical DPI X:" << screen->logicalDotsPerInchX();
        qDebug() << "  Logical DPI Y:" << screen->logicalDotsPerInchY();
        qDebug() << "  Orientation:" << Orientation(screen->orientation());
        qDebug() << "  Physical DPI:" << screen->physicalDotsPerInch();
        qDebug() << "  Physical DPI X:" << screen->physicalDotsPerInchX();
        qDebug() << "  Physical DPI Y:" << screen->physicalDotsPerInchY();
        qDebug() << "  Physical size:" << screen->physicalSize().width() << "x" << screen->physicalSize().height() << "mm";
        qDebug() << "  Primary orientation:" << Orientation(screen->primaryOrientation());
        qDebug() << "  Refresh rate:" << screen->refreshRate() << "Hz";
        qDebug() << "  Size:" << screen->size().width() << "x" << screen->size().height();
        qDebug() << "  Virtual geometry:" << screen->virtualGeometry().x() << screen->virtualGeometry().y() << screen->virtualGeometry().width() << "x" << screen->virtualGeometry().height();
        qDebug() << "  Virtual size:" << screen->virtualSize().width() << "x" << screen->virtualSize().height();
    }
}


In summary, the new QScreen class in Qt 5 in a useful class for getting information about the properties of the display screens on a system in a portable manner. In addition to the properties demonstrated in this example, it also supports a number of methods and can emit signals when the display properties change.

You can download the source code for the example, at least for the next little while, fromhere.


Comments

Comment: 

Hi Jeff Tranter,

Thank you very much for your usefull post! I have some questions as below:

1. on which platform (x86 desktop, embedded linux) did you run that code?

2. I have 2 fb devices on my target board running linux 3.4.23 but the screen().size() returns only 1.

I have been around this for days but got no answer yet. Could you address this?

Thank you!

Comment: 
I ran my example on an x86 Linux Desktop running X11. I don't currently have access to an embedded Linux running Qt 5 to try it. It should work with the Linux frame buffer if Qt is properly configured and working for it. The relevant Qt source code is in qtbase/src/plugins/platforms/linuxfb/qlinuxfbscreen.cpp. You could add some debugging statements to that code to see what it is doing on your hardware. If you still need help, ask on the Qt interest mailing list (http://lists.qt-project.org/mailman/listinfo/interest).