Topic: PILLOW, ImageTk  (Letto 391 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline Gianpatrizio

  • python unicellularis
  • *
  • Post: 49
  • Punti reputazione: 0
    • Mostra profilo
PILLOW, ImageTk
« il: Luglio 26, 2020, 21:57 »
Buongiorno, oggi stavo cercando di realizzare un applicazione dotata di interfaccia grafica che mi facesse visualizzare delle figure all'interno di essa. Googleando davvero poco ho trovato la libreria PIl che faceva esattamente al caso mio ma una volta implementata la classe ImageTk di questo modulo mi sono imbattuto in quest'errore:
Sono riuscito a far visualizzare un'immagine solo quando il codice era stato scritto al livello globale mentre se cerco di visualizzare avemdo scritto il codice al livello locale mi crea solamente l'apposito spazio dedicato alla figura completamente bianco.
Inoltre ho scoperto anche un modo per possiamo dire "fregare" questo bug, ovvero quello di commettere un errore volontario ad esempio NameError e in questo modo effettivamente sono riuscito a visualizzare la figura come sperato, ma il tutto mi sembra un po' strano.
Vi posto il codice per spiegarvi meglio.

img = ImageTk.PhotoImage(Image.open('img.jpg'))
Label(self.root, image=img).pack()
# in questo modo riesco a visualizzare l'immagine con il risultato sperato


def function(self, event):
        img = ImageTk.PhotoImage(Image.open('img.jpg'))
        Label(self.root, image=img).pack()

        # in questo modo visualizzo soltanto lo spazzi dedicato all'immagine


def function(self, event):
        img = ImageTk.PhotoImage(Image.open('img.jpg'))
        Label(self.root, image=img).pack()

        print(d)
        # in questo modo riesco a visualizzare l'immagine con il risultato sperato
        # ma ricevendo NameError non avendo definito la variabile d


Avete qualche idea?
Grazie in anticipo per le risposte.

Offline Gianpatrizio

  • python unicellularis
  • *
  • Post: 49
  • Punti reputazione: 0
    • Mostra profilo
Re:PILLOW, ImageTk
« Risposta #1 il: Luglio 26, 2020, 22:11 »
scusatemi ovviamente vi dovevo dare gli import:



from tkinter import *
from PIL import Image
from PIL import ImageTk

Offline nuzzopippo

  • python neanderthalensis
  • ****
  • Post: 381
  • Punti reputazione: 0
    • Mostra profilo
Re:PILLOW, ImageTk
« Risposta #2 il: Luglio 27, 2020, 07:33 »
...
Sono riuscito a far visualizzare un'immagine solo quando il codice era stato scritto al livello globale mentre se cerco di visualizzare avemdo scritto il codice al livello locale mi crea solamente l'apposito spazio dedicato alla figura completamente bianco.
Inoltre ho scoperto anche un modo per possiamo dire "fregare" questo bug...

Ciao @Gianpatrizio, Ti sei imbattuto in una caratteristica del framework tkinter (ben conosciuta) che ha spiazzato anche me a suo tempo, non è un bug, il fatto è che tkinter non "memorizza" i dati di una eventuale "risorsa" assegnata ad un widget, non dimentichiamo che tkinter è piuttosto "spartano".
La conseguenza è che quando Tu definisci una immagine in una funzione e la assegni ad un widget l'immagine esisterà solo all'interno della funzione, una volta uscita dalla funzione ti troverai il widget, memorizzato quale oggetto assegnato al "frame" della finestra ma l'immagine sarà persa (cerca info sullo "scope" delle variabili) e rimarrà solo lo spazio (vuoto) a lei riservato.

Pertanto, nel Tuo caso, devi giocoforza definire le immagini "da conservare" a livello globale ed utilizzarle come tali, ciò risolverà il Tuo problema.

... ma ... perdonami se approfitto di questo Tuo post per lanciare un messaggio, ma la modalità "imperativa" (Tuo primo stralcio) o la modalità "funzionale" (2° stralcio) mal si prestano a programmare interfacce grafiche, pur essendo paradigmi ampiamente utilizzati per piccoli esempi mirati deviano gli utenti dalla "giusta" modalità da adottare per affrontare l'argomento "GUI", ossia la programmazione ad oggetti, condita da concetti sulla programmazione ad eventi ... intendiamoci, anche senza utilizzare la OOP qualcosa si può fare, centuplicando la fatica però, ed annegando in un mare di complicazioni.

Certo, la programmazione ad oggetti non è una barzelletta, ma è opportuno conoscerla se si voglio programmare interfacce utente, senza non si va da nessuna parte.
Se non la si conosce, un primo approccio lo si può avere col tutorial e guardando in giro per trovare qualche esempio d'uso con tkinter ... nel mio piccolo un esempio (tutt'altro che "perfetto") lo ho anche postato in questo forum, ad uso degli iniziandi come me (che troppo spesso vedo utilizzare il paradigma funzionale).
Naturalmente, non è, poi, che sia sufficiente fermarsi agli esempi preliminari, la materia è complessa e bisogna approfondire svariati aspetti, tanto circa la OOP, quanto sul framework utilizzato per giungere agli svariati pattern di design applicativo, se si vuol "produrre" qualcosa di "sostanzioso".

Offline Gianpatrizio

  • python unicellularis
  • *
  • Post: 49
  • Punti reputazione: 0
    • Mostra profilo
Re:PILLOW, ImageTk
« Risposta #3 il: Agosto 02, 2020, 22:55 »
Buongiorno, scusami per il ritardo di questa risposta. Grazie invece per la sua risposta molto precisa e soprattutto che mi ha fatto capire sia il problema e anche che non vale la pena continuare con questo framework per la sua ambiguità, perciò ho deciso che passerò a kivy. Ti ringrazio ancora per la risposta

Offline RicPol

  • python sapiens sapiens
  • ******
  • Post: 3.154
  • Punti reputazione: 9
    • Mostra profilo
Re:PILLOW, ImageTk
« Risposta #4 il: Agosto 03, 2020, 12:43 »
Uhm... beh attenzione però. Questo non è un problema di Tkinter e/o di Pillow... anzi direi che è una cosa *giusta* che fa PIllow. Se definisci un nome in una funzione, quel nome sparisce fuori dallo scope della funzione. Se a quel nome c'è "attaccato" qualcosa che ti serve, quel qualcosa sparisce e basta (i dettagli sono complessi, ma poco importa). Non è soltanto un'immagine, avresti lo stesso "problema" con un file aperto, per dire.

Questo è un "problema" che avresti con Kivy o con qualunque cosa puoi inventarti. Dipende dallo scoping dei nomi, ed è uno degli aspetti più di base in Python. Il problema si risolve usando le classi, che sia Pillow, Tkinter, Kivy o quel che vuoi.

Povero Tkinter, con tutti i suoi guai, anche questa croce addosso non gliela butterei proprio...

Offline nuzzopippo

  • python neanderthalensis
  • ****
  • Post: 381
  • Punti reputazione: 0
    • Mostra profilo
Re:PILLOW, ImageTk
« Risposta #5 il: Agosto 03, 2020, 13:40 »
... che mi ha fatto capire sia il problema e anche che non vale la pena continuare con questo framework per la sua ambiguità ...

Spero che non sia qualcosa da me scritto che Ti abbia dato l'impressione di "ambiguità" da parte di tkinter, perché non è ambiguo, semplicemente funziona in quel modo : non memorizza di "sua iniziativa" eventuali immagini assegnate a widget e bisogna provvedere che esse siano "raggiungibili" dall'oggetto che le deve esporre.
... niente di astruso o di "strano" fondamentalmente, il fatto che a suo tempo abbia trovato, a mia volta, spiazzante la circostanza era dovuto alla "abitudine" di utilizzare altri framework che provvedevano di loro a tali "dettagli", nascondendo la necessità di dette operazioni.

Per altro, pur non conoscendo Kivy, non è che si possa evitare la OOP o di acquisire concetti circa la "programmazione ad eventi", fondamentali nel programmare le interfacce grafiche (p.e., @Ric stesso, nel suo libro, ha dedicato un rilevante numero di capitoli già ai soli eventi), non è che framework più avanzati di tkinter te ne dispensino dal conoscerle ... anzi, magari incrementaranno un bel po' il materiale documentale sul framework stesso da studiare (cosa sempre necessaria), essendo più "completi/articolati".

Offline Gianpatrizio

  • python unicellularis
  • *
  • Post: 49
  • Punti reputazione: 0
    • Mostra profilo
Re:PILLOW, ImageTk
« Risposta #6 il: Agosto 09, 2020, 22:20 »
Buongiorno ancora, chiedo scusa per la mia ignoranza in materia, grazie per avermi fatto capire e inoltre chiedo scusa a tkinter per avergli aggiunto anche questa crocetta. Vi ringrazzio per le risposte date e per avermi aiutato sempre (anche in altri topic) a risolvere un problema.