自从Qt 5.0发布以来,Qt不再包含自己的窗口系统(QWS)实现。对于单进程用例,Qt平台抽象是一个优秀的解决方案。Wayland可以支持多种图形化流程。

有多个平台插件可能在嵌入式Linux系统上可用:EGLFS,LinuxFB,DirectFB,Wayland。这些可用性取决于Qt的配置。在许多板上选择eglfs作为默认选项。如果默认值不合适,QT\_QPA\_PLATFORM则可以使用环境变量参数来请求另一个插件。或者,对于快速测试,-platform命令行可以使用相同的语法。

配置特定设备

对于给定的设备构建Qt需要一个工具链和一个sysroot。另外,一些设备需要针对EGL和OpenGLES 2.0支持的供应商特定的适配代码。这与非加速平台无关,例如使用LinuxFB插件的平台,仅用于基于软件的渲染。


目录qtbase/ mkspecs / devices包含许多设备的配置和图形适配代码。例如,linux-rasp-pi2-g++mkspec包含构建设置,如Raspberry Pi 2设备的最佳编译器和链接器标志。mkspec还包含有关eglfs钩子的实现(供应商特定的适配代码)的信息,或者是对适合的eglfs设备集成插件的引用。通过配置工具的-device参数选择设备。在此参数之后的名称必须至少部分地匹配设备下的一个子目录。

以下是Raspberry Pi 2的示例配置。对于大多数嵌入式Linux板,configure命令看起来类似:

./configure -release -opengl es2 -devicelinux-rasp-pi2-g ++ -device-option CROSS\_COMPILE = $ TOOLCHAIN / arm-bcm2708 /gcc-linaro-arm-linux-gnueabihf-raspbian / bin / arm-linux-gnueabihf- -sysroot $ROOTFS -prefix / usr / local / qt5

最重要的参数是-device和-sysroot。通过指定-sysroot,configure特征检测测试使用的包含文件和库以及Qt本身,取自指定的位置,而不是主机PC的标准位置。这意味着在主机上安装开发包是无关紧要的。例如,要获得libinput支持libinput,在主机环境中安装开发头和库是不够的。相反,目标架构(例如ARM)的标头和库必须存在于sysroot。

pkg-config在执行交叉编译时也得到支持。configure自动设置PKG\_CONFIG\_LIBDIR为pkg-config基于sysroot代替主机的报告编译器和链接器设置。这通常功能很好,没有任何进一步的调整。但是,PKG\_CONFIG\_PATH运行前,主机必须先设置环境变量configure。否则,Qt构建可能会尝试从主机系统使用不适当的头文件和库。

指定-sysroot在--sysroot调用编译器时自动设置参数的结果。在某些情况下,这是不可取的,可以通过传递-no-gcc-sysroot来禁用configure。

-prefix,-extprefix并-hostprefix控制Qt构建的目标目标目录。在上述示例中,Qt的ARM版本预计将放置在/usr/local/qt5目标设备上。请注意,运行make install不会部署任何设备。相反,该install步骤将目标指定的目录extprefix默认为sysroot+ prefix,因此是可选的。然而,在很多情况下,“污染”是不可取的,因此指定-extprefix变得重要。最后,-hostprefix允许从目标的二进制文件分离主机工具,如qmake,rcc,uic。给定时,这些工具将安装在指定的目录下,而不是extprefix。

有关详细信息,请参阅Qt配置选项。

嵌入式Linux设备的平台插件

EGLFS

EGL是OpenGL和本机窗口系统之间的接口。Qt可以使用EGL进行上下文和表面管理,但是API不包含平台特定的内容:创建本机窗口(这不一定是屏幕上的实际窗口)仍然必须通过平台特定的方式完成。因此需要板或GPU特定的适配代码。这样的修改可以被提供为eglfs钩子,其可以是编译到平台插件中的单个源文件,或作为动态加载的EGL设备集成插件。

EGLFS是一个平台插件,用于在没有实际的窗口系统(如X11或Wayland)的EGL和OpenGLES 2.0之上运行Qt5应用程序。除了QtQuick 2和本机OpenGL应用程序,它还支持软件渲染的窗口(例如QWidget)。在后一种情况下,小部件的内容将使用CPU渲染成图像,然后将其上传到纹理并由插件合成。

这是包含GPU的现代嵌入式Linux设备的推荐插件。

EGLFS强制第一个顶级窗口(无论是QWidget还是QQuickView)成为全屏幕。此窗口也被选择为根部件窗口窗口,其中所有其他顶级窗口小部件(例如对话框,弹出菜单或组合框下拉列表)都被合成。这是必要的,因为使用EGLFS总是有一个本机窗口和EGL窗口表面,这些窗口属于首先创建的窗口小部件或窗口。当主窗口在整个应用程序的整个生命周期中存在,并且所有其他窗口小部件都是非顶层或之后创建的主窗口显示时,此方法运行良好。

对于基于OpenGL的窗口还有其他限制。从Qt 5.3起,eglfs支持一个全屏GL窗口(例如,基于OpenGL的QWindow,QQuickView或QGLWidget)。打开额外的OpenGL窗口或混合这些窗口与基于QWidget的内容是不支持的并终止应用程序与错误消息。

如有必要,eglfs可以使用以下环境变量进行配置:

· QT\_QPA\_EGLFS\_INTEGRATION-除了编译的钩子之外,还可以以动态加载的插件的形式提供设备或供应商特定的适配。这个环境变量强制执行一个特定的插件。例如,将其设置为eglfs\_kms使用KMS/ DRM后端。这只是在设备makepecs中没有指定静态或编入钩子的选项。在实践中,传统的编入钩子很少被使用,几乎所有后端都被迁移到插件。设备制造商仍然包含相关EGLFS\_DEVICE\_INTEGRATION条目:该特定设备的首选后端的名称。这是可选的,但是非常有用,以避免在目标系统中存在多个插件的情况下设置此环境变量。DISPLAY在桌面环境中,根据环境变量的存在,KMS或X11后端是优先的。请注意,在某些电路板上使用特殊的值none而不是实际的插件。这表明使用EGL与framebuffer不需要特殊的集成,所以不能加载插件。

· QT\_QPA\_EGLFS\_PHYSICAL\_WIDTH和QT\_QPA\_EGLFS\_PHYSICAL\_HEIGHT-物理屏幕宽度和高度以毫米为单位。在不能从帧缓冲设备/ dev / fb0或其他方式查询值的平台上,使用默认DPI为100。此变量可用于覆盖任何此类默认值。设置此选项很重要,因为基于QWidget或QtQuick Controls的应用程序依赖于这些值。使用硬编码设置运行可能会导致用户界面元素大小不适合在使用中显示。

· QT\_QPA\_EGLFS\_ROTATION-指定在基于QWidget的应用程序中应用于软件渲染内容的旋转。支持的值为180,90和-90。这不适用于基于OpenGL的窗口,包括QtQuick。QtQuick应用程序可以在QML场景中应用转换。无论应用程序类型如何,标准的eglfs鼠标光标总是考虑到该值,具有适当定位和旋转的指针图像。特殊光标实现(如KMS/ DRM后端的硬件光标)可能不支持旋转。

· QT\_QPA\_EGLFS\_FORCEVSYNC-设置后,每次调用eglSwapBuffers()后,帧缓冲设备上的eglfs请求FBIO\_WAITFORVSYNC。这仅适用于依赖于fbdevLinux 的传统子系统的后端。通常,默认交换间隔为1,Qt假定调用eglSwapBuffers()处理vsync; 如果没有(例如,由于驱动程序错误),请尝试设置QT\_QPA\_EGLFS\_FORCEVSYNC为非零值。

· QT\_QPA\_EGLFS\_FORCE888 -设置时,在创建新的上下文,窗口或屏幕外表面时,将忽略红色,绿色和蓝色颜色通道大小。相反,插件要求每个通道8位配置。这对于在默认情况下选择具有小于32或24位/像素(例如5-6-5或4-4-4)的配置的设备可能是有用的,但是已知不是理想的,例如,由于绑带效应。而不是更改应用程序代码,此变量提供了一个更容易的快捷方式来强制24或32 bpp配置。

此外,以下 - 较不常用的变量也可用:

· QT\_QPA\_EGLFS\_FB -覆盖帧缓冲设备。默认是/dev/fb0。在大多数嵌入式平台上,这不是很相关,因为帧缓冲区仅用于查询显示维度等设置。然而,在某些设备上,该参数提供了指定要在多个显示设置中使用的显示的功能,类似于LinuxFB中的fb参数。

· QT\_QPA\_EGLFS\_WIDTH和QT\_QPA\_EGLFS\_HEIGHT-包含屏幕宽度和高度(以像素为单位)。在eglfs尝试从framebuffer设备/ dev / fb0中确定尺寸时,但是这并不总是和手动指定大小可能变得必要。

· QT\_QPA\_EGLFS\_DEPTH -覆盖屏幕的颜色深度。在framebuffer设备/ dev / fb0不可用或查询不成功的平台上,使用默认值32。此变量可用于覆盖任何此类默认值。请注意,这仅影响QScreen报告的颜色深度值。它与EGL配置和OpenGL渲染使用的颜色深度无关。

· QT\_QPA\_EGLFS\_SWAPINTERVAL-默认情况下1将要求交换间隔。这使得能够与显示器垂直刷新同步。该值可以用此环境变量覆盖。例如,传递0将禁用交换阻塞,导致尽可能快地运行而没有任何同步。

· QT\_QPA\_EGLFS\_DEBUG -设置时,调试输出上会打印一些调试信息。例如,输入的QSurfaceFormat和所选EGL配置的属性在创建新上下文时打印。与QtQuick的QSG\_INFO变量一起,可以为与EGL配置相关的故障排除提供有用的信息。

除此之外QT\_QPA\_EGLFS\_DEBUG,eglfs还支持更现代的Qt分类日志记录系统。以下日志记录类别可用:

· qt.qpa.egldeviceintegration -为动态加载的后端启用日志记录。非常有用的检查后端是否正在使用。

· qt.qpa.input-启用来自evdev和libinput输入处理程序的调试输出。检查给定输入设备是否被识别和打开非常有用。

· qt.qpa.eglfs.kms -在KMS/ DRM后端启用详细日志记录。

运行后configure,确保检查其输出。由于相应的配置测试失败,没有启用必要的eglfs后端,libudev或libinput是相当常见的问题,可以通过这种方式快速识别。当有不想要的“不”的结果,运行configure与-v才能看到编译器和链接调用每个配置测试打开详细输出。

注意:关于缺少标题,库或似乎隐含的链接器故障的错误通常是不完整或破碎的sysroot的标志,与Qt无关,也不能被Qt解决。

例如,当使用Broadcom专有图形驱动程序定位RaspberryPi时,输出应包含以下内容。如果不是这样,没有必要进一步进行构建,因为如果没有RaspberryPi特定的后端,加速图形将不起作用,即使Qt的其余部分成功编译。

QPA后端:

EGLFS ................................是的

EGLFS详细信息:

EGLFS i.Mx6........................ no

EGLFS i.Mx6 Wayland................ no

EGLFS EGLDevice.................... no

EGLFS GBM.......................... no

EGLFS马里.........................

EGLFS Rasberry Pi..................是的

XL上的EGL.........................

该插件通过Linux的fbdev子系统直接写入帧缓冲区。只支持软件渲染内容。请注意,在某些设置上,显示性能预计将受到限制。

从Qt 5.9开始,由于fbdev在Linux内核中被弃用,DRMdumb缓冲区支持也是可用的。必须通过将QT\_QPA\_FB\_DRM环境变量设置为非零值来请求。当设置时,只要系统支持哑缓冲区,传统的帧缓冲设备/dev/fb0就不会被访问。相反,通过DRMAPI设置渲染,类似于eglfs\_kmseglfs 的后端。输出将被双缓冲和页面翻转,为软件渲染内容提供适当的vsync。

注意:当使用哑缓冲区时,以下所述的任何选项都不适用,因为物理和逻辑屏幕尺寸等属性都将被自动查询。

该linuxfb插件允许通过将它们传递给QT\_QPA\_PLATFORM环境变量或-platform命令行选项来指定其他设置。例如,QT\_QPA\_PLATFORM=linuxfb:fb=/dev/fb1指定/dev/fb1必须使用帧缓冲设备而不是默认值fb0。可以通过用冒号分隔多个设置来指定多个设置。

· fb=/dev/fbN -指定帧缓冲设备。在多个显示设置上,这通常允许在不同显示器上运行应用程序。暂时没有办法从一个Qt应用程序使用多个帧缓冲区。

· size= x -指定屏幕大小(以像素为单位)。插件尝试从framebuffer设备查询物理和逻辑的显示维度。然而,这可能并不总是导致正确的结果,因此可能需要明确指定值。

· mmsize= x -物理宽度和高度(以毫米为单位)。

· offset= x -指定屏幕左上角的像素偏移量。默认位置在(0, 0)。

· nographicsmodeswitch-不要将虚拟终端切换到图形模式(KD\_GRAPHICS)。除了切换到图形模式外,闪烁的光标和屏幕消隐也通常被禁用。设置此参数时,也会跳过这些参数。

· tty=/dev/ttyN -覆盖虚拟控制台。仅在nographicsmodeswitch未设置时使用。

从Qt 5.9起,在窗口大小调整策略中,eglfs和linuxfb的行为已被同步:第一个顶级窗口被迫使用两个平台插件覆盖整个屏幕。如果不想这样,环境变量设置QT\_QPA\_FB\_FORCE\_FULLSCREEN到0以恢复早期的Qt版本的行为。

输入

当没有窗口系统存在时,鼠标,键盘,以及触摸输入是通过直接读取evdev或使用辅助库如libinput或tslib。请注意,这要求/dev/input/event*用户可以读取设备节点。eglfs并linuxfb具有编译的所有输入处理代码。

使用libinput

libinput是一个用于处理输入设备的库。它提供了Qt自己的evdev输入支持的替代方案。为了能够使用libinput,请确保所开发的文件libudev和libinput配置和构建Qt时可用。xkbcommon如果需要键盘支持,也是必需的。由于这些插件默认使用eglfs,因此linuxfb无需进一步的操作libinput。如果libinput支持不可用或环境变量QT\_QPA\_EGLFS\_NO\_LIBINPUT设置,Qt自己的evdev处理程序进来玩。

输入eglfs和linuxfb而不用libinput

像设备节点名称参数可以在环境变量设置QT\_QPA\_EVDEV\_MOUSE\_PARAMETERS,QT\_QPA\_EVDEV\_KEYBOARD\_PARAMETERS和QT\_QPA\_EVDEV\_TOUCHSCREEN\_PARAMETERS。用冒号分隔条目。这些参数作为传递-plugin命令行参数中的设置的替代方法,并且对于某些后端,它们是至关重要的:eglfs和linuxfb使用内置的输入处理程序,因此-plugin在使用中没有单独的参数。

此外,内置的输入处理程序可以通过设置被禁用QT\_QPA\_EGLFS\_DISABLE\_INPUT或QT\_QPA\_FB\_DISABLE\_INPUT到1。

老鼠

鼠标光标每当出现QT\_QPA\_EGLFS\_HIDECURSOR(对于eglfs)或QT\_QPA\_FB\_HIDECURSOR(对于linuxfb)未设置,Qt的基于libudev的设备发现报告至少有一个鼠标可用。当libudev不存在支持时,鼠标光标始终显示,除非通过环境变量显式禁用。

支持热插拔,但只有当Qt配置了libudev支持(即,如果libudev开发头在配置时在sysroot中存在)。这允许在应用程序运行时连接或断开输入设备。

该了evdev鼠标处理器支持以下额外的参数:

· /dev/input/... -指定输入设备的名称。当没有给出时,Qt通过libudev或通过可用节点来查找合适的设备。

· nocompress -默认情况下,与最后一个Qt鼠标事件相比,不会导致更改位置的输入事件被压缩; 在更改位置或按钮状态后,才会发送新的Qt鼠标事件。可以通过设置nocompress参数来禁用。

· dejitter -指定抖动限制。默认情况下禁用消隐功能。

· grab -当1,Qt将抓住设备专用。

· abs -一些触摸屏报告绝对坐标,不能与触摸板区分开来。在这种特殊情况下,通过abs表示设备正在使用绝对事件。

键盘

该了evdev键盘处理程序支持以下额外的参数:

· /dev/input/... -指定输入设备的名称。当没有给出时,Qt通过libudev或通过可用节点来查找合适的设备。

· grab -启用抓取输入设备。

· keymap -指定自定义键盘映射文件的名称。

· enable-compose -启用合成。

· repeat-delay -设置自定义键重复延迟。

· repeat-rate -设置自定义键重复率。

在没有停用终端会话的嵌入式Linux系统上,由于输入事件由Qt应用程序和tty处理,按键上的行为可能会令人困惑。为了克服这一点,可以使用以下选项:

· EGLFS和LinuxFB尝试通过设置tty的键盘模式来禁用应用程序启动时的终端键盘K\_OFF。这样可以防止键盘进入终端。如果由于某些原因需要恢复标准行为,请将环境变量设置QT\_QPA\_ENABLE\_TERMINAL\_KEYBOARD为1。请注意,仅当应用程序从远程控制台(例如,通过ssh)启动并且终端键盘输入保持启用时,该功能才起作用。

· 另一种方法是使用了evdev键盘处理程序的grab通过传递参数抢= 1在QT\_QPA\_EVDEV\_KEYBOARD\_PARAMETERS。这样会导致尝试在输入设备上进行抓取。如果grab成功,只要Qt应用程序运行,系统中没有其他组件从中接收事件。这种方法更适合远程启动的应用程序,因为它不需要访问tty设备。

· 最后,对于许多专门的嵌入式Linux图像,首先启用标准终端会话是没有意义的。请参阅您的构建环境的文档,了解如何禁用它们。例如,当使用Yocto Project生成图像时,取消设置将SYSVINIT\_ENABLED\_GETTYS导致getty任何虚拟终端无任何进程运行,从而导致无输入。

如果默认内置键盘映射不够,可以通过keymap参数或使用eglfs特定的loadKeymap()函数指定不同的键盘映射。后者允许在运行时切换键盘映射。但是请注意,这需要使用eglfs的内置键盘处理程序; 当通过-plugin命令行参数加载键盘处理程序时,不支持它。

注意:目前不支持特殊的系统组合键,例如控制台切换(Ctrl + Alt + Fx)或zap(Ctrl + Alt + Backspace),并被忽略。

要生成自定义键盘映射,可以使用kmap2qmap实用程序。这可以在qttools模块中找到。源文件必须是标准的Linux kmap格式,这是内核的loadkeys命令所理解的。这意味着可以使用以下源生成qmap文件:

· 在Linux控制台工具(LCT)项目。

· Xorg X11键盘映射可以转换kmap为该ckbcomp实用程序的格式。

· 由于kmap文件是纯文本文件,它们也可以手工制作。

kmap2qmap是一个命令行程序,至少需要2个文件作为参数。最后一个是生成的.qmap文件,而其他所有文件都被解析为输入.kmap文件。例如:

kmap2qmap i386 / qwertz /de-latin1-nodeadkeys.kmap include / compose.latin1.inc de-latin1-nodeadkeys.qmap

注意:kmap2qmap不支持Linux内核支持的所有(伪)符号。转换标准键盘图时,会显示许多警告,关于Show\_Registers,Hex\_A等等; 这些消息可以安全地被忽略。

触摸

对于一些电阻式单触摸触摸屏,可能需要退回使用,tslib而不是依赖于Linux多点触控协议和事件设备。对于现代触摸屏,这是不必要的。tslib可以通过设置环境变量QT\_QPA\_EGLFS\_TSLIB或QT\_QPA\_FB\_TSLIB1 来启用支持。要更改设备,请TSLIB\_TSDEVICE在命令行中设置环境变量或传递设备名称。请注意,tslib输入处理程序生成鼠标事件并支持单触摸,而不是evdevtouch生成真正的多点触控QTouchEvent事件。

该了evdev触摸处理器支持以下额外的参数:

· /dev/input/... -指定输入设备的名称。当没有给出时,Qt通过libudev或通过可用节点来查找合适的设备。

· rotate-在某些触摸屏上,坐标必须旋转,这可以通过设置rotate为90,180或270进行。

· invertx和inverty- 反转输入事件中的X或Y坐标,通过invertx或inverty。

例如,exportQT\_QPA\_EVDEV\_TOUCHSCREEN\_PARAMETERS=/dev/input/event5:rotate=180在启动应用程序之前,会导致明确指定的触摸设备并翻转坐标- 当实际屏幕和触摸屏的方向不匹配时很有用。

笔式平板电脑

该evdevtablet插件为Wacom和类似的基于笔的平板​​电脑提供了基本的支持。它仅生成QTabletEvent事件。要启用它,请传递QT\_QPA\_GENERIC\_PLUGINS=evdevtablet给环境,或者-plugin evdevtablet在命令行中传递参数。插件可以使用设备节点参数,例如QT\_QPA\_GENERIC\_PLUGINS=evdevtablet:/dev/event1,Qt的自动设备发现(基于libudev或演练/dev/input/event*)不起作用或行为不正常的情况。

调试输入设备

通过启用qt.qpa.input日志规则,例如通过将QT\_LOGGING\_RULES环境变量设置为,可以向调试输出打印一些信息qt.qpa.input=true。这对于检测正在使用哪个设备或对设备发现问题进行故障排除非常有用。

使用自定义鼠标光标图像

eglfs自带的32x32尺寸的鼠标光标图像。如果这些还不够,可以通过将QT\_QPA\_EGLFS\_CURSOR环境变量设置为JSON文件的名称来提供自定义游标地图集。该文件也可以通过Qt的资源系统嵌入到应用程序中。

例如,每行具有8个光标图像的嵌入式光标图集可以指定如下:

{

“image”:“:/cursor-atlas.png”

“cursorsPerRow”:8,

“热点”:[

[7,2]

[12,3]

[12,12]

...

]

}

请注意,图像预计将紧紧地包装在图集中:光标的宽度和高度根据总图像大小和cursorsPerRow设置决定。地图集必须为所有支持的游标提供图像。

显示输出

当连接多个显示器时,从一个单一Qt应用程序中定向一个或多个显示器的支持级别在平台插件之间变化,并且通常取决于设备及其图形堆栈。

eglfs与eglfs\_kms后端

当KMS / DRM后台正在使用时,eglfs报告QGuiApplication :: screens()中的所有可用屏幕。应用程序可以使用不同的窗口通过QWindow :: setScreen()来定位不同的屏幕。

注意:每个屏幕的一个全屏窗口的限制仍然适用。使QWindow可见后更改屏幕也不受支持。因此,嵌入式应用程序必须在调用QWindow :: show()之前进行所有必要的QWindow :: setScreen()调用。

当开始在给定的嵌入式设备上开发时,通常需要验证设备和驱动程序的行为,并且所连接的显示器应该是正常工作的。一个简单的方法是使用hellowindow示例。用-platform eglfs--multiscreen --timeout参数启动它在每个连接的屏幕上显示一个旋转的Qt标志几秒钟。

注意:下面描述的大多数配置选项适用于所有基于KMS/ DRM的后端,无论缓冲管理技术(GBM或EGLStreams)如何。

KMS / DRM后端还支持通过JSON文件进行自定义配置。将环境变量设置为QT\_QPA\_EGLFS\_KMS\_CONFIG文件的名称以启用此功能。该文件也可以通过Qt资源系统嵌入到应用程序中。示例配置如下:

{

“device”:“/dev / dri / card1”,

“hwcursor”:false,

“pbuffers”:真的,

“输出”:[

{

“name”:“VGA1”,

“关闭模式”

},

{

“name”:“HDMI1”,

“mode”:“1024x768”

}

]

}

这里我们配置指定的设备

· 它不会使用硬件光标(通过OpenGL退回渲染鼠标光标;默认情况下,启用硬件光标,因为它们更有效),

· 它将使用标准的EGLpbuffer表面返回QOffscreenSurface(默认情况下,这是禁用的,而是使用gbm表面),

· VGA连接器上的输出被禁用,而HDMI处于活动状态,分辨率为1024x768。

另外,这样的配置也禁用寻找设备libudev,而是使用指定的设备。

何时mode未定义,系统选择报告为首选的模式。为可接受的值mode是:off,current,preferred,宽度x高度,或模式行字符串。

默认情况下,DRM层报告的所有屏幕都将被视为一个大型虚拟桌面。鼠标光标实现将考虑到这一点,并按预期在屏幕上移动。尽管不推荐,虚拟桌面模式可以通过设置被禁用separateScreens,以false在配置上,如果需要的话。

默认情况下,根据系统报告的连接器顺序,虚拟桌面从左到右形成。这可以通过设置virtualIndex为从0开始的值来更改。例如,以下配置使用首选分辨率,但确保虚拟桌面中的左侧是屏幕连接到HDMI端口,而右侧是屏幕连接到DisplayPort:

{

“device”:“drm-nvdc”,

“输出”:[

{

“name”:“HDMI1”,

“virtualIndex”:0

},

{

“name”:“DP1”,

“virtualIndex”:1

}

]

}

数组中的元素的顺序是不相关的。具有未指定虚拟索引的输出将放在其他虚拟索引之后,并保留DRM连接器列表中的原始顺序。

要创建一个垂直的桌面空间(即,从上到下而不是从左到右堆叠),添加一个virtualDesktopLayout属性后面device的值vertical。

注意:建议虚拟桌面中的所有屏幕使用相同的分辨率,否则像鼠标光标那样的元素可能会在输入仅存在于一个给定屏幕上的区域时以意想不到的方式运行。

何时virtualIndex不够,该属性virtualPos可用于明确指定问题屏幕的左上角位置。以前面的例子,假设HDMI1的分辨率为1080p,下面第一个基于HDMI的屏幕放在第一个:

{

...

“输出”:[

...

{

“name”:“HDMI2”,

“virtualPos”:“0,1080”

}

]

}

注意:在需要鼠标支持时避免这样的配置。鼠标光标的行为可能是意想不到的非线性布局。Touch应该没有问题。

在某些情况下,通过DRM自动查询物理屏幕尺寸可能会失败。通常QT\_QPA\_EGLFS\_PHYSICAL\_WIDTH,QT\_QPA\_EGLFS\_PHYSICAL\_HEIGHT环境变量将用于提供缺失值,但是当存在多个屏幕时,这并不适用。而是使用列表中的physicalWidth和physicalHeight属性outputs来指定以毫米为单位的大小。

注意:不同的物理尺寸和不同的逻辑DPI不鼓励,因为它可能会导致意外的问题,因为一些图形堆栈组件不知道多个屏幕,仅依靠第一个屏幕的值。

从每个有源输出outputs阵列对应于一个QScreen从报告实例QGuiApplication ::屏幕()。QGuiApplication :: primaryScreen()报告的主屏幕是默认首先注册的屏幕。当不使用时virtualIndex,这意味着决定是基于DRM连接器顺序。要覆盖这一点,属性设置primary,以true对在所需的条目outputs列表。例如,为了确保与VGA输出相对应的屏幕将是主要的,即使系统首先报告HDMI,则可以执行以下操作:

{

“device”:“/dev / dri / card0”,

“输出”:[

{“name”:“HDMI1”},

{“name”:“VGA1”,“mode”:“1280x720”,“primary”:true},

{“name”:“LVDS1”,“mode”:“off”}

]

}

为了进行故障排除,可能会启用KMS / DRM后端的调试日志。为此,启用分类日志记录规则qt.qpa.eglfs.kms。

注意:在嵌入式环境中,虚拟桌面比全窗口系统更为有限。应该避免Windows重叠多个屏幕,非全屏窗口和屏幕之间的移动窗口,并且可能无法正常运行。

多屏幕设置最常用和最受支持的用例是为每个屏幕打开一个专用的QQuickWindow或QQuickView。使用threadedQt Quick场景图的默认渲染循环,这些窗口中的每个都将获得自己的专用渲染线程。这是很好的,因为线程可以基于vsync独立调节,并且不会相互干扰。通过basic循环,这可能会产生问题,动画可能会因此而恶化。

例如,发现所有连接的屏幕,并为每个屏幕创建一个QQuickView可以这样完成:

int main(int argc,char** argv)

{

QGuiApplication应用程序(argc,argv);

QVector视图;

for(QScreen* screen:app.screens()){

QQuickView * view = new QQuickView;

视图 - > setScreen(屏幕);

视图 - > setResizeMode(QQuickView ::SizeRootObjectToView);

视图 - >的SetSource(QUrl( “QRC:/main.qml”));

QObject :: connect(view-> engine(),&QQmlEngine :: quit,qGuiApp,&QCoreApplication:: quit);

views.append(视图);

视图 - > showFullScreen();

}

int result = app.exec();

qDeleteAll(视图);

返回结果;

}

eglfs与eglfs\_kms\_egldevice后端

通常在Tegra设备上使用的这种后端与上述KMS/ DRM后端类似,不同之处在于它依赖于EGLDevice和EGLStream扩展而不是GBM。

有关此方法的技术细节,请查看此演示文稿。

截至Qt 5.7,该后端与基于GBM的后端共享了许多内部实现。这意味着支持多个屏幕和高级配置通道QT\_QPA\_EGLFS\_KMS\_CONFIG。一些设置,如hwcursor和pbuffers不适用。

默认情况下,后端将自动为每个输出的默认平面选择正确的EGL层。必要时,可以通过将QT\_QPA\_EGLFS\_LAYER\_INDEX环境变量设置为所需层的索引来覆盖。此方法目前不支持多个输出,因此其使用应限于具有单个屏幕的系统。要查看哪些层可用,并调试潜在的启动问题,请启用日志记录类别qt.qpa.eglfs.kms。

在某些情况下,即使屏幕报告已经设置了所需分辨率,也可能需要执行应用程序启动时设置的视频模式。这通常是被优化的,但如果屏幕保持关闭状态,请尝试将环境变量设置为QT\_QPA\_EGLFS\_ALWAYS\_SET\_MODE非零值并重新启动应用程序。

要配置后端使用的EGLStream对象的行为,请使用QT\_QPA\_EGLFS\_STREAM\_FIFO\_LENGTH环境变量。这假定KHR\_stream\_fifo是目标系统支持的。默认情况下,流以邮箱模式运行。要切换到FIFO模式,请设置1或更大的值。该值指定流可以容纳的最大帧数。

在某些系统上,可能需要通过预定义的连接器来定位特定的覆盖平面。强制层索引通过QT\_QPA\_EGLFS\_LAYER\_INDEX不执行平面配置,因此本身不适用。相反,在这种特殊情况下,使用QT\_QPA\_EGLFS\_KMS\_CONNECTOR\_INDEX和QT\_QPA\_EGLFS\_KMS\_PLANE\_INDEX环境变量。当这些设置被设置时,只有指定的连接器和平面将被使用,所有其他输出将被忽略。后端将负责选择对应于所需平面的EGL层和配置平面。

在KMS / DRM上有多个屏幕的系统中触摸输入

触摸屏在多显示系统中需要额外的考虑因素,因为触摸事件必须路由到正确的虚拟屏幕,这需要触摸屏和显示器输出之间的正确映射。

映射通过QT\_QPA\_EGLFS\_KMS\_CONFIG前面部分中指定和描述的JSON配置文件完成。当touchDevice属性存在于outputs数组的元素中时,该值被视为设备节点,并且触摸设备与所讨论的显示输出相关联。

例如,假设我们的触摸屏具有/ dev /input / event5的设备节点,并且是集成到通过HDMI连接的显示器作为辅助屏幕的触摸屏,以下配置确保正确的触摸(和合成鼠标)事件转换:

{

“device”:“drm-nvdc”,

“输出”:[

{

“name”:“HDMI1”,

“touchDevice”:“/ dev / input / event5”,

“virtualIndex”:1

},

{

“name”:“DP1”,

“virtualIndex”:0

}

]

}

注意:如有疑问,请QT\_LOGGING\_RULES=qt.qpa.*=true在启动应用程序之前通过设置环境变量来启用图形和输入子系统的日志记录。这将有助于识别正确的输入设备节点,并且可能会发现可能难以调试的输出配置问题。

注意:从Qt 5.8起,上述只支持evdevtouch输入后端。其他变体,例如基于libinput的变体,将继续将事件路由到主屏幕。要强制在具有多个输入后端的系统上使用evdevtouch,请将环境变量设置QT\_QPA\_EGLFS\_NO\_LIBINPUT为1。

eglfs与其他后端

通常基于通过供应商的EGL实现直接针对帧缓冲区或组合API的其他后端,通常对多个显示器提供有限或不支持的支持。在使用VivanteGPU的基于i.MX6的电路板上,与linuxfb类似,QT\_QPA\_EGLFS\_FB环境变量可用于指定要缓存的帧缓冲区。在RaspberryPi上,QT\_QPA\_EGLFS\_DISPMANX\_ID环境变量可用于指定要输出的屏幕。该值对应于其中一个DISPMANX\_ID\_常量,请参考Dispmanx文档。请注意,与KMS/ DRM不同,这些方法通常不允许从同一应用程序输出到多个屏幕。或者,驱动程序特定的环境变量或内核参数也可以用于控制所使用的帧缓冲区。参考嵌入式板“

视频内存

具有固定数量的专用视频内存的系统在运行基于Qt Quick的Qt应用程序或类似QOpenGLWidget的类之前,可能需要特别注意。对于这样的应用,默认设置可能不足,特别是当它们以高分辨率(例如,全高清)屏幕显示时。在这种情况下,他们可能以意想不到的方式开始失败。建议确保至少有128MB的GPU内存可用。对于没有为GPU保留的固定内存量的系统,这不是一个问题。

linuxfb

使用fbplugin参数指定要使用的framebuffer设备。

Unix信号处理程序

面向控制台的平台插件,如eglfs和linuxfb默认安装信号处理程序来捕获interrupt(SIGINT),suspend和continue(SIGTSTP,SIGCONT)和terminate(SIGTERM)。这样,当应用程序终止或由于kill或Ctrl+C或暂停时,可以恢复键盘,终端光标和可能的其他图形状态Ctrl+Z。(尽管通过键盘终止或暂停只能在QT\_QPA\_ENABLE\_TERMINAL\_KEYBOARD设置时进行,如上面的“输入”部分所述)。然而,在某些情况下,捕获SIGINT可能是不合需要的,因为它可能会与远程调试冲突。因此,QT\_QPA\_NO\_SIGNAL\_HANDLER提供环境变量以选择退出所有内置信号处理。

字体

Qt通常用于fontconfig提供对系统字体的访问。如果fontconfig不可用,Qt会回退使用QBasicFontDatabase。在这种情况下,Qt应用程序将在Qt的lib/fonts目录中查找字体。Qt会自动检测预渲染的字体和TrueType字体。可以通过设置QT\_QPA\_FONTDIR环境变量来覆盖此目录。

有关支持的格式的详细信息,请参阅嵌入式Linux字体的Qt。

注意: Qt不再在lib/fonts目录中装载任何字体。这意味着由平台(系统映像)提供必要的字体。

嵌入式Linux设备上的窗口系统的平台插件

XCB

这是常规桌面Linux平台上使用的X11插件。在一些嵌入式环境中,它为Xcb提供了X和必要的开发文件,这个插件就像在普通的PC桌面上一样。

注意:在某些设备上,由于EGL实现与Xlib不兼容,因此在X下没有EGL和OpenGL支持。在这种情况下,XCB插件是在没有EGL支持的情况下构建的,这意味着QtQuick 2或其他基于OpenGL的应用程序不适用于此平台插件。然而,仍然可以使用它来运行软件渲染的应用程序(例如基于QWidget)。

作为一般规则,XCB在嵌入式设备上的使用是不可取的。像eglfs这样的插件可能会提供更好的性能和硬件加速。

Wayland

Wayland是一个重量轻的开窗系统; 或者更准确地说,它是用于客户端与显示服务器通信的协议。

Qt Wayland模块提供了一个wayland平台插件,允许Qt应用程序连接到Wayland合成器。

注意:使用Weston参考合成器时,您可能会遇到触摸屏输入的问题。有关更多信息,请参阅Qt Wiki。

标签: Linux, 插件, Qt, 屏幕, 嵌入式, QT, QPA, EGLFS

相关文章推荐

添加新评论,含*的栏目为必填