Topic: [Risolto] layout "grid", classi e persistenza oggetti  (Letto 61 volte)

0 Utenti e 1 Visitatore stanno visualizzando questo topic.

Offline nuzzopippo

  • python unicellularis
  • *
  • Post: 38
  • Punti reputazione: 0
    • Mostra profilo
I miei saluti a Voi :)

Intrigato da una idea reperita altrove, mi sono avventurato a costruire una specie di "controllo" composito con tkinter che provvede ad esporre righe di immagini miniaturizzate e didascalie. Nel costruirlo mi sono anche scritto una serie di test per verificare la "resa" di quanto fatto in vali punti di sviluppo.

Ho implementato una versione utilizzante il metodo "pack()" costituita da due classi, una definente una singola "riga" dati (immagine/didascalia) mentre la seconda visualizza un insieme di tali righe e fornisce i metodi per la navigazione tra i dati. Tale versione è funzionante.

Insoddisfatto da alcune questioni di resa grafica degli automatismi di pack() ho provato a definire una variante dell'oggetto utilizzante il metodo "grid()" ed incappando già alla definizione della singola riga in una serie di problematiche che, dopo un po' di ricerche e prove, credo si individuino in una mancata persistenza degli oggetti invocati dal codice per una qualche peculiarità del metodo grid() che non mi riesce di individuare, probabilmente per la mia ignoranza dell'inglese (enorme palla al mio piede)

Appresso, esemplifico il codice, funzionante, del costruttore di una riga, versione utilizzante pack(), e della sua invocazione, con inseriti del print di debug.

costruttore :

class FRMTumbnail(tk.Frame):
    '''Pannello per singola miniatura (tumbnail) con descrizione.'''
    def __init__(self, master, mater, imgdim=60):
        self.mater = mater
        self.f_img = ''
        super().__init__(master)
        self.dim_tmb = imgdim
        self._curr_img = None
        self.indice = None
        self.default_bc = self.cget('bg')
        self.configure(relief='sunken', border=2, padx=2, pady=2)
        self.cnv_tmb = tk.Canvas(self,
                                 width=self.dim_tmb,
                                 height=self.dim_tmb,
                                 bg='#ffffc0',
                                 relief='raised',
                                 border=2
                              )
        self.cnv_tmb.pack(side='left')
        print('self.cnv_tmb è : ', self.cnv_tmb)
        print(self.cnv_tmb)
        self.cnv_tmb.bind('<Button-1>', self._scelto)
        f = tk.Frame(self, height=self.dim_tmb+4)
        f.pack(side='left', expand=True, fill='x')
        #f.pack_propagate(0)
        self.lbl_dida = tk.Label(f,
                                text='..'*10,
                                justify='left',
                                )
        self.lbl_dida.pack(expand=True, fill='both')
        print('self.lbl_dida è : ', self.lbl_dida)
        self.lbl_dida.bind('<Button-1>', self._scelto)


invocazione:

class GUI_01(tk.Tk):
    ''' Finestra principale test 01 : singola riga. '''

    def __init__(self, fnome='', dim=60):
        super().__init__()
        self.f_nome = fnome
        self.title('Test 01')
        sfondo = tk.Frame()
        sfondo.pack(fill='both')
        self.f = fd.FRMTumbnail(sfondo, None, dim)
        self.f.pack(fill='x')
        print('self.f è : ', self.f)
        f2 = tk.Frame(sfondo, relief='sunken', padx=2, pady=2)
        f2.pack(fill='x')
        btn = tk.Button(f2, text='Mostra immagine', command=self.mostra)
        btn.pack()
        self.minsize(300, self.winfo_reqheight())
        # self.update()
        centraFinestra(self)
   
    def mostra(self):
        self.f.set_fileimg(self.f_nome)
        self.f.set_dida("un po' di testo a caso")


Ed ora analoghi costruttore ed invocazione con grid(), si noti il commento dei "bind()", con ciò la riga viene visualizzata correttamente ma è inutilizzabile.

Costruttore:

class GriFRMTmb(tk.Frame):
    '''Pannello per singola miniatura (tumbnail) con descrizione.'''
    def __init__(self, master, mater, imgdim=60):
        self.mater = mater
        self.f_img = ''
        super().__init__(master)
        self.dim_tmb = imgdim
        self._curr_img = None
        self.indice = None
        self.default_bc = self.cget('bg')
        self.configure(relief='sunken', border=2, padx=2, pady=2)
        self.cnv_tmb = tk.Canvas(self,
                                 width=self.dim_tmb,
                                 height=self.dim_tmb,
                                 bg='#ffffc0',
                                 relief='raised',
                                 border=2
                                 ).grid(row=0, column=0, sticky='w')
        print('self.cnv_tmb è : ', self.cnv_tmb)
        #self.cnv_tmb.bind('<Button-1>', self._scelto)
        self.lbl_dida = tk.Label(self,
                                text='...',
                                justify='left',
                                ).grid(row=0, column=1, sticky='nsew')
        #self.lbl_dida.bind('<Button-1>', self._scelto)
        print('self.lbl_dida è : ', self.lbl_dida)
        self.columnconfigure(1, weight=1)


invocazione:

class GUI_01_G(tk.Tk):
    ''' Finestra principale test 01 - variante layout grid : singola riga. '''

    def __init__(self, fnome='', dim=60):
        super().__init__()
        self.f_nome = fnome
        self.title('Test 01-Grid')
        sfondo = tk.Frame().grid(sticky='nsew')
        self.f = fd.GriFRMTmb(sfondo, None, dim).grid(row=0,
                                                        padx=2,
                                                        pady=2,
                                                        sticky='ew'
                                                        )
        print('self.f è : ', self.f)
        btn = tk.Button(sfondo,
                        text='Mostra immagine',
                        command=self.mostra).grid(row=1,
                                                  padx=2,
                                                  pady=2,
                                                  sticky='nsew'
                                                  )
        self.columnconfigure(0, minsize=300, weight=1)
        self.update()
        centraFinestra(self)
   
    def mostra(self):
        self.f.set_fileimg(self.f_nome)
        self.f.set_dida("un po' di testo a caso")

(mi si perdoni l'incompleta aderenza alla Pep8)

e qui segue l'output del test effettuato per le due versioni :

NzP:~$ python3 test.py 1 risorse/01.jpg 60
self.cnv_tmb è :  .!frame.!frmtumbnail.!canvas
.!frame.!frmtumbnail.!canvas
self.lbl_dida è :  .!frame.!frmtumbnail.!frame.!label
self.f è :  .!frame.!frmtumbnail
NzP:~$ python3 test.py 5 risorse/01.jpg 60
self.cnv_tmb è :  None
self.lbl_dida è :  None
self.f è :  None
NzP:~$


Mi sembra evidente che con l'utilizzo di pack() le variabili di istanza nelle classi vengono correttamente create mentre utilizzando grid() invece no
 ... malgrado abbia cercato nella docs ed in rete mi son fermato qui, non mi riesce di capirne il perché e come rimediare, qualcuno di Voi conosce il problema e può darmi indicazioni in merito?

Scusate la lunghezza del post, non mi riuscirebbe di essere chiaro, altrimenti.
« Ultima modifica: Aprile 16, 2019, 06:24 da nuzzopippo »

Offline nuzzopippo

  • python unicellularis
  • *
  • Post: 38
  • Punti reputazione: 0
    • Mostra profilo
Re:layout "grid", classi e persistenza oggetti
« Risposta #1 il: Aprile 16, 2019, 06:23 »
Risolto, il problema era nella notazione "unica" utilizzata per definire il widget e la sua posizione nella griglia : non da errore ma non restituisce l'oggetto creato. Bisogna, quindi, tener separate le definizioni ed i posizionamenti.

Mi hanno "fregato" la mancanza di eccezioni e "vecchie" esperienze.

Per improbabili interessati :

Notazione accettata ma inutilizzabile :

        self.lbl_dida = tk.Label(self,
                                text='...',
                                justify='left',
                                ).grid(row=0, column=1, sticky='nsew')


Notazione funzionale :

        self.lbl_dida = tk.Label(self,
                                text='...',
                                justify='left',
                                )
...
        self.lbl_dida.grid(row=0, column=1, sticky='nsew')


Mi si perdoni se Vi ho fatto perdere tempo a leggere.
« Ultima modifica: Aprile 16, 2019, 06:28 da nuzzopippo »