简体   繁体   中英

Qt GUI application on macOS: how to find the currently active screen?

We are developing a macOS application whose GUI is relying on Qt.

At startup, we want to show() the QMainWindow at a specific location on the currently active screen (with multi screen systems in mind).

Is there a way to get the QScreen representing the currently active screen?

From our test, QGuiApplication::primaryScreen() is the first screen (which is consistent with the name), but we cannot find an equivalent for the active screen.

Qt5 provides functionality to do so, the QWindow::setScreen method sets the screen on which the window should be shown.

Any widget provides access to this pointer via QWidget::windowHandle() :

QWidget * widget = new QWidget();
auto screens = qApp->screens();
// compute the index
widget->windowHandle()->setScreen(screens[index]);
widget->showFullScreen();

To get the screen number, you can use the mouse position and assume that the screen with the mouse is the one with the current focus:

QPoint globalCursorPos = QCursor::pos();
int mouseScreen = qApp->desktop()->screenNumber(globalCursorPos); 

So the final code can be something like that:

QWidget * widget = new QWidget();
const auto globalCursorPos = QCursor::pos();
const auto mouseScreen = qApp->desktop()->screenNumber(globalCursorPos); 
widget->windowHandle()->setScreen(qApp->screens()[mouseScreen]);
widget->showFullScreen();

Windows

If this approach does not fit your needs, you will need to perform some OS calls.

For instance, on Windows, you can use MonitorFromWindow :

HMONITOR active_monitor_number = MonitorFromWindow(GetActiveWindow(), MONITOR_DEFAULTTONEAREST);

If you need more information about the screen, you can use Qt or GetMonitorInfo .

I am not a Mac OS X developer, but it may exist a similar API

I did it in the following way:

#if (QT_VERSION >= QT_VERSION_CHECK(5, 10, 0))
    QPoint topLeft = QPoint(0, 0);
    QScreen* currentScreen = QGuiApplication::screenAt(QCursor::pos());
    if (nullptr != currentScreen) {
        topLeft = currentScreen->geometry().topLeft();
    }
#else
    QPoint topLeft =
      qApp->desktop()
        ->screenGeometry(qApp->desktop()->screenNumber(QCursor::pos()))
        .topLeft();
#endif
    someWidget->move(mapFromGlobal(topLeft) + QPoint(offset, offset));

Note that, sometimes, you may get nullptr for currentScreen (in my case if primary screen is at the bottom and mouse pos at the bottom or left edge on the primary screen).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM