Python GUI in Linux frame buffer

I was recently wondering about how can I display some graphics in Linux frame buffer with Python. It seems that if your text terminal is initialized in frame buffer mode (most of modern distributions do this), what you need is our old friend PyGame. It supports a wide selection of video drivers among which there is also some for utilizing frame buffer. If you want to play with or develop GUI applications in Python without X Window then here’s a simple example how.

PyGame checks for environment variable SDL_VIDEODRIVER that specifies which video driver PyGame should utilize for initializing display. This can come handy if you are running pure PyGame based application and want to use it if you don’t have or want X.org. Unfortunately this also means that you have to manually export SDL_VIDEODRIVER variable before running your application. There’s a little trick you can do for automatically determining whether you want to run your app in frame buffer.

When application is run within X.org context, the DISPLAY environment variable is passed to your application (in fact it’s set in the system context for the app, but that doesn’t matter). You can test if app was run from X Window system like this:

import os
disp_no = os.getenv('DISPLAY')
if disp_no:
    print "I'm running under X display = {0}".format(disp_no)

 

When we know if we have X Window running or not we can act accordingly. What we want to do in our app is to check for the X display first, the check if SDL_VIDEODRIVER is set and if not we want to set it automatically. This is how we do it:

driver = 'directfb'
if not os.getenv('SDL_VIDEODRIVER'):
    os.putenv('SDL_VIDEODRIVER', driver)

 

As PyGame documentation states there are different video drivers available under Linux: x11, dga, fbcon, directfb, ggi, vgl, svgalib, aalib. Obviously we are interested only in three: directfb, fbcon and svgalib. Those are the drivers for console frame buffers. Which should you choose depends on the Linux distribution you have. Ideally you want directfb, because it’s probably the most advanced and modern type of frame buffer library. You can either let your users choose the appropriate driver before you launch your primary app or you can test which is the most suitable. This is really simple:

drivers = ['directfb', 'fbcon', 'svgalib']

found = False
for driver in drivers:
    if not os.getenv('SDL_VIDEODRIVER'):
        os.putenv('SDL_VIDEODRIVER', driver)
    try:
        pygame.display.init()
    except pygame.error:
        print 'Driver: {0} failed.'.format(driver)
        continue
    found = True
    break

if not found:
   raise Exception('No suitable video driver found!')

 

This will automatically try all drivers in the list and stay with the first one that works. If none is found an Exception will be raised.

When we found appropriate driver we now have to initialize our screen and display mode. With frame buffer we have to determine it’s resolution before we can appropriately set mode. We can do this like this:

size = (pygame.display.Info().current_w, pygame.display.Info().current_h)
screen = pygame.display.set_mode(size, pygame.FULLSCREEN)

 

pygame.display.Info() is a special object that carries information about current display. We use current_w and current_h variables to set new size for PyGame display. If we didn’t do it, we would not be using the whole frame buffer resolution which would look awkward. I’m not sure if it’s possible to switch between frame buffer modes after fb console terminals were initialized.

After we’ve called pygame.display.set_mode() we can proceed with our application development as usually.

About Wolverine

If you are looking for IT consultant, let me know! karol at karoltomala dot REMOVE com Just remove the REMOVE word from the e-mail above!
This entry was posted in Game Programming, Linux, Programming, Python and tagged , , , , , , , , . Bookmark the permalink.

21 Responses to Python GUI in Linux frame buffer

  1. Ganso says:

    Finally I found this info!! I’ve searched a lot… I’m trying to do a pygame app to run without a window manager, launched from text-mode. Do you think it’s possible?
    I tried your way, but sometimes works, sometimes no, do you know what is my problem?

    Thanks, Ganso

  2. Wolverine says:

    Hello Ganso. I was on my holidays.
    This tutorial is exactly telling how to run PyGame app without X Windows. I don’t have any clue why this may sometimes work and sometimes won’t. Remember that you have to run your app from text mode terminal. This solution won’t work if you are using pseudo terminal like gnome-terminal, konsole, xterm or any other pseudo terminal running under X.

    Perhaps if you provided more information, like for example debug output of your environment variables and information about frame buffer devices I might be able to help you.

    Greetings,
    Karol

  3. Pingback: Status-Q » Blog Archive » Raspberry Pi Webcam Viewer

  4. Alfonso E.M. says:

    This is great for my Raspberry Pi. Thanks!

  5. Wolverine says:

    Glad you like it.

  6. BernardJ says:

    Has this been actually tested with a Raspberry Pi?
    I’ve just tried it, running Rasbian 16/8/2012 build, and I get the following failures:
    DirectFB/fbdev/vt: /KD_GRAPHICS failed:
    –> Operation not permitted
    DirectFB/Core: Could not initialise ‘Sydtem_core’ core:
    –> Initialization error!

    any clues? I would love to get this working! Thanks in advance.

  7. Alfonso E.M. says:

    Try running it as root, with “sudo”. It works for me.

  8. TheEvil says:

    Just found you blog, Big moo2 fan my self. read your whole sheet hope your less blue been there or that not. I use ubnutu 10.04 and/or xp. got your viewer Ill try me hand at getting it going. Love to use it and breathe new life into MOO2 . not much of a programmer. if your could find time to mod the code to 10.04 or xp(i know im a sick man to still jump back to windows from time to time) tat would by great! ill mod the hell out of the game. nothing make a man feel better than a FRESH game of moo2!!! ive got most other mod s u have anything off beat? out

  9. TheEvil says:

    ps hows the lords game coming along

  10. Wolverine says:

    You can also try to change driver from DirectFB to another. Thanks!

  11. Ron says:

    Sorry to post on such an old article. I’ve been playing with your code. I am a newb to python and obviously pygame. Is this a good starting point to build a game? I am trying to make something fairly simple, almost as simple as a click counter. Should I be able to get the mouse pointer that shows up to move?

    I am using a Raspberry Pi B+ with the latest Rasbian OS.

    Thank you! Your code is really helping me wrap my head around python. I feel I am right around the corner from being able to do something useful.

  12. Wolverine says:

    Hello Ron! Thank you for your comment. I am pretty sure this is a good starting point for developing a simple game. I am not sure if I understand correctly what you mean by getting mouse pointer to show up to move, but I am fairly certain that pygame, even when using framebuffer should be able to use it. It may however be necessary to install some additional drivers, but AFAIR mouse cursor should be visible after initializing framebuffer. If not you may install gpm (sudo apt-get install gpm) under Raspbian.

    I have seen a great tutorial that is using the code I have developed here, especially for Raspberry Pi to show more advanced usage of PyGame. You can check it out here: https://learn.adafruit.com/pi-video-output-using-pygame/pointing-pygame-to-the-framebuffer

    Thanks a lot and have a great fun coding!

  13. TapEC says:

    Hi there,

    Thank you very much for sharing this information. Would you please help me in my case. I am new to python and Raspberry Pi. I have just wrote python script for simple GUI that give two buttons. I want to run that script when RPi boot without getting xWindow. I mean, I want to boot to my python GUI directly without going into desktop.
    I tried editing /etc/rc.local file but no luck. Would you please help me with this issue. That would be great.

    Thank you.

  14. TapEC says:

    Here is the simpple python script I want to run when RPi boot without going to xWindow:

    #/usr/bin/python3
    #creat GUI
    #Language:Python(3)
    from tkinter import *
    mywin=TK()

    mywin.title(“Raspberry Pi GUI”)
    label=Label(mywin,text=”abc”)
    label.pack

    firstButton=Button(mywin,text=”xyz”)
    firstButton.pack(side=LEFT)

    secondButton=Button(mywin,text=”quit”)
    secondButton.pack(side=RIGHT)
    mywin.geometry(“300×300”)
    mywin.mainloop()

  15. Wolverine says:

    Hello TapEC. I’m sorry to tell you this, but you probably would not be able to use TK within pygame display, at least not without doing some very complex coding.

    But first things first. If you would like to show graphics in your raspberry pi without XWindow, you’ll have to use my recipe for initializing what’s called a DISPLAY. A display uses most appropriate console graphics driver to give you a SURFACE on which you can draw which is associated with a DISPLAY.

    Then, after initializing a PyGame display you have to use some GUI frameworks to show buttons, windows, any other widgets that you want. Unfortunatelly you can’t use TK widgets to draw on PyGame surface, because TK requires XWindow (AFAIK). So, you’ll have to use some other library to do what you want. Here’s a list of GUI libraries for PyGame, but I’m sure there is more:

    http://ocemp.sourceforge.net/gui.html
    http://www.pygame.org/project-Tygame+-+GUI+Project-2081-.html
    http://www.pygame.org/project-SGC-2089-.html
    http://www.pygame.org/project-Interphase-2917-.html
    http://www.pygame.org/project-Stellar+-+Pygame+GUI-2293-.html
    http://www.google.pl/url?sa=t&rct=j&q=&esrc=s&source=web&cd=8&cad=rja&uact=8&ved=0CE8QtwIwBw&url=http%3A%2F%2Fwww.youtube.com%2Fwatch%3Fv%3D8TcrTTXPD7s&ei=6XXrVNTwB4L2UrrVgHA&usg=AFQjCNEd50zK3EeaIqPIPzYAIrS68pk3UA&sig2=78HQxmumbyDM6lvme0uc3g&bvm=bv.86475890,d.d24

    Good luck and happy coding!

  16. TapEC says:

    Thanks for the response Wolverine,

    I am not using pygame display… I want to display python GUI with two simple buttons without any graphics. I have shared my drop box link here :

    https://www.dropbox.com/s/748a9sjqia2j1gf/Video%202015-02-23%2C%2013%2019%2048.mov?dl=0

    I could do that by editing “autostart” script (/etc/xdg/lxsession/LXDE/autostart)
    and pasted location of my script of python GUI at the end of line in “autostart” file. I had to delete all the line to boot to python GUI.
    As I am done with my experiment, now how would I go back to normal boot without getting GUI?
    Any thoughts?

  17. TapEC says:

    I mean I am kind of stuck as I created GUI with “Quit” button. When you press Quit button, python GUI closes and only black screen stays on the screen. I have to unplug RPi to reboot. As I have modified “autostart” file, it never boot to xWindow.

    I think I have to format the SD card and re-install everything …
    Please let me know if you have other way out.

  18. Wolverine says:

    Hi TapEC. I understand what you did. You are still booting your RPi into X, that’s I’m certain, because you have said that you simply removed autostart from LXDE. You can switch to normal linux console pressing CTRL+ALT+F1 or CTRL+ALT+F2 up to CTRL+ALT+F6. One of those combinations will land you on a text terminal console. You’ll see login prompt. Type in your login, press enter, then password. The default login for RPi is “pi” with password “raspberry”. Then you will have to switch user to root typing in: “sudo su” and probably retyping password “raspberry”. You should see # at the end of the prompt and it will mean you are logged in as administrative user “root”. You can then reinstall LXDE by typing in:
    "sudo apt-get install --reinstall lxde".

    Good luck.

  19. TapEC says:

    Thank you so much for your reply Wolverine…In-fact I just right clicked and I had access to terminal and I modified the file again…It’s working fine now…

    Thanks again… You are awesome…

  20. Huw says:

    Hi there.

    Completely new to python and Linux dev, but would it be possible to use your solution with a touch screen display?

Leave a Reply

Your email address will not be published. Required fields are marked *