You are not logged in.

#1 2008-04-13 11:13:42

gunnihinn
Member
From: Torreón, Mexico
Registered: 2007-10-28
Posts: 81

Launching programs from python and ncurses

I've made a little menu launcher with python and ncurses. It works most of the time, but occationally it does nothing when I select a program to launch.

This is how it works:
1. A keyboard shortcut launches an xterm window that runs the program.
2. I select some program, which is launched via this command:
os.system("nohup " + "program_name" + "> /dev/null &")
3. ncurses cleans up and python calls "sys.exit()"

The whole idea with nohup is that the xterm window will close after I select an application, but the application will still start normally (this was a bit of a problem). This works most of the time, but sometimes nothing happens (it never works the first time I try launching a program after starting the computer, the other times are more random).

So, has anyone got an idea of what's going on or a better solution than the nohup hack?

The whole code for the menu launcher is below. It's quite hackish, but then again it was just meant for me. The file's called "curmenu.py", and I launch it with an xbindkeys shortcut that runs "xterm -e curmenu.py".

#!/usr/bin/env python

import os,sys
import curses

##
## Variables one might like to configure
##

programs = ["Sonata", "sonata", "Ncmpc", "xterm -e ncmpc", "Emacs", "emacs", "Firefox", "swiftfox",\
                "Pidgin", "pidgin", "Screen", "xterm -e screen", "Thunar", "thunar", \
                "Gimp", "gimp", "Vlc", "vlc", "Skype", "skype"]
highlight = 3 
on_screen = 7

##
## Functions
##

# Gets a list of strings, figures out the middle one
# and highlights it. Draws strings on screen.
def drawStrings(strings):
    length = len(strings)
    middle = (length - 1)/2
    for num in range(length):
        addString(strings[num], middle, num, length)
    stdscr.refresh()

def addString(string, middle, iter_step, iter_max):
    if iter_step < iter_max:
        string = string + "\n"
    if iter_step == middle:
        stdscr.addstr(iter_step + 1, 1, string, curses.A_REVERSE)
    else:
        stdscr.addstr(iter_step + 1, 1, string)

# Returns a list of strings to draw on screen. The
# strings chosen are centered around position.
def listStrings(strings, position, on_screen):
    length = len(strings)
    low = (on_screen - 1)/2
    start = position - low
    str = []
    for num in range(start, start + on_screen):
        str = str + [strings[num % length]]
    return str        

##
## Start doing stuff
##

names = programs[::2]
longest = max(map(lambda x: len(x), names))

# Start our screen
stdscr=curses.initscr()

# Enable noecho and keyboard input
curses.curs_set(0)
curses.noecho()
curses.cbreak()
stdscr.keypad(1)

# Display strings
drawStrings(listStrings(names, highlight, on_screen))

# Wait for response
num_progs = len(names)
low = (on_screen - 1)/2
while 1:
    c = stdscr.getch()
    if c == ord("q") or c == 27:  # 27 = "Escape"
        break
    elif c == curses.KEY_DOWN:
        highlight = (highlight + 1)%num_progs
    elif c == curses.KEY_UP:
        highlight = (highlight - 1)%num_progs
    elif c == curses.KEY_NPAGE:
        highlight = (highlight + low)%num_progs
    elif c == curses.KEY_PPAGE:
        highlight = (highlight - low)%num_progs
    elif c == 10:   # actually "Enter", but hey
        os.system("nohup " + programs[2*highlight + 1] + "> /dev/null &")
        break
    drawStrings(listStrings(names, highlight, on_screen))

# Close the program
curses.nocbreak()
stdscr.keypad(0)
curses.echo()
curses.endwin()
sys.exit()

Offline

#2 2008-04-13 11:21:31

iphitus
Forum Fellow
From: Melbourne, Australia
Registered: 2004-10-09
Posts: 4,927

Re: Launching programs from python and ncurses

Try:
http://docs.python.org/lib/module-subprocess.html

Should let you fork programs off into the background.

Offline

Board footer

Powered by FluxBB