wiki:qt

Qt For Embedded Linux

See also:

Platform Plugins

On Embedded Linux systems there are multiple 'platform plugins' that can be used for backend display such as EGLFS, LinuxFB, DirectFB, or Wayland. The availability of these plugins depends on how Qt is configured. Note that as of Qt 5.0 Qt no longer has its own window system (QWS) implementation as for single-process use cases the Qt Platform Abstraction is a superior solution. If you need support for a multi-process compositing window manager use the Wayland platform plugin and run a Wayland server.

List platform plugins:

ls /usr/lib/arm-linux-gnueabihf/qt5/plugins/platforms

The platform plugin is specified in one of two ways:

  • running app with '-platform <platform>' cmdline options
  • defining QT_QPA_PLATFORM env variable

EGLFS

EGL is an interface between OpenGL and the native windowing system. EGLFS is a platform plugin for running Qt5 applications on top of EGL and OpenGL ES 2.0 without an actual windowing system like X11 or Wayland.

EGLFS is the default plugin on many boards and is recommended for Embedded Linux devices that include a GPU. You can use the QT_QPA_PLATFORM env variable or the -platform command-line argument to request another plugin.

EGLFS forces the first top-level window (either a QWidget or a QQuickView) to become full screen and chosen to be the root widget window into which all other top-level widgets are composited. There are a number of env variables that can be used to configure EGLFS: see https://doc.qt.io/qt-5/embedded-linux.html#eglfs

To use the EGLFS platform plugin with a KMS/DRM backend you need to define a screen configuration file customized to your board and display.

Examples:

  • 1080p HDMI:
    cat << EOF > /etc/eglfs_hdmi.json
    {
      "device": "/dev/dri/card1",
      "hwcursor": false,
      "pbuffers": true,
      "outputs": [
        {
          "name": "HDMI-A-1",
          "mode": "1920x1080"
        },
        {
          "name": "LVDS-1",
          "mode": "off"
        }
      ]
    }
    EOF
    export QT_QPA_EGLFS_KMS_CONFIG=/etc/eglfs_hdmi.json
    export QT_QPA_EGLFS_ALWAYS_SET_MODE=1
    export QT_QPA_PLATFORM=eglfs
    
  • 1024x600 LVDS:
    cat << EOF > /etc/eglfs_lvds.json
    {
      "device": "/dev/dri/card1",
      "hwcursor": false,
      "pbuffers": true,
      "outputs": [
        {
          "name": "HDMI-A-1",
          "mode": "off"
        },
        {
          "name": "LVDS-1",
          "mode": "1024x600"
        }
      ]
    }
    EOF
    export QT_QPA_EGLFS_KMS_CONFIG=/etc/eglfs_lvds.json
    export QT_QPA_EGLFS_ALWAYS_SET_MODE=1
    export QT_QPA_PLATFORM=eglfs
    

In order to use EGLFS you need to be using a kernel with the etnaviv KMS/DRM driver enabled, libdrm (userspace lib to interface with Linux DRM drivers), and libmesa. Note that the etnaviv driver uses cma memory - if you get memory allocation errors when trying to run applications try increasing the cma memory via the kernel command-line.

For more info see:

LinuxFB

LinuxFB writes directly to the framebuffer via Linux's fbdev subsystem where only software-rendered content is supported (no hw acceleration). Note that the fbdev subsystem is being deprecated in the Linux kernel and the DRM dub buffer support is to take its place and is supported in Qt 5.9. To use it set QT_QPA_FB_DRM=1. This provides a double-buffered and page flipped output providing proper vsync for software-rendered content. For env variables and options see https://doc.qt.io/qt-5/embedded-linux.html#linuxfb

export QT_QPA_PLATFORM=linuxfb

Qt Examples

QtWebEngine

QtWebEngine is essentially the Chromium core wrapped in Qt making it possible to render web content even without X11/Wayland and it works just fine with pure framebuffer.

A simple example using QtWebEngine can be found at https://code.qt.io/cgit/qt/qtwebengine.git/tree/examples/webengine/minimal

To build the simple example which creates a QtWebEngine fullscreen widget using content from http://www.qt.io:

  • Ubuntu Focal 20.04:
    apt update && apt upgrade # always a good idea to keep up to date
    # install basic development requirements
    apt install build-essential git
    # install qt5 development packages
    apt install qtwebengine5-dev
    # install qt5 runtime
    apt install qt5-default qml-module-qtwebengine
    # install qtwebengine minimal code example
    apt install qtwebengine5-examples
    cd /usr/lib/arm-linux-gnueabihf/qt5/examples/webengine/minimal
    # edit main.qml if you want to change the width/height or url
    qmake # generate Makefile from *.pro
    make # build
    ./minimal --no-sandbox
    

Qt5 Cinematic Experience

This UX demo application presents some graphical features of Qt5. The name 'Cinematic Experience' reflects how it's possible to build user interfaces with increased dynamics.

Examples:

  • Ubuntu Focal 20.04:
    apt update && apt upgrade # always a good idea to keep up to date
    # install basic development requirements
    apt install build-essential git
    # install qt5 runtime
    apt install qt5-default qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-particles2
    # install qt5 development packages
    apt install qtbase5-dev qtdeclarative5-dev
    git clone https://github.com/rzr/qt5-cinematic-experience
    cd qt5-cinematic-experience
    qmake
    make
    ./Qt5_CinematicExperience
    

Qt GL Video Demo

This UX demo application shows how to render video frames on 3D objects which in turn are integrated in a Q graphical features of Qt5. The name 'Cinematic Experience' reflects how it's possible to build user interfaces with increased dynamics.

The video frames are produced by the GStreamer GstPlayer library. They are uploaded into OpenGL textures, which are then used on 3D meshes. These meshes are rendered in QQuickFramebufferObject QtQuick 2 items, and the items are composed by a PathView on screen. The 3D objects can be rotated with the mouse or with touch events. UI controls allow for adjusting several parameters such as opacity, scale, mesh type, etc. and for adding/removing objects. The video frames can come from local video files, network streams, or Video4Linux2 based video capture devices.

Subtitles can be shown on screen. The subtitles can come either from the playing media itself, or from a FIFO if one is enabled in the configuration file.

Examples:

  • Ubuntu Focal 20.04:
    apt update && apt upgrade # always a good idea to keep up to date
    # install basic development requirements
    apt install build-essential git
    # install qt5 runtime and qml modules required
    apt install qt5-default qml-module-qtquick-controls qml-module-qtquick-controls2 qml-module-qtquick-dialogs qml-module-qt-labs-folderlistmodel qml-module-qt-labs-settings
    # install qt5 development packages
    apt install qtbase5-dev qtdeclarative5-dev qtquickcontrols2-5-dev
    # install Gstreamer development packages
    apt install libgstreamer1.0-dev libgstreamer-plugins-base1.0-dev libgstreamer-plugins-bad1.0-dev libudev-dev
    git clone https://github.com/dv1/qtglviddemo
    cd qtglviddemo
    qmake
    make
    ./qtglviddemo
    

See: https://github.com/dv1/qtglviddemo

Qt Fingerpaint Touchscreen Example

Qt has a fingerpaint example app demonstrating how to use touch input

Examples:

  • Ubuntu Focal 20.04:
    apt update && apt upgrade # always a good idea to keep up to date
    # install basic development requirements
    apt install build-essential git
    # install libevdev
    apt install libevdev2 libevdev-tools
    # install qt5 runtime and qml modules required
    apt install qt5-default
    git clone git://code.qt.io/qt/qtbase.git -b 5.12
    cp -r qtbase/examples/widgets/touch/fingerpaint .
    cd fingerpaint/
    qmake
    make
    # run using linuxfb backend
    ./fingerpaint -platform linuxfb
    

Qt's input systems:

Qt can use Linux evdev directly for input or it can use helper libraries such as libinput or tslib:

  • By default Qt5 on Ubuntu is using libinput and there is no tslib support
  • To troublshoot input you can set 'QT_LOGGING_RULES=qt.qpa.input=true'.
  • If you wish to disable libinput you can set 'QT_QPA_EGLFS_NO_LIBINPUT=1' for eglfs backend or 'QT_QPA_FB_NO_LIBINPUT=1' for linuxfb backend and input will default to evdev.

evdev:

When using evdev you can parameters via QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS with colon separated parameters, for example:

  • Run fingerpaint using evdev and linuxfb backend and specify /dev/input/event1 for input, rotate input 90 degrees, and invert both x and y:
    QT_LOGGING_RULES=qt.qpa.input=true QT_QPA_FB_NO_LIBINPUT=1 QT_QPA_EVDEV_TOUCHSCREEN_PARAMETERS=/dev/input/event1:rotate=90:invertx:inverty ./fingerpaint -platform linuxfb
    

For more details Qt Input see:

User Interface Design with QT

It is often best to consider QML instead of HTML5 for UI design. QML is much easier to use than HTML5 and is typically just fine for most user interface designs. QML has been designed for compsiting UIs and screen elements from the start while HTML5 had these things added to an existing standard meant for text rendering.

Last modified 4 days ago Last modified on 10/13/2021 08:54:07 PM