NotePublic/Software/Development/Environment/Qt/Embedded/Qt_Embedded_说明.md

5.1 KiB
Raw Blame History

Qt Embedded 说明

1. QPA

QPA 的全称是 Qt Platform Abstraction即 Qt 平台抽象层。在 Qt5 中替代 QWS(Qt Window System)。QPA 插件是通过对各种 QPlatform* 类进行子类化来实现的。有几个根类,例如用于窗口系统集成的 QPlatformIntegration 和 QPlatformWindow以及用于更深入的平台主题和集成的 QPlatformTheme。QStyle 不是 QPA 的一部分。QPA 类没有源代码或二进制兼容性保证这意味着平台插件只能保证与它开发的Qt版本一起使用。

在 Qt4 在编译时需要引入平台相关代码其可移植性差Qt5 通过引入 QPA 来剥离平台相关代码,提高跨平台特性。

1.1. Qt 应用程序的 QPA 参数/环境变量

优先使用环境变量中的宏定义,如 QT_QPA_PLATFORM其次使用程序运行时指定的参数。

指定 mouse、touch、keyboard需要加载 hid、hid-generic、usbhid 驱动):

# 使用 linuxfb
<qt program> -platform linuxfb:fb=/dev/fb0:mmsize=1024x600 -plugin evdevmouse:/dev/input/event<X> -plugin evdevtouch:/dev/input/event<Y> -plugin evdevkeyboard:/dev/input/event<Z>
# 使用 directfb
<qt program> -platform directfb

使用 directfb 不需要指定 fbdev、input 等,这些信息在 /etc/directfbrc 中指定,具体查看 directfbrc 的 man 手册。

1.1.1 常用环境变量

# 指定插件安装路径.qp   
export QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib/qt/plugins
# 指定 Platform 参数.
export QT_QPA_PLATFORM=linuxfb:tty=/dev/fb0
# 设置字体目录.
export QT_QPA_FONTDIR=/usr/share/fonts
# 打开插件调试.
export QT_DEBUG_PLUGINS=1

1.1.2. -platform 参数QPA Platform

主要见 plugin/platforms 文件夹下有哪些插件,如:

  • linuxfb
  • directfb
  • weston

1.1.3. -plugin 参数QPA Evdev Plugin

主要见 plugin/generic 文件夹下的 libqevdev* 插件,如:

  • evdevkeyboard
  • evdevmouse
  • evdevtablet
  • evdevtouch

1.2. EGLFS

export QT_QPA_EGLFS_KMS_CONFIG=kms_config.json
export QT_QPA_PLATFORM=eglfs
export QT_QPA_EGLFS_INTEGRATION=eglfs_kms
export QT_LOGGING_RULES=qt.qpa.*=true
export QT_QPA_EGLFS_DEBUG=1

sudo cat /sys/kernel/debug/dri/0/summary

kms_config.json 如下:

{
  "device": "/dev/dri/card0",
  "hwcursor": false,
  "pbuffers": true,
  "outputs": [
    {
      "name": "HDMI1",
      "mode": "1920x1080"
    }
  ]
}

QT_QPA_EGLFS_INTEGRATION

  • eglfs_x11
  • eglfs_kms
  • eglfs_emu
  • eglfs_kms_egldevice

2. 自启动

2.1. init 方式启动

如果程序能通过命令行进行启动,则可以通过系统服务来实现自开机自启动。

首先,在 /etc/init.d/ 文件夹下创建一个启动脚本,比如 mydemo

#!/bin/bash
### BEGIN INIT INFO
# Provides:          airobot
# Required-Start:    $all
# Required-Stop:
# Default-Start:     2 5
# Default-Stop:
# Short-Description: your description here
### END INIT INFO

start(){
    /path/to/demo -platform linuxfb:fb=/dev/fb0:mmsize=1920x1080 &
}

stop(){
    killall -q demo
}

restart(){
    stop
    start
}

case $1 in
    "start")
    start
    ;;
    "stop")
    stop
    ;;
    "restart")
    restart
    ;;
    *)
    start
esac

注意文件头 Default-Start 等注释是必须的,用于指定 runlevel。在 init 脚本中start、stop 和 restart 是几个必须支持的命令,根据实际需求,设置运行环境,编写对应命令即可。

之后通过 chkconfig 或 update-rc.dUbuntu 系统) 对服务进行配置即可:

update-rc.d 使用方式如下:

# 添加服务
sudo update-rc.d [service name] defaults
# 使能
# 出现“Failed to enable unit: Unit /run/systemd/generator.late/mydemo.service is transient or generated.” 
# 说明 default 执行时已经生成了对应的 .service 文件,可以忽略该错误。
sudo update-rc.d [service name] enable
# 移除
sudo update-rc.d -f [service name] remove
# 查看当前服务
ls /etc/init.d/

chkconfig 使用方式如下:

# 添加
chkconfig --add mydemo
# 删除
chkconfig --del mydemo
# 设置 runlevel
chkconfig --level 2345 mydemo on
# 查看服务
chkconfig --list | grep mydemo

2.1. systemd 方式启动

在 /usr/lib/systemd/system 下创建 mydemo.service 文件,参考内容如下:

[Unit]
Description=MyDemo
# After=syslog.target
# After=network.target
# After=multi-user.target
# After=graphical.target
After=plymouth-quit-wait.service
# After=systemd-logind.service

[Service]
RestartSec=2s
Type=simple
User=root
Group=root
WorkingDirectory=/path/to/workDirectory
ExecStart=/path/to/demo/demo -platform linuxfb:fb=/dev/fb0:mmsize=1920x1080
Restart=always

[Install]
WantedBy=multi-user.target

也可以使用 After=graphical.target。

然后使用 systemctl 命令控制服务:

sudo systemctl enable mydemo
sudo systemctl start mydemo
sudo systemctl stop mydemo
sudo systemctl disable mydemo

如果 Screen 的虚拟终端遮蔽了 QPA 应用程序,则可以将其关闭:

sudo systemctl mask getty@tty1.service

3. 外部参考资料

  1. Qt for Embedded Linux