memos 2.0, con drag’n’drop

Premessa
Dr. prof osserva che l’app memos del post precedente potrebbe essere completato, ad esempio inserendoci il drag & drop. Vero. Ogni osservazione del dr. prof — o di qualunque altro lettore del blog — è benvenuta e, nei limiti delle mie capacità, degna di essere esaudita, per quanto possibile. Mica come qualche studente, per esempio:

Il package wx ha tutto quello che serve per fil drag & drop, ecco un esempio minimo

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx

class FileDrop(wx.FileDropTarget):
	def __init__(self, window):

		wx.FileDropTarget.__init__(self)
		self.window = MyFrame

	def OnDropFiles(self, x, y, filenames):
		for c in filenames:
			print c
		print

class MyFrame(wx.Frame):
	def __init__(self, parent, id):
		wx.Frame.__init__(self, parent, id,
						  size = (160, 120), title = "Drag & Drop",
						  style = wx.wx.CAPTION | wx.CLOSE_BOX)

		#posizione window
		self.SetPosition(wx.Point(200, 50))

		#ddrop
		dt = FileDrop(self)
		self.SetDropTarget(dt)

class MyApp(wx.App):
	def OnInit(self):
		frame = MyFrame(None, -1)
		frame.Show(True)
		self.SetTopWindow(frame)
		return True

app = MyApp(redirect = 0)
app.MainLoop()

Ulteriori informazioni abbondano sul web, per esempio qui.

È immediato applicarlo, tanto per entrare in argomento, al caso del collegamento ricavato dal trascinamento dell’icona dal browser accennato nel post precedente. Lo script, solo per Linux, per Windows richiederebbe alcune semplici modifiche:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import wx, os

class FileDrop(wx.FileDropTarget):
	def __init__(self, window):

		wx.FileDropTarget.__init__(self)
		self.window = MyFrame

	def OnDropFiles(self, x, y, filenames):
		for c in filenames:
			url = ''
			if os.path.splitext(c)[1] == '.desktop':
				f = open(c, 'r')
				txt = f.readlines()
				f.close()
				print txt
				for riga in txt:
					riga = riga.rstrip('\n')
					print riga
					if riga[:4] == 'URL=':
						url = riga[4:]
						break
			else:
				f = open(c, 'r')
				txt = f.readlines()
				f.close()
				print txt
				for riga in txt:
					riga = riga.rstrip('\n')
					print riga
					if riga[:4] == 'http':
						url = riga
						break
			if len(url) > 0:
				cmd = 'xdg-open "%s"' %url
				print cmd
				os.system(cmd)
		print

class MyFrame(wx.Frame):
	def __init__(self, parent, id):
		wx.Frame.__init__(self, parent, id,
						  size = (160, 120), title = "Drag & Drop",
						  style = wx.wx.CAPTION | wx.CLOSE_BOX)

		#posizione window
		self.SetPosition(wx.Point(200, 50))

		#ddrop
		dt = FileDrop(self)
		self.SetDropTarget(dt)

class MyApp(wx.App):
	def OnInit(self):
		frame = MyFrame(None, -1)
		frame.Show(True)
		self.SetTopWindow(frame)
		return True

app = MyApp(redirect = 0)
app.MainLoop()

funziona anche droppandogli un file di testo contenente un URL, come questo

https://okpanico.wordpress.com/

Il passo successivo è verificare se si possono cambiare al volo le dimensioni della finestra dell’app e aggiungere pulsanti: sembra immediato, ecco

#!/usr/bin/env python
# -*- coding: utf-8 -*-

import wx, os, sys, datetime

class MyFrame(wx.Frame):
	def __init__(self, parent, id):
		global aggiunti
		aggiunti = 0
		wx.Frame.__init__(self, parent, id, size = (120, 120),
				pos = (200, 200), title = "change size")
				#style = wx.CAPTION | wx.CLOSE_BOX)

		self.pn = wx.Panel(id = 1, name='pn', parent = self)
		self.pn.SetBackgroundColour('yellow')

		txt = '%s' %datetime.datetime.now()
		self.label1 = wx.StaticText(self.pn, label = txt,
                                                    pos = (10, 8))
		self.cresci = wx.Button(self.pn, label="cresci",
                            pos = (10, 30),	size = wx.Size(100, 24))
		self.cala = wx.Button(self.pn, label="cala", pos = (10, 60),
											size = wx.Size(100, 24))
		self.adduno = wx.Button(self.pn, label="add", pos = (10, 90),
											size = wx.Size(100, 24))
		self.cresci.Bind(wx.EVT_BUTTON, self.on_cresci)
		self.cala.Bind(wx.EVT_BUTTON, self.on_cala)
		self.adduno.Bind(wx.EVT_BUTTON, self.on_add)

	def on_cresci(self, event):
		sz = self.GetSize()
		self.SetSize((sz[0] + 20, sz[1] + 20))
		self.label1.SetLabel('%s' %datetime.datetime.now())

	def on_cala(self, event):
		sz = self.GetSize()
		self.SetSize((sz[0] - 20, sz[1] - 20))
		self.label1.SetLabel('%s' %datetime.datetime.now())

	def on_add(self, event):
		global aggiunti
		aggiunti += 1
		self.adduno = wx.Button(self.pn, label="nguh! " + str(aggiunti),
							pos = (10, 90 + aggiunti * 30),
							size = wx.Size(100, 24))
		self.adduno.Bind(wx.EVT_BUTTON, self.on_chlabel)

	def on_chlabel(self, event):
		self.label1.SetLabel('eccomi')

class MyApp(wx.App):
	def OnInit(self):
		frame = MyFrame(None, -1)
		frame.Show(True)
		self.SetTopWindow(frame)
		return True

app = MyApp()
app.MainLoop()

semplice vero? 😀

memos 2.0 — con drag & drop
Bene, abbiamo tutti gli elementi per affrontare il compito di completare memos, basta assemblare i prototipi precedenti e il gioco è fatto 🙂
E qui sono capitato dentro un bug (mio o di wx per Linux?) che mi ha fatto quasi prendere dal panico, 42 volte 😦
I problemi sono sul ridimensionamento della finestra, la sua posizione varia e tende a sfuggire verso l’alto 😦
La soluzione finale è in qualche misura non bella, proprio quando Knulp posta questa roba in ‘tagliano e inglisc

In ogni caso ecco il risultato:

#!/usr/bin/python
# -*- coding: utf-8 -*-

import os, sys, platform, wx

flist = [] #lista dei memo
OS = platform.system() #Linux | Windows
BOFS = 100 #offest per i pulsanti

def get_flist():
	global flist, home, memofile

	NL = '\n'
	home = os.path.dirname(os.path.abspath(sys.argv[0]))
	memofile = os.path.join(home, 'memos-list.txt')
	if os.path.isfile(memofile):
		fdat = open(memofile, 'r')
		mdata = fdat.readlines()
		fdat.close()
		for c in mdata:
			r = c.strip(NL)
			r = r.strip()
			if len(r) > 0 and r[0] != '#':
				if os.path.isfile(r):
					flist.append(r)
	else:
		fdat = open(memofile, 'w')
		fdat.close()

	#alla fine aggiunge il suo file di configurazione
	flist.append(memofile)
	return flist

class FileDrop(wx.FileDropTarget):
	def __init__(self, window):

		wx.FileDropTarget.__init__(self)
		self.window = Slate

	def OnDropFiles(self, x, y, filenames):
		global slate_self
		global m2add

		for m2add in filenames:
			if os.path.isfile(m2add):
				abs_pos = slate_self.GetPosition()
				Slate.addbtn(slate_self)

class Slate(wx.Frame):
	def __init__(self, parent, id, title):
		global slate_self, nbtn, memofile
		global box, boy, woffset
		global abs_pos

		slate_self = self
		flist = get_flist()
		nbtn = len(flist)

		if OS == 'Linux':
			woffset = 0
			box = 10
			boy = 10
		elif OS == 'Windows':
			woffset = 24
			box = 6
			boy = 6
		stile = wx.SYSTEM_MENU | \
				wx.CAPTION | wx.CLOSE_BOX | \
				wx.FULL_REPAINT_ON_RESIZE
		hframe = 20 + nbtn * 40 + woffset + 36
		wx.Frame.__init__(self, parent, id, title,
					size=(220, hframe),	style = stile)
		self.pn = wx.Panel(id = 1, name = 'pn', parent = self)
		self.pn.SetBackgroundColour('green')
		#i bottoni
		for c in range(nbtn):
			y = boy + c * 40
			button = wx.Button(self.pn, id = BOFS + c,
					pos = (box, y), size = wx.Size(200, 40))
			button.SetLabel(os.path.basename(flist[c]))
			button.Bind(wx.EVT_BUTTON, self.on_button)
		#il file dell'elenco ha background rossiccio
		button.SetBackgroundColour('#DEBABA')
		txt = 'puoi aggiungere file memo\ntrascinandoli qui'
		self.hint = wx.StaticText(self.pn, label = txt,
										pos = (10, y + 45))

		abs_pos = (20, 50)
		self.SetPosition(abs_pos)
		self.Show(True)

		#ddrop
		dt = FileDrop(self)
		self.SetDropTarget(dt)

	def on_button(self, event):
		global home
		quale = event.GetId()
		if OS == 'Linux':
			os.system('xdg-open "%s"' %flist[quale - BOFS])
		elif OS == 'Windows':
			sh = os.path.join(home, 'shex.exe')
			os.system('%s "%s"' %(sh, flist[quale - BOFS]))

	def addbtn(self):
		global slate_self, nbtn, memofile
		global box, boy, woffset
		global abs_pos
		global m2add

		nbtn += 1
		y = boy + (nbtn -1) * 40
		button = wx.Button(self.pn, id = BOFS + nbtn - 1,
					pos = (box, y), size = wx.Size(200, 40))
		button.SetLabel(os.path.basename(m2add))
		button.Bind(wx.EVT_BUTTON, self.on_button)
		flist.append(m2add)
		ml = open(memofile, 'a')
		ml.write('\n%s' %m2add)
		ml.close()

		sz = self.GetSize()
		self.Hide()
		if OS == 'Linux':
			self.SetSize((sz[0], sz[1] + 40))
		else:
			self.hint.Hide()
			hframe = 20 + nbtn * 40 + woffset
			self.SetSize((sz[0], hframe))
		self.Refresh()
		self.Update()
		self.Show(True)
		self.SetPosition(abs_pos)

app = wx.App() #redirect = 1, filename = 'dump.txt')
Slate(None, -1, 'memos')
app.MainLoop()

Diversamente dalla versione precedente il file memos-list.txt contenete la lista dei memo se non c’è viene creato vuoto. Nelle aggiunte, mediante droppaggio dei memo sulla finestra dell’app viene effettutato il controllo che l’oggetto droppato sia un file (o un link a un file), non viene effettuato il controllo se è un doppione di uno già inserito. Anche le cancellazioni andranno fatte a mano.

Conclusioni
Per adesso questo è quanto; conoscete Andrea Gavana e il suo AGW? Se no leggete il prossimo post.
Inoltre ci sono novità (spaziali) anche in altri dipartimenti: http://runrevwidgets.com/applications4/
Buon lavoro ale870 😀
Sono in ritardo, oggi è gelato anche il tubo dell’acqua, salta la corrente elettrica, Telecom ce l’ha con me, Pico vuole indagare sul cane che è passato ieri per vedere se gli ha rovinato i segni che delimitano il suo territorio, davvero ampio, richiederà diverse passeggiate.

Posta un commento o usa questo indirizzo per il trackback.

Commenti

  • glipari  Il 20 dicembre 2010 alle 12:54

    Grandissimo! 🙂

    (mannaggia, ‘sto incasinato con queste proposte di progetto dalla mattina alla sera, e non posso scrivere sui miei amati blog… ma prima o poi torno, eh!)

    • juhan  Il 20 dicembre 2010 alle 12:57

      grassie 😀
      & buon lavoro, adesso finisce anche la scuola (forse per sempre).

Trackback

  • oook – gestore documenti « Ok, panico su 3 gennaio 2011 alle 14:52

    […] Un po’ di tempo fa ho creato uno script per rintracciare velocemente i memos, le note che uno segna sui pezzi di carta, il retro delle buste (delle fatture da pagare, ricevo solo quel genere di posta) e poi butta via e le meravigliose idee sono perse per sempre nel gorgo del tempo Sì mi sono lasciato trasportare dalla foga e da un improvvisa e dubbia vena poetica, comunque i post a cui mi riferivo sono qui e qui. […]

Rispondi

Inserisci i tuoi dati qui sotto o clicca su un'icona per effettuare l'accesso:

Logo di WordPress.com

Stai commentando usando il tuo account WordPress.com. Chiudi sessione /  Modifica )

Google photo

Stai commentando usando il tuo account Google. Chiudi sessione /  Modifica )

Foto Twitter

Stai commentando usando il tuo account Twitter. Chiudi sessione /  Modifica )

Foto di Facebook

Stai commentando usando il tuo account Facebook. Chiudi sessione /  Modifica )

Connessione a %s...

Questo sito utilizza Akismet per ridurre lo spam. Scopri come vengono elaborati i dati derivati dai commenti.

%d blogger hanno fatto clic su Mi Piace per questo: