pygame.display.init() 对于非 root 用户失败

vin*_*lti 5 python pygame framebuffer raspberry-pi sdl-2

太;博士

我需要使用,但由于帧缓冲区驱动程序pygame的权限,它无法作为普通用户初始化屏幕。root 可以做,但用户不能做。用户位于“视频”组中,可以在 上书写。用户缺少什么权限才能工作。 遇到错误:pygame.display.init()/dev/fb0pygame.display.init()
pygame.error: Unable to open a console terminal

描述

所以,我尝试使用pygame来在帧缓冲区上显示内容/dev/fb0。要使用某些功能,我需要(例如pygame.Surface.convert)必须初始化显示器。但是,当调用时pygame.display.init()我遇到错误,但仅当不以 root 身份执行此操作时才会出现错误。

根据@Nodraak (参考),它与帧缓冲区驱动程序的权限有关 。

回答晚了,但我希望我能早点尝试一下:

您可能需要成为 root 才能使用帧缓冲区驱动程序。

(这对我的情况有帮助:RaspberryPi 2 没有运行 X,但连接了屏幕。我现在可以通过 SSH 或直接在 RPi 上打开显示器)

Atree -fupg / | grep fb | grep rwx 似乎没有显示任何可以由 root 执行但不能由其他人执行的二进制文件。我非常确定将我的用户添加到组中,或在某处调整文件权限就足以解决问题。

注意:出于安全原因,不能以 root 身份运行软件。

语境

  • 系统:树莓派
  • X 服务器:无
  • 屏幕:1(HDMI)
  • 连接:远程(SSH)

错误的根源

我正在尝试转换具有功能的表面pygame.Surface.convert(...)。但收到以下错误:

pygame.error: cannot convert without pygame.display initialized
Run Code Online (Sandbox Code Playgroud)

然而,初始化 pygame.displaypygame.display.init()会给出以下错误:

pygame.error: Unable to open a console terminal
Run Code Online (Sandbox Code Playgroud)

我有权向屏幕写入内容,因为我是该video组的一员,并且cat /dev/urandom > /dev/fb0正在屏幕上有效地显示雪。

我还尝试将 SDL_... 环境变量设置为fbconordummy但没有帮助。我还尝试将 root 环境保留为用户su -m user并得到相同的结果。

重现错误

在没有 XServer 的树莓派上,连接 HDMI 屏幕,安装 pygame。

pygame.error: cannot convert without pygame.display initialized
Run Code Online (Sandbox Code Playgroud)

错误信息:
pygame.error: Unable to open a console terminal

软件版本

python     3.7.3
pygame     1.9.4.post1
OS         Raspbian Buster
libsdl     2
Run Code Online (Sandbox Code Playgroud)

有关的

vin*_*lti 2

问题的解决方案

开放式虚拟化技术

因此,满足我列出的所有要求的最佳解决方案似乎是使用openvt.

如何 ?

该过程包含以下几个要点:

1. 将用户添加到tty组中

作为 root,将您的用户添加到名为 的组中tty,这将允许我们授予其访问 TTY 的权限。

# As root:
usermod -a -G tty $username
Run Code Online (Sandbox Code Playgroud)

2. 为组中的用户授予 TTY 访问权限tty

既然用户是组的一部分,tty我们需要允许它在其上写入,因为 openvt 将使用 tty。默认情况下,模式应设置为620我们需要将其设置660为允许组在其上写入。

# Edit file: /lib/udev/rules.d/50-udev-default.rules
SUBSYSTEM=="tty", KERNEL=="tty[0-9]*", GROUP="tty", MODE="0660"
#                                      ensure mode is 0660  ^
Run Code Online (Sandbox Code Playgroud)

3.设置SDL环境变量

在您的软件中,确保设置 SDL 的环境变量。

import os
# ...
os.environ['SDL_VIDEODRIVER'] = 'fbcon'
os.environ["SDL_FBDEV"] = "/dev/fb0"
Run Code Online (Sandbox Code Playgroud)

4. 重新启动树莓派

好吧,你不需要一个片段。是否?好吧,好吧。

# as root / with sudo
reboot
Run Code Online (Sandbox Code Playgroud)

5. 启动软件openvt

openvt(打开虚拟终端)允许我们直接通过屏幕访问运行界面。这必须由最终用户在与软件相同的目录中执行(最好)。

openvt -s -- python3 ./interface.py
Run Code Online (Sandbox Code Playgroud)

这应该有效。
当然,您可以将其集成到 Linux 服务中,以便它在启动时启动。但您可能需要添加服务文件的部分After: getty@tty1.service[Unit]

好吧,我花了很多时间才弄清楚这一点,所以我希望它对其他人也有帮助。