5

I am trying to auto launch a Tkinter/Python program when the Raspberry Pi boots up.

Ideally I would like to boot the Pi into the console and then launch a GUI Tkinter Python program. In testing – not sure if this is possible?

The second best option would be to boot the Pi into the graphical desktop and then launch a GUI Tkinter Python program.

I see similar questions have been asked but none of the answers seem to work launching a Tkinter program in Raspbian

I have tried to edit the following:

nano ~/.config/lxsession/LXDE-pi/autostart

and added the following lines one at a time:

@lxterminal -e 'python /home/pi/guiprog.py  launches command window – no gui

@python /home/pi/guiprog.py             launches command window – no gui

How do I best automatically launch a Tkinter Python program after boot?

Darth Vader
  • 4,206
  • 24
  • 45
  • 69
dkuzdas
  • 59
  • 1
  • 1
  • 2

4 Answers4

6

From Sparkfun website: The three methods covered in this tutorial are:

rc.local - Likely the easiest and simplest way to get your program to run on boot. The downside is that tasks started with rc.local happen before the X windows system starts, which means you will not have access to graphical user interface (GUI) elements.

autostart - Used to automatically run your programs once LXDE (graphical desktop environment used by Raspbian) starts. It's slightly more complicated than rc.local, but it lets you run programs that require graphical elements.

systemd - The new and popular way to automatically start programs in Linux. It is definitely the most complicated of the three, but it allows you to run before LXDE starts, wait until you have access to other processes (e.g. networking, graphical desktop), or simply restart your program over and over again until it works. As such, it is a robust way to create and manage services that run in the background.

With systemd (example for running chromium at start-up) Note: on Sparkfun /lib folder is specified but USE /etc system folder is best choice...

~$ sudo nano /etc/systemd/system/chromium.service

[Unit]
Description=Start Chromium
After=graphical.target
Wants=graphical.target

[Service]
User=pi
Group=pi
ExecStart=/bin/bash -c "export DISPLAY=:0; export XAUTHORITY=/home/pi/.Xauthority; chromium-browser"

[Install]
WantedBy=graphical.target

Configuration:

~$ sudo systemctl daemon-reload
~$ sudo systemctl enable chromium.service
# Now you can test your service (chromium must start)
~$ sudo systemctl start chromium.service
# or for testing at startup
~$ sudo reboot
# Verify the service
~$ sudo systemctl status chromium.service
# for prevent the browser to reopen his processus when you click on the window close button, use:
~$ sudo systemctl stop chromium.service
Ephemeral
  • 2,157
  • 1
  • 6
  • 19
  • With the systemd unit: I hate to restart buggy scripts/programs. They should run stable. If not then it must be fixed and not ignore it. Also I would add After=graphical.target in the [Unit] section. Then there is no need to restart the browser because it is started to early. These attempts are a waste of resources just on startup. – Ingo May 25 '19 at 17:14
  • @Ingo, yes you are right I try to ajust the unit file... – Ephemeral May 25 '19 at 18:41
  • No, don't use Type=oneshot. That's only for programs that run just once a short time. Chromium runs all the time and as I see you want to stop it with systemctl. – Ingo May 25 '19 at 18:41
  • @Ingo, thank for this explanation. – Ephemeral May 25 '19 at 18:43
  • And to elaborate about wasting resources: With systemd there is no order given when services start if they do not have dependencies. So Chromium will start as one of the very first services and will fail because the GUI isn't present. It tries to start as long as the GUI is present. That's the waste. With the After=graphical.target dependency it will definitely start once after the GUI is present. – Ingo May 25 '19 at 18:49
  • @Ingo, I try to put After=graphical.target in unit, but now this doesn't work, chromium is not started on my system. – Ephemeral May 25 '19 at 18:49
  • How do you adapt this for a python script instead of chromium? – Samantha Garcia Apr 28 '21 at 22:23
1

I don't have the source where I got this code from, but it works for me (Pi 4 with Raspian, running a Qt application with Python):

sudo mkdir /home/pi/.config/autostart
    sudo nano /home/pi/.config/autostart/yourApp.desktop
        [Desktop Entry]
        Type=Application
        Name=yourApp
        Exec=/usr/bin/python3 /home/pi/yourfolder/yourApp.py
Clóvis Fritzen
  • 373
  • 1
  • 11
1

You can run a tkinter script with just a window manager and XORG, no desktop needed:

  1. Make sure XORG and openbox are installed.
  2. Create the following file in the directory with your tkinter script (named starter here for example purposes):
    #!/bin/sh
    openbox --config-file ~/.config/openbox/rc.xml --startup tkinterscript.py
  1. Make that file executable with chmod +x starter
  2. Test it by running xinit ./starter. This should run your tkinter script without the desktop environment.

Now I'll propose a different method for at-boot running than the other answer: cron.

You can edit your crontab with the command crontab -e and add:

@reboot xinit /path/to/starter

Clearly, you should replace /path/to with the actual path that your tkinter script and the starter script are stored.

Note: This crontab is for your user. This means that this path starts at your home directory, not the root directory. If your script requires root privileges, edit crontab instead with sudo crontab -e and use the full path from the root directory instead.

Sometimes, running a script RIGHT after a boot doesn't work since Linux is still figuring itself out, in that case you can add a delay (for example of 30 sec):

@reboot sleep 30 && xinit /path/to/starter

Now you should be good to go. That command will run at boot from now on.

Resources: https://www.raspberrypi.org/forums/viewtopic.php?t=152264

Patrick Cook
  • 6,365
  • 7
  • 37
  • 63
0

Yes it is possible to launch Tkinter Python program to the Pi console. What you have tried should have worked. However, if python /home/pi/guiprog.py has a end, a window will appear and run the program to the end and then close the window before the system completes the boot. A good test would be to have a lxterminal and execute the command python /home/pi/guiprog.py launches command window – no gui. Did that work? if yes, that is good. Next exec lxterminal -e 'python /home/pi/guiprog.py launches command window – no gui'. If the new lxterminal stay open, it should also work on boot up.

A GUI EXAMPLE:

pi@RPi3:~ $ ls -l bin/dsphost.py
-rwxr-xr-x 1 pi pi 571 Jan 14 13:15 bin/dsphost.py
pi@RPi3:~ $ cat bin/dsphost.py
#!/usr/bin/env python 
# Program name is dsphost.py.

import Tkinter as tk

fp = open('/etc/hostname', 'r')
hn = fp.read().strip()
fp.close()

fp = open('/etc/os-release', 'r')
os = ((fp.readline().strip().split())[-1])[1:-2].capitalize()
fp.close()

fp = open('/etc/debian_version', 'r')
ver = fp.read().strip()
fp.close()

data = hn + " " + os + " " + ver

mywindow = tk.Tk()
mywindow.geometry("+0+36")
tk.Label(text=data, font=("Roboto 14")).pack()
mywindow.overrideredirect(1)
mywindow.mainloop()

pi@RPi:~ $ cat .config/lxsession/LXDE-pi/autostart
@lxpanel --profile LXDE-pi
@pcmanfm --desktop --profile LXDE-pi
@xscreensaver -no-splash
@dsphost.py

You have to keep the window open as in "mywindow.mainloop()" or some other way. Note, as I put the program in /home/pi/bin a boot is requited after creating the bin directory.

bstipe
  • 534
  • 3
  • 5