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()