Platform APIs in Qt 6
While Qt solves many of the typical tasks of writing an application, there are always corner cases that Qt can not cover, or where it makes more sense to build a feature on top of the platform specific APIs, or another toolkit. One of the tasks we wanted to address for Qt 6 was to clean up and coordinate the various mechanisms we had for accessing platform-specific functionality.
We'll now go through the result of this work in Qt 6. The full documentation is available in the documentation snapshots, as part of the new Platform Integration section.
For example, to get the current user's username on Apple platforms:
NSProcessInfo *processInfo = NSProcessInfo.processInfo;
QString userName = QString::fromNSString(processInfo.userName)
For a complete list of all type conversions, see the Type Conversions overview.
Windows created by the underlying platform APIs may be used as both parent containers for Qt windows, or embedded into Qt windows as child windows.
The former is useful if the application is mainly written using the native platform APIs, but where parts of the application use Qt, for example to draw a specialized UI. To embed Qt into the window hierarchy of the native application, use QWindow::winId() to get the native handle for the Qt window, and then use the native APIs to re-parent the window into the native UI.
The latter is useful if the native platform, or another toolkit, exposes a specialized control as a native window. By using QWindow::fromWinId() to wrap the native window handle in a QWindow, the window can then be re-parented into the Qt window hierarchy as any other QWindow. To re-parent this QWindow into a Qt Widget based UI, use the widgets-specific QWidget::createWindowContainer() function.
In cases where this is not enough, Qt provides access to the delivery of the native events. A global event filter that receives all native events can be installed by using QCoreApplication::installNativeEventFilter(), while per-window native events can be handled in QWindow::nativeEvent().
Note: Interfering with the native event flow may put Qt in an inconsistent state. These APIs should primarily be used to augment Qt's existing event handling, for example for events Qt doesn't handle yet.
Platform specific functionality not covered by the APIs mentioned above are handled by the new generic native interface mechanism. This mechanism replaces the platform headers user-facing API, as well as the QPA-level
QPlatformNativeInterface API. The interfaces provide access to native or platform specific APIs of the classes they extend.
The interfaces live in the QNativeInterface namespace, and cover use-cases such as accessing underlying native handles, adopting existing native handles, or providing platform specific APIs.
The majority of the old platform header APIs can be found in the
QNativeInterface::Private namespace, since these were largely used by other internal code. Over time we'll expose more of these APIs based on feedback and use-cases.
In situations where a feature of the native platform is not exposed in Qt, it can be helpful to access the native handles maintained by Qt, and use those to call the native APIs instead.
using namespace QNativeInterface;
if (auto *cocoaGLContext = glContext->nativeInterface<QCocoaGLContext>())
The native interface is accessed through the QOpenGLContext::nativeInterface() accessor, which ensures that the requested interface is available, and otherwise returns
nullptr. The underlying NSOpenGLContext is then accessed through the nativeContext() accessor.
Similarly to the window embedding use-case, there are situations where the native platform, or another toolkit, has created a native handle that you would like to pass on to Qt — wrapping the existing handle instead of creating a new one.
For example, to adopt an existing NSOpenGLContext, and use that to share resources with a context created by Qt:
using namespace QNativeInterface;
QOpenGLContext *adoptedContext = QCocoaGLContext::fromNativeContext(nsOpenGLContext);
The adopted context is created by a platform specific factory function in the QNativeInterface::QCocoaGLContext native interface.
In some cases an API is too platform specific to be included in the cross platform Qt classes, but is still useful to include. These APIs are available either in the same way as when accessing the underlying native handles, through the nativeInterface() accessor, or directly as static function in the native interface.
For example, to obtain the OpenGL module handle on Windows:
using namespace QNativeInterface;
HMODULE moduleHandle = QWGLContext::openGLModuleHandle();
Or to tweak the border behavior of a window on Windows, via its platform window handle:
using namespace QNativeInterface::Private;
if (auto *windowsWindow = dynamic_cast<QWindowsWindow*>(window->handle()))
One important thing to note is that are no source or binary compatibility guarantees for the native interface APIs, meaning that an application using these interfaces is only guaranteed to work with the Qt version it was developed against. This allows us to adjust and add to these APIs as needed -- making them more flexible in tracking the underlying native functionality.
As some of you have noticed, the "extras" modules are not part of the initial Qt 6.0 release. This is related to the work described in this blog post, as we still need to go through these modules to survey:
- Whether any features are deprecated and can be removed
- Whether any features have more modern replacements that we should advocate instead
- Whether any features can be better solved by integrating directly with the native APIs
- Whether any features fit better in the API paradigms described earlier, for example as native interfaces
The end goal would ideally be that we don't need any standalone "extras" module, but rather that the functionality is available directly in the relevant modules, e.g. QtGui or QtDeclarative. If you want to track this work you can follow QTBUG-83251.
Subscribe to our newsletter
Try Qt 5.15 LTS Now!
Download the latest release here: www.qt.io/download.
Qt 5.15 was developed with a strong focus on quality and is a long-term-supported (LTS) release that will be supported for 3 years.
Check out all our open positions here and follow us on Instagram to see what it's like to be #QtPeople.
Näytä tämä julkaisu Instagramissa.
Want to build something for tomorrow, join #QtPeople today! We have loads of cool jobs you don’t want to miss! http://qt.io/careers #builtwithQt #software #developers #coding #framework #tool #tooling #C++ #QML #engineers #sales #tech #technology #UI #UX #CX #Qt #Qtdev #global #openpositions #careers #job
Henkilön Qt (@theqtcompany) jakama julkaisu