Qt für eingebettetes Linux

Plattform-Plugins für eingebettete Linux-Geräte

Für Embedded Linux-Systeme gibt es mehrere Plattform-Plugins, die Sie verwenden können: EGLFS, VkKhrDisplay, LinuxFB, oder Wayland. Die Verfügbarkeit dieser Plugins hängt davon ab, wie Qt konfiguriert ist. Von diesen Plugins erfordert Wayland das Vorhandensein eines Compositors und bietet ein vollständiges Fenstersystem, das mehrere Fenster unterstützt, ähnlich wie X11 oder Windows. Die anderen arbeiten ohne Windowing-System, d.h. die Qt-Anwendung hat die volle Kontrolle über das Rendering und die Ausgabe. Sie unterstützen in der Regel ein Vollbild-Qt-"Fenster" pro Bildschirm.

EGLFS ist das Standard-Plugin auf vielen Boards. Wenn es nicht geeignet ist, verwenden Sie die Umgebungsvariable QT_QPA_PLATFORM, um ein anderes Plugin anzufordern. Alternativ können Sie für schnelle Tests das Kommandozeilenargument -platform mit der gleichen Syntax verwenden.

Hinweis: Seit Qt 5.0 verfügt Qt nicht mehr über eine eigene Implementierung des Fenstersystems (QWS). Für Anwendungsfälle mit einem Prozess ist die Qt Platform Abstraction die bessere Lösung; Anwendungsfälle mit mehreren Prozessen werden durch Wayland unterstützt.

Siehe Konfigurieren eines Embedded-Linux-Geräts für einen Überblick über die Konfiguration von Qt für die Cross-Kompilierung unter Verwendung einer Embedded-Linux-Toolchain.

EGLFS

EGL ist eine Schnittstelle zwischen OpenGL und dem nativen Windowing-System. Qt kann EGL für das Kontext- und Oberflächenmanagement nutzen, allerdings enthält die API keine plattformspezifischen Eigenschaften. Das Erstellen eines nativen Fensters, das nicht unbedingt ein tatsächliches Fenster auf dem Bildschirm ist, muss immer noch mit plattformspezifischen Mitteln erfolgen. Aus diesem Grund benötigen wir den Board- oder GPU-spezifischen Anpassungscode. Typischerweise werden diese Anpassungen wie folgt bereitgestellt:

  • EGLFS Hooks - eine einzelne Quelldatei, die in das Plattform-Plugin kompiliert wird
  • EGL-Geräteintegration - dynamisch geladene Plugins

EGLFS ist ein Plattform-Plugin für die Ausführung von Qt-Anwendungen auf EGL und OpenGL ES 2.0, ohne ein tatsächliches Windowing-System wie X11 oder Wayland. Es ist das empfohlene Plugin für moderne Embedded Linux-Geräte, die eine GPU enthalten.

Zusätzlich zu Qt Quick und nativen OpenGL-Anwendungen unterstützt EGLFS auch software-gerenderte Fenster, wie QWidget. Bei QWidget werden die Inhalte der Widgets von der CPU in Bilder umgewandelt, die dann in Texturen hochgeladen und vom Plugin zusammengesetzt werden.

EGLFS erzwingt, dass das erste Fenster der obersten Ebene - entweder ein QWidget oder ein QQuickView - zum Vollbild wird. Dieses Fenster wird auch als Root-Widget-Fenster ausgewählt, in dem alle anderen Widgets der obersten Ebene zusammengesetzt werden. Zum Beispiel Dialoge, Popup-Menüs oder Kombinationsfelder. Dieses Verhalten ist notwendig, weil es bei EGLFS immer genau ein natives Fenster und eine EGL-Fensteroberfläche gibt; diese gehören zu dem Widget oder Fenster, das zuerst erstellt wird. Dieser Ansatz funktioniert gut, wenn es ein Hauptfenster gibt, das für die gesamte Lebensdauer der Anwendung existiert, und alle anderen Widgets entweder keine Top-Levels sind oder erst danach erstellt werden, sobald das Hauptfenster angezeigt wird.

Es gibt weitere Einschränkungen für OpenGL-basierte Fenster. EGLFS unterstützt ein einzelnes bildschirmfüllendes GL-Fenster (ab Qt 5.3), wie z.B. ein OpenGL-basiertes QWindow, ein QQuickView oder ein QOpenGLWidget. Das Öffnen zusätzlicher OpenGL-Fenster oder das Mischen solcher Fenster mit QWidget-basierten Inhalten wird nicht unterstützt; Qt beendet die Anwendung mit einer Fehlermeldung.

Außerdem werden APIs, die für Desktop-Plattformen oder Umgebungen mit einem Fenstersystem entwickelt wurden, wie z.B. Drag and Drop, auf EGLFS nicht unterstützt.

Von EGLFS verwendete Umgebungsvariablen

Falls erforderlich, kann eglfs mit Hilfe der folgenden Umgebungsvariablen konfiguriert werden:

UmgebungsvariableBeschreibung
QT_QPA_EGLFS_INTEGRATIONZusätzlich zu den einkompilierten Hooks können auch dynamisch geladene Plugins verwendet werden, um eine geräte- oder herstellerspezifische Anpassung zu ermöglichen. Diese Umgebungsvariable erzwingt ein bestimmtes Plugin. Wird sie zum Beispiel auf eglfs_kms gesetzt, wird das KMS/DRM-Backend verwendet. Dies ist nur eine Option, wenn in den Geräte-Makespecs keine statischen oder einkompilierten Hooks angegeben wurden. In der Praxis werden die traditionellen einkompilierten Hooks nur noch selten verwendet, fast alle Backends sind inzwischen zu Plugins migriert. Die Geräte-Makespecs enthalten immer noch einen relevanten, wenn auch optionalen, EGLFS_DEVICE_INTEGRATION Eintrag: den Namen des bevorzugten Backends für dieses bestimmte Gerät. Vermeiden Sie es, diese Umgebungsvariable zu setzen, wenn mehr als ein Plugin auf dem Zielsystem vorhanden ist. In einer Desktop-Umgebung werden die KMS- oder X11-Backends priorisiert, je nach Vorhandensein der Umgebungsvariablen DISPLAY.

Hinweis: Auf einigen Boards wird ein spezieller Wert von none anstelle eines tatsächlichen Plugins verwendet. Dies zeigt an, dass keine spezielle Integration notwendig ist, um EGL mit dem Framebuffer zu verwenden; es müssen keine Plugins geladen werden.

QT_QPA_EGLFS_PHYSICAL_WIDTH und QT_QPA_EGLFS_PHYSICAL_HEIGHTGibt die Breite und Höhe des physischen Bildschirms in Millimetern an. Beachten Sie, dass seit Qt 6 die physikalische Bildschirmgröße nicht mehr zur Bestimmung der logischen dpi verwendet wird.
QT_QPA_EGLFS_ROTATIONLegt die Rotation fest, die auf software-gerenderte Inhalte in QWidget-basierten Anwendungen angewendet wird. Unterstützte Werte sind 180, 90, und -90. Diese Variable gilt nicht für OpenGL-basierte Fenster, einschließlich Qt Quick. Qt Quick Anwendungen können stattdessen Transformationen in ihrer QML-Szene anwenden. Der Standard-Mauszeiger eglfs berücksichtigt den Wert immer und zeigt ein entsprechend positioniertes und gedrehtes Zeigerbild an, unabhängig vom Anwendungstyp. Spezielle Cursor-Implementierungen, wie z. B. der Hardware-Cursor des KMS/DRM-Backends, unterstützen jedoch möglicherweise keine Rotation.
QT_QPA_EGLFS_FORCEVSYNCWenn sie gesetzt ist, fordert eglfs nach jedem Aufruf von eglSwapBuffers() FBIO_WAITFORVSYNC auf dem Framebuffer-Gerät an. Diese Variable ist nur für Backends relevant, die sich auf das alte Linux fbdev Subsystem verlassen. Normalerweise geht Qt bei einem Standard-Swap-Intervall von 1 davon aus, dass der Aufruf von eglSwapBuffers() sich um vsync kümmert; wenn dies nicht der Fall ist (zum Beispiel aufgrund von Treiberfehlern), versuchen Sie QT_QPA_EGLFS_FORCEVSYNC auf einen Wert ungleich Null zu setzen.
QT_QPA_EGLFS_FORCE888Wenn diese Option gesetzt ist, werden die Größen der roten, grünen und blauen Farbkanäle ignoriert, wenn eglfs einen neuen Kontext, ein Fenster oder eine Oberfläche außerhalb des Bildschirms erstellt. Stattdessen fordert das Plugin eine Konfiguration mit 8 Bit pro Kanal an. Dies kann auf Geräten hilfreich sein, auf denen standardmäßig Konfigurationen mit weniger als 32 oder 24 Bits pro Pixel (z. B. 5-6-5 oder 4-4-4) gewählt werden, obwohl bekannt ist, dass sie nicht ideal sind, z. B. aufgrund von Banding-Effekten. Anstatt den Anwendungscode zu ändern, bietet diese Variable eine Abkürzung, um 24- oder 32-Bit-pro-Pixel-Konfigurationen zu erzwingen.

Zusätzlich sind die folgenden, weniger häufig verwendeten Variablen verfügbar:

UmgebungsvariableBeschreibung
QT_QPA_EGLFS_FBSetzt das Framebuffer-Gerät außer Kraft. Die Vorgabe ist /dev/fb0. Auf den meisten eingebetteten Plattformen ist diese Variable nicht sehr relevant, da der Framebuffer nur zur Abfrage von Einstellungen wie den Display-Abmessungen verwendet wird. Auf bestimmten Geräten bietet diese Variable jedoch die Möglichkeit festzulegen, welches Display bei mehreren Display-Setups verwendet werden soll, ähnlich wie der Parameter fb in LinuxFB.
QT_QPA_EGLFS_WIDTH und QT_QPA_EGLFS_HEIGHTEnthält die Breite und Höhe des Bildschirms in Pixeln. Während eglfs versucht, die Abmessungen aus dem Framebuffer-Gerät /dev/fb0 zu ermitteln, funktioniert dies nicht immer. Es kann notwendig sein, die Größen manuell festzulegen.
QT_QPA_EGLFS_DEPTHSetzt die Farbtiefe für den Bildschirm außer Kraft. Auf Plattformen, auf denen das Framebuffer-Gerät /dev/fb0 nicht verfügbar ist oder die Abfrage nicht erfolgreich war, wird die Voreinstellung 32 verwendet. Verwenden Sie diese Variable, um solche Voreinstellungen zu überschreiben.

Hinweis: Diese Variable wirkt sich nur auf den von QScreen gemeldeten Farbtiefenwert aus. Sie hat keinen Bezug zu EGL-Konfigurationen und der für das OpenGL-Rendering verwendeten Farbtiefe.

QT_QPA_EGLFS_SWAPINTERVALStandardmäßig wird ein Swap-Intervall von 1 angefordert. Diese Variable ermöglicht die Synchronisierung mit der vertikalen Aktualisierung des Bildschirms. Verwenden Sie diese Variable, um den Wert des Swap-Intervalls außer Kraft zu setzen. Wenn Sie z.B. 0 angeben, wird das Blockieren beim Swap deaktiviert, was dazu führt, dass das Programm so schnell wie möglich ohne jegliche Synchronisation läuft.
QT_QPA_EGLFS_DEBUGWenn sie gesetzt ist, werden einige Debugging-Informationen in der Debug-Ausgabe ausgegeben. Zum Beispiel werden die Eingabe QSurfaceFormat und die Eigenschaften der gewählten EGL-Konfiguration beim Erstellen eines neuen Kontexts ausgegeben. In Verbindung mit der Variable Qt Quick's QSG_INFO können Sie nützliche Informationen für die Fehlersuche bei Problemen mit der EGL-Konfiguration erhalten.

Protokollierung

Zusätzlich zu QT_QPA_EGLFS_DEBUG unterstützt eglfs auch das moderne kategorisierte Logging-System von Qt. Die folgenden Logging-Kategorien sind verfügbar:

  • qt.qpa.egldeviceintegration - Aktiviert die Protokollierung für dynamisch geladene Backends. Verwenden Sie diese Kategorie, um zu überprüfen, welches Backend verwendet wird.
  • qt.qpa.input - Ermöglicht Debug-Ausgaben sowohl von evdev als auch von libinput input handlers. Verwenden Sie diese Kategorie, um zu prüfen, ob ein bestimmtes Eingabegerät erkannt und geöffnet wurde.
  • qt.qpa.eglfs.kms - Aktiviert die ausführliche Protokollierung im KMS/DRM-Backend.

Nachdem Sie configure ausgeführt haben, sollten Sie die Ausgabe überprüfen. Dies ist der einfachste und schnellste Weg, um festzustellen, ob Sie das notwendige EGLFS-Backend, libudev oder libinput aktiviert haben. Kurz gesagt, wenn in der Ausgabe von configure ein unerwünschtes "no" erscheint, führen Sie es aus:

./configure -v

um die ausführliche Ausgabe einzuschalten, so dass Sie die Compiler- und Linker-Aufrufe für jeden configure-Test sehen können.

Anmerkung: Wenn Sie Fehlermeldungen über fehlende Header, Bibliotheken oder scheinbar kryptische Linker-Fehler erhalten, sind diese oft ein Zeichen für eine unvollständige oder kaputte Sysroot und haben nichts mit Qt zu tun.

Wenn Sie zum Beispiel den Raspberry Pi mit den proprietären Broadcom-Grafiktreibern ansteuern, sollte die Ausgabe in etwa wie folgt aussehen:

QPA backends:
EGLFS ................................ yes
EGLFS details:
  EGLFS i.Mx6 ........................ no
  EGLFS i.Mx6 Wayland ................ no
  EGLFS EGLDevice .................... no
  EGLFS GBM .......................... no
  EGLFS Mali ......................... no
  EGLFS Raspberry Pi ................. yes
  EGL on X11 ......................... no

Wenn dies nicht der Fall ist, ist es nicht ratsam, mit dem Build fortzufahren, da die beschleunigte Grafik ohne das Raspberry Pi-spezifische Backend nicht funktioniert, selbst wenn der Rest von Qt erfolgreich kompiliert wird.

VkKhrDisplay

Während EGLFS nur OpenGL (ES) unterstützt, ist VkKhrDisplay ein experimentelles Plattform-Plugin, das Rendering mit der Vulkan-API unterstützt. Zum Aufzählen von Anzeigen und zum Einrichten des Renderings stützt es sich auf die VK_KHR_display-Familie von Erweiterungen. Es ist nicht vorausgesetzt, dass eine Vulkan-Implementierung innerhalb eines Grafik-Stacks diese Funktionalität unterstützt. Derzeit wurde dieses Plattform-Plugin mit Mesa und V3DV auf einem Raspberry Pi 4 verifiziert und getestet.

Dieses Plattform-Plugin unterstützt weder OpenGL noch irgendein Software-Rendering. Der Versuch, eine QWidget-basierte Benutzeroberfläche anzuzeigen, wird daher fehlschlagen. Der einzige unterstützte QWindow -Oberflächentyp ist QSurface::VulkanSurface. Für Qt Quick Anwendungen bedeutet dies, dass Vulkan-basiertes Rendering erzwungen werden muss, entweder durch die Einstellung QSG_RHI_BACKEND=vulkan in der Umgebung oder durch den Aufruf von QQuickWindow::setGraphicsApi(QSGRendererInterface::Vulkan); zu einem frühen Zeitpunkt, bevor ein QQuickWindow oder QQuickView erstellt wird.

Um dieses Plattform-Plugin zu verwenden, führen Sie die Anwendung mit -platform vkkhrdisplay aus oder setzen Sie QT_QPA_PLATFORM auf vkkhrdisplay. Das Plugin wird nur erstellt, wenn Qt mit Vulkan-Unterstützung konfiguriert ist.

Eine erweiterte Konfiguration im EGLFS-Stil (z. B. die JSON-Konfigurationsdatei) oder die Ausgabe auf mehrere Bildschirme aus derselben Anwendung sind derzeit nicht implementiert. Anwendungen können jedoch den zu verwendenden Bildschirm über Umgebungsvariablen auswählen.

Um die Indexwerte zu ermitteln, überprüfen Sie die Protokolle, die das Plugin in der Debug-Ausgabe ausgibt. Derzeit sind diese Protokolle nicht kategorisiert (sie werden über qDebug ausgegeben), da ihre Überprüfung in den meisten Fällen unerlässlich ist, um sicherzustellen, dass das Plugin die richtige Anzeige und den richtigen Modus auswählt.

  • QT_VK_DISPLAY_INDEX - Wenn gesetzt, wird die Anzeige mit dem angegebenen Index verwendet.
  • QT_VK_MODE_INDEX - Wenn gesetzt, wird der Modus mit dem angegebenen Index verwendet.
  • QT_VK_PHYSICAL_DEVICE_INDEX - Wenn gesetzt, wird das physikalische Vulkan-Gerät mit dem angegebenen Index verwendet. Dies wird in den meisten Fällen bei Embedded nicht relevant sein. Beachten Sie, dass diese Variable auch vom Rest des Qt-Grafikstacks verwendet wird.

Die Behandlung von Eingaben (Tastatur, Maus, Touch) ist ähnlich wie bei EGLFS und unterstützt evdev, libinput und tslib. Es ist jedoch kein Mauszeiger-Rendering implementiert. Dies liegt daran, dass es in dieser Umgebung kein Konzept eines Hardware-Cursors gibt und das Rendern eines Cursors mit Vulkan innerhalb des Plattform-Plugins, ähnlich wie EGLFS es mit OpenGL macht, aus mehreren Gründen problematisch ist. Daher ist dieses Plattform-Plugin im Moment nicht gut für mausbasierte Eingaben geeignet.

Die entsprechenden Umgebungsvariablen sind:

  • QT_QPA_DISABLE_INPUT - Deaktiviert Tastatur/Maus/Touch-Eingabe.
  • QT_QPA_NO_LIBINPUT - Bevorzugt die evdev-basierten Input-Handler, auch wenn libinput verfügbar ist.
  • QT_QPA_TSLIB - Fordert die Verwendung der alten tslib-Bibliothek an.

LinuxFB

Dieses Plugin schreibt direkt in den Framebuffer über das fbdev-Subsystem von Linux. Es werden nur software-gerenderte Inhalte unterstützt. Beachten Sie, dass bei einigen Konfigurationen die Anzeigeleistung eingeschränkt sein dürfte. Um Qt Quick Anwendungen mit diesem Plattform-Plugin zu verwenden, muss das software Scenegraph-Backend verwendet werden, entweder durch Setzen von QT_QUICK_BACKEND=software in der Umgebung oder durch Aufrufen von setGraphicsApi() mit QSGRendererInterface::Software. QWidget Anwendungen oder QWindow mit einem Oberflächentyp von QSurface::RasterSurface werden unterstützt, aber dies schließt keine speziellen Widgets wie QOpenGLWidget ein.

Da fbdev im Linux-Kernel veraltet ist, ist auch die Unterstützung für DRM-Dumb-Buffer verfügbar. Um sie zu nutzen, setzen Sie die Umgebungsvariable QT_QPA_FB_DRM auf einen Wert ungleich Null. Wenn sie gesetzt ist und Ihr System Dumb Buffer unterstützt, wird nicht auf ältere Framebuffer-Geräte wie /dev/fb0 zugegriffen. Stattdessen wird das Rendering über die DRM-APIs eingerichtet, ähnlich wie das eglfs_kms Backend in EGLFS. Die Ausgabe ist doppelt gepuffert und seitenverkehrt, so dass auch für softwaregerenderte Inhalte ein korrektes Vsync gewährleistet ist.

Hinweis: Wenn Dumb Buffer verwendet werden, ist keine der unten beschriebenen Optionen anwendbar, da Eigenschaften wie physische und logische Bildschirmgrößen automatisch abgefragt werden.

Festlegen zusätzlicher Einstellungen

Mit dem Plugin linuxfb können Sie zusätzliche Einstellungen über die Umgebungsvariable QT_QPA_PLATFORM oder die Befehlszeilenoption -platform festlegen. Zum Beispiel gibt QT_QPA_PLATFORM=linuxfb:fb=/dev/fb1 an, dass das Framebuffer-Gerät /dev/fb1 anstelle des Standardgeräts fb0 verwendet werden muss. Um mehrere Einstellungen anzugeben, trennen Sie die m mit einem Doppelpunkt (:).

EinstellungenBeschreibung
fb=/dev/fbNLegt die Framebuffer-Geräte fest. Bei der Verwendung mehrerer Bildschirme können Sie mit dieser Einstellung die Anwendung auf verschiedenen Bildschirmen laufen lassen. Derzeit gibt es keine Möglichkeit, mehrere Framebuffer in einer Qt-Anwendung zu verwenden.
size=<Breite>x<Höhe>Gibt die Bildschirmgröße in Pixeln an. Das Plugin versucht, die Display-Dimensionen, sowohl physisch als auch logisch, vom Framebuffer-Gerät abzufragen. Diese Abfrage führt jedoch nicht immer zu korrekten Ergebnissen; es kann notwendig sein, die Werte explizit anzugeben.
mmsize=<Breite>x<Höhe>Gibt die physische Breite und Höhe in Millimetern an.
offset=<Breite>x<Höhe>Legt die linke obere Ecke des Bildschirms in Pixeln fest. Die Standardposition ist bei (0, 0).
nographicsmodeswitchLegt fest, dass das virtuelle Terminal nicht in den Grafikmodus geschaltet wird (KD_GRAPHICS). Normalerweise werden durch die Aktivierung des Grafikmodus der blinkende Cursor und die Bildschirmausblendung deaktiviert. Wenn dieser Parameter jedoch gesetzt ist, werden diese beiden Funktionen ebenfalls übersprungen.
tty=/dev/ttyNSetzt die virtuelle Konsole außer Kraft. Wird nur verwendet, wenn nographicsmodeswitch nicht gesetzt ist.

Ab Qt 5.9 wurde das Verhalten von EGLFS und LinuxFB in Bezug auf die Fenstergrößenpolitik synchronisiert: das erste Fenster der obersten Ebene wird gezwungen, den gesamten Bildschirm zu bedecken, mit beiden Plattform-Plugins. Wenn dies nicht gewünscht ist, setzen Sie die Umgebungsvariable QT_QPA_FB_FORCE_FULLSCREEN auf 0, um das Verhalten früherer Qt-Versionen wiederherzustellen.

Ausgabe anzeigen

Der Grad der Unterstützung, um einen oder mehrere Bildschirme von einer einzigen Qt-Anwendung aus anzusteuern, variiert zwischen den Plattform-Plugins. Die Unterstützung hängt oft vom Gerät und seinem Grafikstack ab.

EGLFS mit dem eglfs_kms-Backend

Wenn das KMS/DRM-Backend verwendet wird, meldet EGLFS alle verfügbaren Bildschirme in QGuiApplication::screens(). Anwendungen können verschiedene Bildschirme mit verschiedenen Fenstern über QWindow::setScreen() ansteuern.

Hinweis: Die Beschränkung auf ein einziges Vollbildfenster pro Bildschirm gilt weiterhin. Das Wechseln von Bildschirmen nach dem Sichtbarmachen von QWindow wird ebenfalls nicht unterstützt. Daher ist es wichtig, dass eingebettete Anwendungen alle notwendigen QWindow::setScreen()-Aufrufe tätigen, bevor sie QWindow::show() aufrufen.

Wenn Sie mit der Entwicklung auf einem bestimmten eingebetteten Gerät beginnen, ist es oft notwendig, das Verhalten des Geräts und der Treiber zu überprüfen und sicherzustellen, dass die angeschlossenen Bildschirme so funktionieren, wie sie sollten. Eine einfache Möglichkeit ist die Verwendung des hellowindow Beispiels. Wenn Sie es mit den -platform eglfs --multiscreen --timeout Argumenten starten, wird auf jedem angeschlossenen Bildschirm für einige Sekunden ein rotierendes Qt-Logo angezeigt.

Benutzerdefinierte Konfiguration

Das KMS/DRM-Backend unterstützt auch benutzerdefinierte Konfigurationen über eine JSON-Datei. Um dies zu aktivieren, setzen Sie die Umgebungsvariable QT_QPA_EGLFS_KMS_CONFIG auf den Namen der Datei. Sie können diese Datei auch über das Qt-Ressourcensystem in die Anwendung einbetten.

Die meisten dieser Konfigurationsoptionen gelten für alle KMS/DRM-basierten Backends, unabhängig von der Pufferverwaltungstechnologie (GBM oder EGLStreams).

Hier ist eine Beispielkonfiguration:

{
  "device": "/dev/dri/card1",
  "hwcursor": false,
  "pbuffers": true,
  "outputs": [
    {
      "name": "VGA1",
      "mode": "off"
    },
    {
      "name": "HDMI1",
      "mode": "1024x768"
    }
  ]
}

Hier konfigurieren wir das angegebene Gerät so, dass:

  • Es wird den Hardware-Cursor nicht verwenden (es greift auf das Rendern des Mauszeigers über OpenGL zurück; standardmäßig sind Hardware-Cursor aktiviert, da sie effizienter sind).
  • Es unterstützt QOffscreenSurface mit Standard EGL pbuffer Oberflächen (standardmäßig ist dies deaktiviert und eine gbm Oberfläche wird stattdessen verwendet).
  • Die Ausgabe über den VGA-Anschluss ist deaktiviert, während HDMI mit einer Auflösung von 1024x768 aktiv ist.

Außerdem deaktiviert eine solche Konfiguration auch die Suche nach einem Gerät über libudev; stattdessen wird das angegebene Gerät verwendet.

Wenn mode nicht definiert ist, wird der bevorzugte Modus des Systems gewählt. Die akzeptierten Werte für mode sind: off, current, preferred, skip, BreitexHöhe, BreitexHöhe@vrefresh, oder eine Modeline-Zeichenkette.

Die Angabe von current wählt einen Modus mit einer Auflösung, die mit der aktuellen übereinstimmt. Da das Setzen des Modus nur dann erfolgt, wenn der gewünschte Modus sich tatsächlich vom aktiven unterscheidet (es sei denn, dies wird durch die Umgebungsvariable QT_QPA_EGLFS_ALWAYS_SET_MODE erzwungen), ist dieser Wert nützlich, um den aktuellen Modus und alle Inhalte in den Ebenen zu erhalten, die nicht von Qt berührt werden.

skip bewirkt, dass der Anschluss für die Ausgabe ignoriert wird, als ob er nicht angeschlossen wäre. off ist ähnlich, aber es ändert den Modus und schaltet die Anzeige aus.

Standardverhalten

Standardmäßig werden alle Bildschirme, die von der DRM-Schicht gemeldet werden, als ein großer virtueller Desktop behandelt. Die Implementierung des Mauszeigers berücksichtigt dies und bewegt sich wie erwartet über die Bildschirme. Obwohl nicht empfohlen, können Sie den virtuellen Desktop deaktivieren, indem Sie in der Konfiguration separateScreens auf false setzen.

Standardmäßig wird der virtuelle Desktop von links nach rechts gebildet, basierend auf der vom System gemeldeten Reihenfolge der Anschlüsse. Um dies zu ändern, setzen Sie virtualIndex auf einen Wert, der bei 0 beginnt.

Die folgende Konfiguration verwendet beispielsweise die bevorzugte Auflösung, stellt aber sicher, dass die linke Seite des virtuellen Desktops der mit dem HDMI-Anschluss verbundene Bildschirm ist, während die rechte Seite der mit dem DisplayPort verbundene Bildschirm ist:

{
  "device": "drm-nvdc",
  "outputs": [
    {
      "name": "HDMI1",
      "virtualIndex": 0
    },
    {
      "name": "DP1",
      "virtualIndex": 1
    }
  ]
}

Die Reihenfolge der Elemente im Array ist nicht relevant. Ausgänge mit nicht spezifizierten virtuellen Indizes werden hinter den anderen platziert, wobei die ursprüngliche Reihenfolge in der DRM-Anschlussliste beibehalten wird.

Um einen vertikalen Arbeitsbereich zu erstellen (d. h. von oben nach unten statt von links nach rechts zu stapeln), fügen Sie nach device eine Eigenschaft virtualDesktopLayout mit dem Wert vertical hinzu.

Warnung: Es wird empfohlen, dass alle Bildschirme des virtuellen Desktops die gleiche Auflösung verwenden, da sich sonst Elemente wie der Mauszeiger beim Betreten von Bereichen, die nur auf einem bestimmten Bildschirm vorhanden sind, unerwartet verhalten können.

Wenn virtualIndex nicht ausreicht, kann die Eigenschaft virtualPos verwendet werden, um die obere linke Position des betreffenden Bildschirms explizit anzugeben. Ausgehend vom vorherigen Beispiel und unter der Annahme einer Auflösung von 1080p für HDMI1 platziert der folgende Codeschnipsel einen zweiten HDMI-basierten Bildschirm unterhalb des ersten:

{
   ...
  "outputs": [
    ...
    {
      "name": "HDMI2",
      "virtualPos": "0, 1080"
    }
  ]
}

Hinweis: Vermeiden Sie solche Konfigurationen, wenn Mausunterstützung gewünscht ist. Das Verhalten des Mauszeigers kann bei nicht-linearen Layouts unerwartet sein. Touch sollte keine Probleme bereiten.

Automatische Abfrage der physischen Bildschirmgröße

In einigen Fällen kann die automatische Abfrage der physischen Bildschirmgröße über DRM fehlschlagen. Normalerweise würden die Umgebungsvariablen QT_QPA_EGLFS_PHYSICAL_WIDTH und QT_QPA_EGLFS_PHYSICAL_HEIGHT verwendet werden, um die fehlenden Werte zu liefern. Dies ist nicht mehr geeignet, wenn mehrere Bildschirme vorhanden sind. Verwenden Sie stattdessen die Eigenschaften physicalWidth und physicalHeight in der Liste outputs, um die Größen in Millimetern anzugeben.

Hinweis: Von unterschiedlichen physikalischen Größen und damit unterschiedlichen logischen DPI-Werten wird abgeraten, da dies zu unerwarteten Problemen führen kann, weil einige Komponenten des Grafikstapels nicht von mehreren Bildschirmen wissen und sich nur auf die Werte des ersten Bildschirms verlassen.

Aktive Ausgaben und QScreen-Instanzen

Jede aktive Ausgabe aus dem Array outputs entspricht einer Instanz von QScreen, die von QGuiApplication::screens() gemeldet wird. Standardmäßig ist der primäre Bildschirm, den QGuiApplication::primaryScreen() meldet, derjenige, der zuerst registriert wird. Wenn Sie nicht virtualIndex verwenden, bedeutet dies, dass die Entscheidung auf der Reihenfolge der DRM-Konnektoren basiert. Um dies außer Kraft zu setzen, setzen Sie die Eigenschaft primary auf true für den gewünschten Eintrag in der Liste outputs.

Um beispielsweise sicherzustellen, dass der Bildschirm, der dem VGA-Ausgang entspricht, der primäre ist, auch wenn das System den HDMI-Ausgang zuerst meldet, gehen Sie wie folgt vor:

{
  "device": "/dev/dri/card0",
  "outputs": [
      { "name": "HDMI1" },
      { "name": "VGA1", "mode": "1280x720", "primary": true },
      { "name": "LVDS1", "mode": "off" }
  ]
}

Für die Fehlersuche kann es nützlich sein, Debug-Protokolle vom KMS/DRM-Backend zu aktivieren. Aktivieren Sie dazu die Regel qt.qpa.eglfs.kms categorized logging.

Hinweis: In einer eingebetteten Umgebung sind virtuelle Desktops im Vergleich zu einem vollständigen Fenstersystem stärker eingeschränkt. Fenster, die mehrere Bildschirme überlappen, Nicht-Vollbildfenster und das Verschieben von Fenstern zwischen Bildschirmen sollten vermieden werden und funktionieren möglicherweise nicht wie erwartet.

Ein häufiger Anwendungsfall

Der häufigste und am besten unterstützte Anwendungsfall für ein Multi-Screen-Setup ist das Öffnen eines eigenen QQuickWindow oder QQuickView für jeden Bildschirm. Mit der standardmäßigen threaded Rendering-Schleife des Qt Quick Szenegraphen erhält jedes dieser Fenster seinen eigenen Rendering-Thread. Dies ist gut, weil die Threads unabhängig voneinander auf der Grundlage von vsync gedrosselt werden können und sich nicht gegenseitig stören. Bei der basic -Schleife kann dies problematisch werden und zu einer Verschlechterung der Animationen führen.

So können Sie beispielsweise alle angeschlossenen Bildschirme ermitteln und für jeden von ihnen eine QQuickView erstellen:

int main(int argc, char **argv)
{
    QGuiApplication app(argc, argv);

    QVector<QQuickView *> views;
    for (QScreen *screen : app.screens()) {
        QQuickView *view = new QQuickView;
        view->setScreen(screen);
        view->setResizeMode(QQuickView::SizeRootObjectToView);
        view->setSource(QUrl("qrc:/main.qml"));
        QObject::connect(view->engine(), &QQmlEngine::quit, qGuiApp, &QCoreApplication::quit);
        views.append(view);
        view->showFullScreen();
    }

    int result = app.exec();

    qDeleteAll(views);
    return result;
}

Erweiterte eglfs_kms-Funktionen

Klonen (Spiegeln)

Das Klonen (Spiegeln) von Bildschirmen wird unterstützt. Dies wird über die Eigenschaft clones aktiviert:

{
  "device": "/dev/dri/card0",
  "outputs": [
      { "name": "HDMI1", "mode": "1920x1080" },
      { "name": "DP1", "mode": "1920x1080", "clones": "HDMI1" }
 ]
}

In diesem Fall ist der Inhalt auf dem über DisplayPort angeschlossenen Bildschirm derselbe wie auf dem HDMI-Bildschirm. Dies wird dadurch sichergestellt, dass auf beiden der gleiche Puffer ausgelesen wird.

Diese Funktion kann jedoch nur funktionieren, wenn die Auflösungen gleich sind, es keine Inkompatibilitäten bei den akzeptierten Pufferformaten gibt und die Anwendung keine Ausgabe auf QScreen hat, die mit einem Klonziel verbunden ist. Letzteres bedeutet in der Praxis, dass kein QWindow, das mit dem fraglichen QScreen - im Beispiel DP1 - verbunden ist, jemals eine QOpenGLContext::swapBuffers()-Operation durchführen muss. Es liegt an der Konfiguration und der Anwendung, dies sicherzustellen.

Kopfloser Modus über DRM-Renderer

Der Headless-Modus über DRM-Render-Knoten wird unterstützt. Dies ermöglicht die Durchführung von GPU-Berechnungen (OpenGL-Compute-Shader, OpenCL) oder Off-Screen-OpenGL-Rendering, ohne dass DRM-Master-Rechte erforderlich sind. In diesem Modus können Anwendungen auch dann funktionieren, wenn bereits ein anderer Prozess die Ausgabe auf dem Bildschirm vornimmt.

Das Umschalten von device auf /dev/dri/card0 zu /dev/dri/renderD128 allein ist nutzlos, da es eine Reihe von Operationen gibt, die im Headless-Modus nicht ausgeführt werden können. Daher muss dies z. B. mit einer headless -Eigenschaft kombiniert werden:

{
    "device": "/dev/dri/renderD128",
    "headless": "1024x768"
}

Denken Sie daran, dass die Größe von Fenstern immer noch an die - jetzt virtuelle - Bildschirmgröße angepasst wird, daher die Notwendigkeit der Angabe einer Größe in der Eigenschaft headless. Es fehlt auch eine vsync-basierte Drosselung.

Einmal aktiviert, haben Anwendungen zwei typische Möglichkeiten, das Off-Screen-Rendering im Headless-Modus durchzuführen:

Die Verwendung eines gewöhnlichen Fensters, z. B. einer QOpenGLWindow -Unterklasse, das auf den Standard-Framebuffer des Fensters abzielt, was in der Praxis gbm_surface bedeutet:

MyOpenGLWindow w;
w.show(); // will not actually show up on screen
w.grabFramebuffer().save("output.png");

Oder der typische Offscreen-Ansatz mit einem zusätzlichen FBO:

QOffscreenSurface s;
s.setFormat(ctx.format());
s.create();
ctx.makeCurrent(&s);
QOpenGLFramebufferObject fbo(1024, 768);
fbo.bind();
ctx.functions()->glClearColor(1, 0, 0, 1);
ctx.functions()->glClear(GL_COLOR_BUFFER_BIT);
fbo.toImage().save("output.png");
ctx.doneCurrent();

DRM-API-Auswahl

KMS/DRM kann mit zwei verschiedenen DRM-APIs verwendet werden, nämlich Legacy und Atomic. Der Hauptvorteil der atomaren DRM-API besteht darin, dass sie mehrere DRM-Ebenenaktualisierungen innerhalb desselben Renderloops ermöglicht, während die Legacy-API eine Ebenenaktualisierung pro Vsync erfordern würde.

Die atomare API ist nützlich, wenn Ihre Anwendung Inhalte in Overlays einblenden muss, wobei alle Aktualisierungen innerhalb derselben Vsynchronisation erfolgen. Noch immer unterstützen nicht alle Geräte diese API und sie könnte auf einigen älteren Geräten nicht verfügbar sein. Das KMS-Backend verwendet standardmäßig die Legacy-API, aber Sie können die DRM-Atomic-API aktivieren, indem Sie die Umgebungsvariable QT_QPA_EGLFS_KMS_ATOMIC auf 1 setzen.

Die Verwendung eines kleineren Framebuffers als die Bildschirmauflösung kann ebenfalls nützlich sein. Dies ist mit DRM atomic unter Verwendung des Parameters size in der JSON-Datei möglich. Das folgende Beispiel verwendet einen Framebuffer von 1280x720 auf einem Videomodus von 3840x2160:

{
  "device": "/dev/dri/card0",
  "outputs": [
    { "name": "HDMI1", "mode": "3840x2160", "size": "1280x720", "format": "argb8888" }
  ]
}

EGLFS mit einem eglfs_kms_egldevice-Backend

Dieses Backend, das typischerweise auf Tegra-Geräten verwendet wird, ähnelt dem oben erwähnten KMS/DRM-Backend, mit der Ausnahme, dass es sich auf die EGLDevice- und EGLStream-Erweiterungen anstelle von GBM stützt.

Technische Details zu diesem Ansatz finden Sie in dieser Präsentation.

Ab Qt 5.7 teilt dieses Backend viele seiner internen Implementierungen mit dem GBM-basierten Backend. Dies bedeutet, dass mehrere Bildschirme und die erweiterte Konfiguration über QT_QPA_EGLFS_KMS_CONFIG unterstützt werden. Einige Einstellungen, wie hwcursor und pbuffers, sind jedoch nicht anwendbar.

Standardmäßig wählt das Backend automatisch die richtige EGL-Ebene für die Standardebene der jeweiligen Ausgabe. Bei Bedarf kann dies durch Setzen der Umgebungsvariablen QT_QPA_EGLFS_LAYER_INDEX auf den Index der gewünschten Ebene außer Kraft gesetzt werden. Dieser Ansatz unterstützt derzeit keine Mehrfachausgaben, so dass seine Verwendung auf Systeme mit einem einzigen Bildschirm beschränkt sein sollte. Um zu sehen, welche Ebenen verfügbar sind, und um mögliche Startprobleme zu beheben, aktivieren Sie die Protokollierungskategorie qt.qpa.eglfs.kms.

In einigen Fällen kann es notwendig sein, beim Start der Anwendung einen Videomodus zu setzen, auch wenn der Bildschirm meldet, dass die gewünschte Auflösung bereits eingestellt ist. Normalerweise wird dies wegoptimiert, aber wenn der Bildschirm ausgeschaltet bleibt, versuchen Sie, die Umgebungsvariable QT_QPA_EGLFS_ALWAYS_SET_MODE auf einen Wert ungleich Null zu setzen und die Anwendung neu zu starten.

Um das Verhalten des vom Backend verwendeten EGLStream-Objekts zu konfigurieren, verwenden Sie die Umgebungsvariable QT_QPA_EGLFS_STREAM_FIFO_LENGTH. Dies setzt voraus, dass KHR_stream_fifo von dem Zielsystem unterstützt wird. Standardmäßig arbeitet der Stream im Mailbox-Modus. Um in den FIFO-Modus zu wechseln, setzen Sie einen Wert von 1 oder höher. Der Wert gibt die maximale Anzahl von Frames an, die der Stream aufnehmen kann.

Auf einigen Systemen kann es erforderlich sein, eine bestimmte Overlay-Ebene über einen vordefinierten Anschluss anzusteuern. Das bloße Erzwingen eines Ebenenindexes über QT_QPA_EGLFS_LAYER_INDEX führt keine Ebenenkonfiguration durch und ist daher an sich nicht geeignet. Verwenden Sie in solchen speziellen Szenarien stattdessen die Umgebungsvariablen QT_QPA_EGLFS_KMS_CONNECTOR_INDEX und QT_QPA_EGLFS_KMS_PLANE_INDEX. Wenn diese gesetzt sind, wird nur der angegebene Verbinder und die Ebene verwendet, alle anderen Ausgaben werden ignoriert. Das Backend kümmert sich um die Auswahl der EGL-Ebene, die der gewünschten Ebene entspricht, und um die Konfiguration der Ebene.

Toucheingabe in Systemen mit mehreren Bildschirmen auf KMS/DRM

Touchscreens erfordern zusätzliche Überlegungen in Systemen mit mehreren Bildschirmen, da Berührungsereignisse an den richtigen virtuellen Bildschirm weitergeleitet werden müssen, und dies erfordert eine korrekte Zuordnung zwischen Touchscreens und Bildschirmausgaben.

Die Zuordnung erfolgt über die JSON-Konfigurationsdatei, die unter QT_QPA_EGLFS_KMS_CONFIG angegeben und in den vorherigen Abschnitten beschrieben wurde. Wenn eine touchDevice -Eigenschaft in einem Element des outputs -Arrays vorhanden ist, wird der Wert als Geräteknoten behandelt und das Touch-Gerät mit der betreffenden Bildschirmausgabe verknüpft.

Angenommen, unser Touchscreen hat den Geräteknoten /dev/input/event5 und ist ein Touchscreen, der in den Monitor integriert ist, der über HDMI als sekundärer Bildschirm angeschlossen ist, dann gewährleistet die folgende Konfiguration die korrekte Übersetzung von Berührungsereignissen (und synthetischen Mausereignissen):

 {
    "device": "drm-nvdc",
    "outputs": [
      {
        "name": "HDMI1",
        "touchDevice": "/dev/input/event5",
        "virtualIndex": 1
      },
      {
        "name": "DP1",
        "virtualIndex": 0
      }
    ]
}

Hinweis: Aktivieren Sie im Zweifelsfall die Protokollierung sowohl des Grafik- als auch des Eingabe-Subsystems, indem Sie die Umgebungsvariable QT_LOGGING_RULES=qt.qpa.*=true setzen, bevor Sie die Anwendung starten. Dies hilft bei der Identifizierung der korrekten Eingabegeräteknoten und kann Probleme bei der Ausgabekonfiguration aufdecken, die sonst nur schwer zu beheben sind.

Hinweis: Ab Qt 5.14 wird dies nur noch für die Backends evdevtouch und libinput unterstützt. Andere Varianten leiten Ereignisse weiterhin an den primären Bildschirm weiter. Um die Verwendung von evdevtouch auf Systemen zu erzwingen, auf denen mehrere Eingabe-Backends verfügbar sind, setzen Sie die Umgebungsvariable QT_QPA_EGLFS_NO_LIBINPUT auf 1.

EGLFS mit anderen Backends

Andere Backends, die typischerweise auf der direkten Ansteuerung des Framebuffers oder einer Composition-API über die EGL-Implementierung des Herstellers basieren, bieten in der Regel nur begrenzte oder gar keine Unterstützung für mehrere Displays. Auf i.MX6-basierten Boards mit Vivante-GPUs kann die Umgebungsvariable QT_QPA_EGLFS_FB verwendet werden, um den Framebuffer zu spezifizieren, ähnlich wie bei linuxfb. Auf dem Raspberry Pi kann die Umgebungsvariable QT_QPA_EGLFS_DISPMANX_ID verwendet werden, um den Bildschirm anzugeben, auf dem die Ausgabe erfolgen soll. Der Wert entspricht einer der DISPMANX_ID_ Konstanten, siehe die Dispmanx Dokumentation. Beachten Sie, dass diese Ansätze, im Gegensatz zu KMS/DRM, in der Regel keine Ausgabe auf mehrere Bildschirme aus derselben Anwendung erlauben. Alternativ können auch treiberspezifische Umgebungsvariablen oder Kernel-Parameter zur Steuerung des verwendeten Framebuffers zur Verfügung stehen. Lesen Sie dazu die Dokumentation des Embedded Boards.

Videospeicher

Bei Systemen mit einer festen Menge an dediziertem Videospeicher ist möglicherweise besondere Vorsicht geboten, bevor Qt-Anwendungen ausgeführt werden, die auf Qt Quick oder Klassen wie QOpenGLWidget basieren. Die Standardeinstellung kann für solche Anwendungen unzureichend sein, insbesondere wenn sie auf einem hochauflösenden Bildschirm (z. B. Full HD) angezeigt werden. In diesem Fall können sie auf unerwartete Weise versagen. Es wird empfohlen, sicherzustellen, dass mindestens 128 MB GPU-Speicher verfügbar sind. Bei Systemen, die keinen festen Speicherplatz für die GPU reserviert haben, stellt dies kein Problem dar.

linuxfb

Verwenden Sie den fb Plugin-Parameter, um das zu verwendende Framebuffer-Gerät anzugeben.

Unix-Signal-Handler

Die konsolenorientierten Plattform-Plugins wie eglfs und linuxfb installieren standardmäßig Signal-Handler, um Interrupt (SIGINT), Suspend und Continue (SIGTSTP, SIGCONT) und Terminierung (SIGTERM) zu erfassen. Auf diese Weise können die Tastatur, der Terminalcursor und möglicherweise andere grafische Zustände wiederhergestellt werden, wenn die Anwendung aufgrund von kill, Ctrl+C oder Ctrl+Z beendet oder angehalten wird (obwohl das Beenden oder Anhalten über die Tastatur nur möglich ist, wenn QT_QPA_ENABLE_TERMINAL_KEYBOARD gesetzt ist, wie oben im Abschnitt Eingabe beschrieben). In einigen Fällen kann das Erfassen von SIGINT jedoch unerwünscht sein, da es z.B. mit dem Remote-Debugging in Konflikt geraten kann. Aus diesem Grund gibt es die Umgebungsvariable QT_QPA_NO_SIGNAL_HANDLER, mit der alle eingebauten Signalverarbeitungen ausgeschaltet werden können.

Schriftarten

Qt verwendet normalerweise fontconfig, um den Zugriff auf Systemschriftarten zu ermöglichen. Wenn fontconfig nicht verfügbar ist, greift Qt auf QBasicFontDatabase zurück. In diesem Fall suchen Qt-Anwendungen nach Schriftarten im lib/fonts Verzeichnis von Qt. Qt erkennt automatisch vorgerenderte Schriftarten und TrueType-Schriftarten. Dieses Verzeichnis kann durch Setzen der Umgebungsvariablen QT_QPA_FONTDIR überschrieben werden.

Weitere Informationen zu den unterstützten Formaten finden Sie unter Qt for Embedded Linux Fonts.

Hinweis: Qt liefert keine Schriftarten mehr im Verzeichnis lib/fonts aus. Dies bedeutet, dass es an der Plattform (dem System-Image) liegt, die notwendigen Schriftarten bereitzustellen.

Plattform-Plugins für Windowing-Systeme auf eingebetteten Linux-Geräten

XCB

Dies ist das X11-Plugin, das auf normalen Desktop-Linux-Plattformen verwendet wird. In einigen Embedded-Umgebungen, die X und die notwendigen Entwicklungsdateien für xcb bereitstellen, funktioniert dieses Plugin genauso wie auf einem normalen PC-Desktop.

Hinweis: Auf einigen Geräten gibt es keine EGL- und OpenGL-Unterstützung unter X, da die EGL-Implementierung nicht mit Xlib kompatibel ist. In diesem Fall ist das XCB-Plugin ohne EGL-Unterstützung gebaut, was bedeutet, dass Qt Quick 2 oder andere OpenGL-basierte Anwendungen nicht mit diesem Plattform-Plugin funktionieren. Es kann jedoch immer noch verwendet werden, um software-gerenderte Anwendungen (z.B. auf Basis von QWidget ) auszuführen.

Im Allgemeinen ist die Verwendung von XCB auf eingebetteten Geräten nicht ratsam. Plugins wie eglfs bieten wahrscheinlich eine bessere Leistung und Hardware-Beschleunigung.

Wayland

Wayland ist ein leichtgewichtiges Fenstersystem; genauer gesagt ist es ein Protokoll für Clients, um mit einem Display-Server zu kommunizieren.

Qt Wayland bietet ein wayland Plattform-Plugin, das es Qt-Anwendungen ermöglicht, sich mit einem Wayland Compositor zu verbinden.

Für weitere Details siehe Wayland und Qt.

Richtlinien zur Leistungsverbesserung

Verwenden Sie Hardware-Rendering wo immer möglich

Wenn die Leistung für Ihre Anwendung entscheidend ist, vermeiden Sie die Verwendung von Qt-Modulen, die auf Software-Rendering angewiesen sind, wie z.B. Qt Charts. Bevorzugen Sie stattdessen, wenn möglich, Module, die auf Hardware-Rendering basieren.

Befolgen Sie die Best Practices für Qt Quick

Befolgen Sie die Best Practices für QML und Qt Quick, insbesondere im Hinblick auf die Einbindung der QML CMake API, so dass qmllint, der QML Script Compiler (qmlsc) und der QML Type Compiler (qmltc) verfügbar sind. Darüber hinaus ist es besser, deklaratives QML zu schreiben und Javascript zu minimieren. Weitere Informationen darüber, wie sich die Verwendung von übermäßigem JavaScript auf die Leistung auswirken kann, finden Sie unter QML Performance Considerations And Suggestions.

Verwenden Sie Bilder/Texturen und Shader-Effekte anstelle des QML-Typs Canvas

Verwenden Sie zum Zeichnen benutzerdefinierter UI-Elemente Bilder/Texturen und Shader-Effekte. Verwenden Sie nicht den Typ QML Canvas. Shader erfordern Hardware-Beschleunigung (GPU).

Verwenden Sie Qt Quick statt Qt Widgets

Mit Qt Quick ist es möglich, entweder hardwarebeschleunigte oder softwaregerenderte Backends zu verwenden. Für komplexe Uls wird die Verwendung von Qt Widgets auf eingebetteten Zielen nicht empfohlen, da immer ein Software-Backend verwendet wird.

Hier gibt es Kompromisse:

  • Die Verwendung der QML-Engine und von Qt Quick ist mit anfänglichem Overhead verbunden.
  • Wenn Ihre Benutzeroberfläche sehr einfach ist und sich nur selten ändert, kann sie schneller funktionieren, wenn sie mit Widgets statt mit QML implementiert wird.
  • Wenn Ihre Benutzeroberfläche von Animationen, smooth scrolling und scaling, rendering effects oder 3D profitiert, benötigen Sie GPU-Beschleunigung und somit Qt Quick.

Wählen Sie eine für die Größe Ihrer Benutzeroberfläche geeignete Auflösung

Bei höheren Auflösungen müssen Sie vorsichtig sein. Auflösungen von 720p und höher können die Leistung verringern.

Verwenden Sie einen QML-Fenstertyp als Root-Element für Ihre Anwendung

Verwenden Sie ein Window als Root-Element Ihrer Anwendung mit dem Hintergrund der Anwendung color.

Der Grund dafür ist, dass eine Fensterkomponente eine Farbeigenschaft hat, die den Effekt eines leeren Puffers hat. Das Rendern des Hintergrunds mit einem bildschirmfüllenden Rectangle als Root-Element einer Anwendung Item würde einen zusätzlichen Zeichenaufruf verursachen. Für einige RHI-Backends kann dies dasselbe sein, aber es gibt einen Unterschied zwischen einem glClear -Aufruf und dem Zeichnen eines Quad. In den meisten Fällen dürfte ein einzelnes, undurchsichtiges Bild keine großen Auswirkungen auf die Leistung haben, aber wenn Sie einen Alphawert in der Farbe dieses Elements verwenden, könnten Sie einen erheblichen Leistungseinfluss feststellen.

© 2025 The Qt Company Ltd. Documentation contributions included herein are the copyrights of their respective owners. The documentation provided herein is licensed under the terms of the GNU Free Documentation License version 1.3 as published by the Free Software Foundation. Qt and respective logos are trademarks of The Qt Company Ltd. in Finland and/or other countries worldwide. All other trademarks are property of their respective owners.