【问题标题】:PyQt: How to run GUI on Raspberry Pi desktop startup?PyQt:如何在 Raspberry Pi 桌面启动时运行 GUI?
【发布时间】:2018-05-16 09:59:36
【问题描述】:

尊敬的 Stackoverflow 社区,

我正在努力运行一个 python 脚本,该脚本在 Raspbian Jessie 的 Raspberry Pi 3B 桌面启动时执行 PyQt5 GUI

到目前为止我有什么?

  • 第一行带有 shebang #!/usr/bin/env python3 的 Python 脚本(python3 --version 是 3.4.2)运行 GUI 没有任何问题

  • Shell 脚本 (.sh) 能够使用以下行执行 GUI:

    #!/bin/bash python3 GUI.py

可能有帮助的信息:

  • 如果我将这两个文件放在同一目录中的某个位置,Shell 脚本会启动 GUI,但如果它们位于桌面上,则不会。

  • 已启用自动登录桌面。

提前感谢您的帮助。

RaspiManu

更新:

我通过大量测试解决了我的问题,并为其他用户发布了答案。

【问题讨论】:

    标签: python python-3.x pyqt raspberry-pi pyqt5


    【解决方案1】:

    经过大量测试,我自己弄清楚了。这就是它对我的工作方式......

    创建自动运行文件:

    2.1 LXTerminal:cd /home/pi/.config/autostart

    2.2 LXTerminal:sudo nano pythonscript.desktop

    2.3 pythonscript.desktop:

    [Desktop Entry]
    Version=1.0
    Name=YourName
    Comment=Your comment
    Exec=/home/pi/pythonscript.py -nograb #-nograb for comboBox on touch Screen
    Icon=/usr/share/pixmaps/python.xpm
    Path=/home/pi/
    Terminal=false
    StartupNotify=true
    Type=Application
    Categories=Utility;Application;
    

    2.4 Ctrl+O、Ctrl+X、sudo reboot

    很高兴知道:

    重要的是,您不能只使用脚本的任何路径。该脚本必须直接位于/home/pi/ 目录中,因此您将在自动运行文件(.desktop)中使用Exec=/home/pi/pythonscript.py。我还了解到,如果您的脚本加载了例如带有 PIL 的图像,则该图像必须位于其他位置,可能在您的桌面上,因为它无法从 /home/pi/ 目录中打开。

    如果您的 GUI 有一个组合框并且您使用的是触摸屏,那么在您触摸它后,组合框可能会使您的整个 GUI 无法使用。使用Exec=/home/pi/pythonscript.py -nograb 可以解决这个问题。

    StartupNotify=true 对于启动 GUI 脚本很重要。

    希望这会有所帮助,

    RaspiManu

    【讨论】:

    • 我正在关注您的回答,并且能够在启动时运行 pyqt5 应用程序。但它没有加载图像。我的项目目录在 /home/pi/Documents/Project 内,其中包含所有图像。我是否需要按照您的建议将我的项目移动到 /hom/pi/
    • 亲爱的@SAndrew,这是很久以前的事了,我不完全确定。很高兴您的脚本在启动时运行。当我做我的 GUI 项目时,我的脚本位于 /home/pi/ 目录中。这个脚本的 python 代码从我桌面上的一个文件夹中打开了图片(Raspbian Stretch)。也许您也可以尝试从桌面文件夹加载图片。如果这可行,您有一个参考,您可以尝试其他可能有效的位置选项。我真的希望,这可以帮助你。祝你好运:)
    • 我做错了什么? cd /home/pi/.config/autostart 给了我这个错误:-bash: cd: /home/pi/.config/autostart: No such file or directory
    • 亲爱的@Phönix64,这个错误意味着你的系统没有那个文件夹。自 2018 年以来,自动启动文件夹的路径可能已更改。正如您在我的原始帖子中看到的,我与现在已经过时的 Raspbian Jessie 合作。该系统甚至将全名从 Raspbian 更改为 Raspberry Pi OS。我建议您对文件夹的新位置进行一些研究,然后再试一次。祝你的项目好运:)
    • 谢谢你,虽然这是我错过的某种配置步骤,但事实证明他们完全改变了服务结构。现在可以了
    【解决方案2】:

    您可以通过以下链接创建一个在启动时运行的后台服务 Service method

    并通过附加这一行

    service yourdaemon start
    

    在 /etc/rc.local 中

    假设您的服务名称是“yourdaemon”

    注意:使用根权限

    示例服务文件

    #! /bin/sh
    ### BEGIN INIT INFO
    # Provides:          yourdaemon
    # Required-Start:    $remote_fs $syslog
    # Required-Stop:     $remote_fs $syslog
    # Default-Start:     2 3 4 5
    # Default-Stop:      0 1 6
    # Short-Description: Your Daemon
    # Description:       Your Daemon
    ### END INIT INFO
    
    # PATH should only include /usr/* if it runs after the mountnfs.sh script
    PATH=/sbin:/usr/sbin:/bin:/usr/bin
    DESC="Your Daemon"
    NAME=yourdaemon
    DAEMON=/hannext/yourdaemon.py  # Path to your python file
    PIDFILE=/var/run/$NAME.pid
    SCRIPTNAME=/etc/init.d/$NAME
    LOGFILE=/var/log/snc/$NAME.log
    
    
    . /lib/lsb/init-functions
    
    do_start()
    {
            echo "$(date +%F) $(date +%T) DAEMON   : Starting $DESC service" >> $LOGFILE
            start-stop-daemon --start --quiet --oknodo --pidfile $PIDFILE --startas $DAEMON --make-pidfile --background
    }
    
    do_stop()
    {
            echo "$(date +%F) $(date +%T) DAEMON   : Stopping $DESC service" >> $LOGFILE
            start-stop-daemon --stop $DAEMON --quiet --oknodo --pidfile $PIDFILE
            rm -f $PIDFILE
    }
    
    #
    # Function that sends a SIGHUP to the daemon/service
    #
    do_reload() {
            #
            # If the daemon can reload its configuration without
            # restarting (for example, when it is sent a SIGHUP),
            # then implement that here.
            #
            start-stop-daemon --stop --signal 1 --quiet --pidfile $PIDFILE --name $NAME
            return 0
    }
    
    case "$1" in
      start)
            [ "$VERBOSE" != no ] && log_daemon_msg "Starting $DESC" "$NAME"
            do_start
            case "$?" in
                    0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                    2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
            esac
            ;;
      stop)
            [ "$VERBOSE" != no ] && log_daemon_msg "Stopping $DESC" "$NAME"
            do_stop
            case "$?" in
                    0|1) [ "$VERBOSE" != no ] && log_end_msg 0 ;;
                    2) [ "$VERBOSE" != no ] && log_end_msg 1 ;;
            esac
            ;;
      status)
            status_of_proc "$DAEMON" "$NAME" && exit 0 || exit $?
            ;;
      #reload|force-reload)
            #
            # If do_reload() is not implemented then leave this commented out
            # and leave 'force-reload' as an alias for 'restart'.
            #
            #log_daemon_msg "Reloading $DESC" "$NAME"
            #do_reload
            #log_end_msg $?
            #;;
      restart|force-reload)
            #
            # If the "reload" option is implemented then remove the
            # 'force-reload' alias
            #
            log_daemon_msg "Restarting $DESC" "$NAME"
            do_stop
            case "$?" in
              0|1)
                    do_start
                    case "$?" in
                            0) log_end_msg 0 ;;
                            1) log_end_msg 1 ;; # Old process is still running
                            *) log_end_msg 1 ;; # Failed to start
                    esac
                    ;;
              *)
                    # Failed to stop
                    log_end_msg 1
                    ;;
            esac
            ;;
      *)
            #echo "Usage: $SCRIPTNAME {start|stop|restart|reload|force-reload}" >&2
            echo "Usage: $SCRIPTNAME {start|stop|status|restart|force-reload}" >&2
            exit 3
            ;;
    esac
    
    :
    

    在 /etc/init.d/ 中以 'yourdaemon' 的名称保存它并使用

    使其可执行
    chmod +x yourdaemon
    

    【讨论】:

    • 非常感谢您的回答,请原谅我的问题...我对此很陌生,从未使用过守护进程。我了解,您可以使用/etc/init.d 中的骨架文件来构建一个,但我查看了其他一些守护程序,如 sudo 或 reboot ,它们似乎是用 C++ 或 C# 编写的,我无法使用。您能否再解释一下创建守护进程的步骤?以及如何使用根权限?
    • 我已经编辑了我的答案并包含了一个示例脚本来提供服务
    • 你帮了我这么大的忙,真是让我开心。谢谢!我已经不在工作了,但我明天一定会尝试并告诉你。
    • 应该$NAME 保持原样并使用NAME=yourdemon,如果这样工作,还是我必须更改yourdemon 以外的其他内容和我的.py 文件的路径?
    • 它是服务的名称,因此您应该相应地命名它。如果您觉得有帮助,请在测试后标记为正确。
    猜你喜欢
    • 1970-01-01
    • 2023-03-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-05-03
    • 1970-01-01
    相关资源
    最近更新 更多