S60 – Un menù per i tuoi script in Python
Questa è la mia prima applicazione sviluppata utilizzando le classi in Python.
La sua funzione è molto semplice: una volta avviata, mostra un menù personalizzabile che permette l’avvio di uno script Python con la semplice pressione di un tasto.
È possibile personalizzare uno script per ogni tasto della tastiera, da 1 a #. Risulta molto utile se utilizzate spesso degli script in Python, dato che attualmente, per avviare uno script, bisogna utilizzare la shell di Python e cercare ogni volta lo script all’interno del file browser.
Con PyMenu basterà la semplice pressione di un tasto per avviare i vostri script.
Ne ho creato una versione .sis in modo da poterla mettere sul desktop o associare ad un tasto di funzione rapida.
L’id dell’applicazione è:
0xE263CB53
Segue il codice sorgente del programma.
import os
import e32
import e32dbm
import appuifw
import key_codes as key
class PyMenu:
def __init__(self):
# System directory - Config file
self.SYS_DIR = u'C:\\data\\PyMenu\\'
self.CONFIG_DIR = self.SYS_DIR + u'key_setting'
if not os.path.isdir(self.SYS_DIR):
os.mkdir(self.SYS_DIR)
self.cfg = e32dbm.open(self.CONFIG_DIR, 'c')
#
# Keyboard
self.set_keyboard = False # If true, key_handler set the key
self.keyN = list(u'123456789*0#')
self.keyV = [key.EKey1, key.EKey2, key.EKey3, key.EKey4,
key.EKey5, key.EKey6, key.EKey7, key.EKey8,
key.EKey9, key.EKeyStar, key.EKey0, key.EScancodeHash]
#
# Application body
self.c = appuifw.Canvas(event_callback=self.key_handler,
redraw_callback=self.draw)
self.lock = e32.Ao_lock()
def draw(self, r=None):
"""Draw icons and text"""
# Graphic size
W, H = self.c.size
WI = W / 3 # Icons width
HI = H / 4 # Icons height
ML = (W - 3 * WI) / 3 # Margin left
MT = (H - 4 * HI) / 4 + 1 # Margin top
# Graphic color - font
BORDER = (220, 220, 220)
ICONS = (157, 190, 217)
NUMBERS = (200, 0, 0)
FONT_ICONS = ('normal', 12)
FONT_NUM = ('normal', 18)
# Draw keyboard
self.c.clear()
index = 0 # Index of keyboard
for row in range(4):
for col in range(3):
# Db requires unicode key value
key = unicode(self.keyV[index])
if key in self.cfg.keys():
script = self.cfg[key]
# Title is just filename without ext
title = os.path.basename(script)
title = os.path.splitext(title)[0].decode('utf-8')
else:
# No title
title = u'-'
# Icon rectangle
icon = (col*WI, row*HI, col*WI + WI, row*HI + HI)
self.c.rectangle(icon, fill=ICONS, outline=BORDER)
# Text alignment
length, height = self.c.measure_text(title, font=FONT_ICONS)[-2:]
description = (icon[0] + WI/2 - length/2, icon[1] + HI/2 - 5)
key_number = (icon[0] + WI/2 - 3, icon[1] + HI/2 + 20)
self.c.text(description, title, font=FONT_ICONS)
self.c.text(key_number,
self.keyN[index],
font=FONT_NUM,
fill=NUMBERS)
index += 1
def list_dir(self, path):
"""List a directory and return the selected file"""
# Previous directory
if path and path.endswith(r'\..'):
# Show memories
if path in [r'C:\\..', r'E:\\..', r'C:\..', r'E:\..']:
files = ['C:', 'E:']
path = ''
# Show previous directory
else:
path = os.path.split(os.path.split(path)[0])[0]
# List the dir
files = os.listdir(path)
files.sort()
files[0:0] = [r'..']
# List the dir
elif path:
files = os.listdir(path)
files.sort()
files[0:0] = [r'..']
ufiles = [i.decode('utf-8') for i in files] # appuifw require unicode
try:
selected = files[appuifw.selection_list(ufiles)]
except TypeError:
# No file selected
return None
# If you select E: it mustn't return \E:!
if path:
return '\\'.join([path, selected])
else:
return selected
def select_file(self, def_dir):
"""Select a script"""
path = def_dir # Default directory
temp = self.list_dir(path)
while True:
if temp and os.path.isfile(temp):
return temp
elif temp and os.path.isdir(temp):
temp = self.list_dir(temp)
else:
return None
def bind_key(self, n):
"""Bind a key to a script"""
appuifw.app.screen = 'normal'
script = self.select_file(r'C:\python')
if script:
self.cfg[unicode(n)] = script.decode('utf-8')
appuifw.note(u'Script bound to "%s" key.' %
self.keyN[self.keyV.index(n)], 'conf')
else:
del self.cfg[unicode(n)]
appuifw.note(u'The "%s" key was deleted.' %
self.keyN[self.keyV.index(n)], 'conf')
appuifw.app.screen = 'large'
def key_set(self):
"""Set global set_keyboard to set keyboard"""
self.set_keyboard = True
appuifw.note(u'Select a key', 'info')
def key_handler(self, event):
"""Handle the keyboard"""
press = event['scancode']
if press in self.keyV:
if self.set_keyboard:
self.bind_key(int(press))
self.set_keyboard = False
else:
if unicode(press) in self.cfg.keys():
namespace = {'__builtins__': __builtins__, '__name__': '__main__'}
try:
execfile(self.cfg[unicode(press)], namespace)
except Exception, error:
appuifw.note(u'Error occurred!', 'error')
appuifw.note(unicode(error), 'error')
else:
n = appuifw.query(u'The "%s" key is not bound, bind now?' %
self.keyN[self.keyV.index(press)], 'query')
if n:
self.bind_key(int(press))
def quit(self):
try:
self.cfg.close()
except RuntimeError:
pass
self.lock.signal()
appuifw.app.set_exit()
def run(self):
appuifw.app.screen = 'large'
appuifw.app.orientation = 'portrait'
appuifw.app.menu = [(u'Bind key', self.key_set)]
appuifw.app.body = self.c
appuifw.app.exit_key_handler = self.quit
self.lock.wait()
app = PyMenu()
app.run()