Forum
>>
Programmazione Python
>>
GUI
>>
[tkinter] drag and drop, ne parliamo?
Pagina: Indietro 1 2
Esegui il login per scrivere una risposta.
Scritto da nuzzopippo |
2024-11-20 17:10:44 - Re: [tkinter] drag and drop, ne parliamo?
|
Ti ringrazio per la Tua disponibilità, prendi tranquillamente tutto il tempo che Ti serve
... comunque, ho il sospetto che il problema derivi dai decoratori "@property" e "@<metodo>.setter" utilizzati nella classe definente l'elemento "drag-drop", apparentemente non vengono ereditati correttamente. Infatti, implementando specifici metodi getter e setter (tipo set_dragable(self, variabile) e get_dragable(self)) le variabili di classe self._dragable e self._dropable vengono variate (prima non avveniva) e si ha conformità nelle valutazioni tra classe ed oggetto. Approfondirò, intanto grazie del Tuo interessamento. Edit: bah ... forse non pongo domande "giuste" nelle mie ricerche, ma non ho trovato informazioni direttamente associate al caso specifico, però ho trovato più volte indicato che "l'incapsulazione delle classi non è completa in python", penso che la problematica da me riscontrata possa ricadere in tale ambito. In effetti, utilizzando i decoratori built-in prima indicati non faccio altro che incapsulare dei metodi di classe in funzioni, forse è possibile che l'ulteriore incapsulamento che avviene utilizzando l'ereditarietà non arrivi a definire tale circostanza. Comunque, evitando i decoratori ed utilizzando metodi diretti per l'impostazione delle proprietà _dragable e _dropable, la funzionalità dello insieme tornano nei criteri da me conosciuti. Pur se esistono varianti possibili da studiarsi (non ultima la definizione di classi-decoratore per i widget) credo che la metodologia a "metodo diretto" raggiunga un sufficiente compromesso tra semplicità ed elasticità, permettendo di svolgere l'intero lavoro (a parte i metodi astratti) all'interno della classe-madre ... Ri-Edit : e, pensandoci un po' e facendo qualche prova class A: def __init__(self, obj): self.obj = obj self._dragable = True self._dropable = True self.obj.dragable = self.dragable @property def dragable(self): return self._dragable @dragable.setter def dragable(self, value): self._dragable = value class B: def __init__(self): self.name = 'Prova' ogg = B() ogg.__dict__ {'name': 'Prova'} toclass = A(ogg) ogg.__dict__ {'name': 'Prova', 'dragable': True} toclass.__dict__ {'obj': <__main__.B object at 0x7a3b07f63710>, '_dragable': True, '_dropable': True} ogg.dragable = False ogg.__dict__ {'name': 'Prova', 'dragable': False} toclass.__dict__ {'obj': <__main__.B object at 0x7a3b07f63710>, '_dragable': True, '_dropable': True} type(toclass.dragable) <class 'bool'> type(ogg.dragable) <class 'bool'>mi sovviene che l'eredità centra ben poco ma entra in gioco una decisa ambiguità nella istruzione self.obj.dragable = self.dragable la quale, ovviamente, va ad assegnare a obj il "valore" restituito dalla dal metodo con decoratore "@property", definendo per esso una nuova proprietà di tipo booleano, il setter non entra mai in gioco. ... mi son sentito un po' stupido, capendolo, il problema, tanto per cambiare ero io --- Ultima modifica di nuzzopippo in data 2024-11-25 09:53:05 --- Fatti non foste a viver come bruti... |
|
Scritto da nuzzopippo |
2024-11-28 09:29:38 - Re: [tkinter] drag and drop, ne parliamo?
|
Dopo aver, credo, compreso ciò che mi lasciava perplesso (e datomi dell'asino) ho ri-adeguato l'implementazione, che ritengo ora corretta, i test effettuati sembrano funzionare bene.
Quanto implementato permette di effettuare il drag & drop di oggetti a piacere tra finestre tkinter di una stessa applicazione, accoppiando widget sorgenti e destinatari per tipologia. I widget vengono incapsulati in implementazioni reali della classe astratta "DragDropElement" e ricevono da essa quattro nuove proprietà che puntano a metodi di istanza che definiscono le capacità di invio/ricezione dati in gioco. Date le 363 visualizzazioni avute dal post, allego, nel caso possa essere utile a qualcuno, i files di codifica della classe e test usati, vi troverete esempi d'uso della tecnica, per operare avrete bisogno anche del file json allegato in precedente post, il tutto presente nella stessa directory. Ritengo adeguatamente conclusa la problematica in oggetto, comunque, se qualcuno riterrà di porle, sarà cosa gradita discutere su osservazioni/domande in merito. Grazie dell'attenzione Fatti non foste a viver come bruti... |
|
Scritto da Daniele aka Palmux |
2024-12-05 12:20:28 - Re: [tkinter] drag and drop, ne parliamo?
|
Prima di tutto ti faccio i miei complimenti, anche se mi occupo di altro, non mi era mai venuta in mente di affrontare una cosa del genere.
Se posso ti farei un paio di domande: A. Perché hai scelto di utilizzare una classe astratta per il supporto al drag and drop, per esempio non poteva essere migliore l'utilizzo di mixin? B. Come garantisci che i dati trascinati e rilasciati siano validi rispetto al tipo specificato?" Comunque ripeto, un gran bel lavoro, bravo. Cya |
|
Scritto da nuzzopippo |
2024-12-05 18:16:25 - Re: [tkinter] drag and drop, ne parliamo?
|
Grazie del complimento, me ne sento lusingato, cercherò di rispondere alle domande
Allora : Ho scelto di utilizzare una classe astratta perché il codice di visualizzazione del "drag" è comune a tutte le possibili implementazioni, ciò che cambia sono i metodi di rilascio e ricezione dei dati, per i quali è reso necessario definire i metodi astratti, rispettivamente, "drag_data" e "drop_data" nelle classi reali. Tal genere di processi mi è facile pianificarli, li conosco e credo che tale mezzo sia utile per far evitare (anche allo scrivente) nei limiti del possibile "mutazioni" di codifica incompatibili tra loro ... le astrazioni sono migliori di "mixin"? Purtroppo al momento non saprei dirlo, è un (anti?)pattern da me ancora non affrontato, posto anche per imparare cose nuove, e credo proprio lo esperimenterò (si tratta di sub-classare più classi contemporaneamente, ho capito giusto? Comunque, come certo hai già rilevato e che preciso per altri lettori, ho adottato una metodologia diametralmente opposta, i widget tkinter non incapsulano assolutamente nulla delle classi reali che effettuano il drag&drop ma sono le istanze a queste ultime che incapsulano i widget, dei quali sfruttano le caratteristiche per funzionare e modificano a loro uso, eventualmente richiedendo possiedano, anche indirettamente, un qualche metodo specifico per il rilascio/acquisizione dei dati, un esempio in tal senso è la classe "DADComuni", di "test.py" che richiede all'oggetto trasmittente i dati il metodo "get_element()" ed all'oggetto ricevente il metodo "set_comune(data)" (forse un po' troppo specifico) ... questo porta alla seconda domanda : è la variabile di istanza "tipe", definita nella classe astratta originale a controllare il tutto, tale controllo è, ovviamente, demandato alla implementazione reale della classe ed è il recettore dei dati che dovrò effettuare il controllo, nella classe DADComuni def drop_data(self, descriptor, data: any) -> None: if not self._dropable: return if descriptor != self.tipe: return self.obj.set_comune(data)Ove il "descriptor" proviene direttamente dalla classe madre, di cui la classe incapsulante un widget origine dei dati è implementazione reale, al rilascio del pulsante del mouse gestito dall'oggetto origine dei dati, che richiama i dati invocando "self.drag_data()" e rilasciandoli alla controparte invocando la proprietà "obj.drop_data(self.tipe, data)" ricevuta quando è stato incapsulato. Il "tipe" delle due istanze della classe reale per origine/ricezione devono essere uguali o il passaggio verrà interrotto ... ovviamente, a tipi uguali corrisponde una stessa tipologia di dati (un dizionario con chiavi conosciute nel caso), non dimentichiamo che parliamo di una stessa applicazione ... i dati possono essere qualsiasi cosa serva, "tipe" può essere definito a piacere in sede di istanza. Ho pensato che una tecnica si fatta sia abbastanza semplice ed elastica per essere adottata in numerosi casi, comunque sono pronto ad imparare come far meglio Ciao e grazie Fatti non foste a viver come bruti... |
Pagina: Indietro 1 2
Esegui il login per scrivere una risposta.