dal 2015 - visita n. 885
TkInter
TkInter

 

4. Condividere Informazioni


4.1. Definizione del problema

Esistono delle situazioni nelle quali si vuole che un gestore di eventi esegua qualche compito per poi condividerne i risultati con altri gestori di eventi all'interno dello stesso programma. Uno schema tipico è quello di un'applicazione con due insiemi di widget: il primo prepara o seleziona alcune informazioni, l'altro le usa per qualche scopo. Sono possibili vari scenari tutti caratterizzati dalla necessità di riutilizzare le informazioni prodotte in una prima fase del programma:

Poichè ogni gestore di eventi è una funzione separata dalle altre, esso dispone di variabili locali sue proprie che non può condividere con altre funzioni di gestione degli eventi, e neppure con successive invocazioni di se stesso. Per potere condividere delle informazioni con altri gestori, le variabili da utilizzare come contenitori non possono essere locali alla funzione di gestione degli eventi, ma devono necessariamente essere conservate all'esterno della funzione stessa.




4.2. Variabili Globali

Una tecnica per ottenere lo scopo è rendere globali le variabili da condividere. Per esempio ogni gestore che abbia necessità di accedere alle variabili var_A e var_B può inserire all'inizio la seguente istruzione:

global var_A, var_B

avendo avuto cura di inizializzare tali variabili nel programma principale.
Tuttavia l'uso delle variabili globali introduce la possibilità di commettere errori, ed inoltre é considerato una tecnica di programmazione poco raffinata. Si rifletta infatti sulla sorte della variabile globale x nel seguente programma di prova.

#!/usr/bin/env python
# -*- coding: iso8859-15 -*-
# global.py - versione 1.0

x = 1                                      # (10)
# x è la variabile Globale

def funz_A():                              # (20)
# Altera la variabile Locale x, ma non vede la Globale
   x = 25
   print "\nfunz_A - Non vedo x Globale"
   print "funz_A - x Locale vale:", x, "all'ingresso"
   x = x+1
   print "funz_A - x Locale vale:", x, "prima di uscire"

def funz_B():                              # (30)
# Altera la variabile Globale x
   global x
   print "\nfunz_B - x Globale vale:",
   print x, "all'ingresso"
   x = x*10
   print "funz_B - x Globale vale:",
   print x, "all'uscita"

def main():                                # (40)
# Altera la variabile Globale x
   global x
   print "\n  main - x Globale vale:", x
   x = 8
   print "  main - x Globale vale:", x
   funz_B()
   funz_A()
   funz_B()
   funz_A()
   print "\n  main - x Globale vale:", x, "\n"
   
main()   

La variabile x definita inizialmente dall'istruzione (10), nel programma principale, viene vista ed alterata dalla funzione funz_B (30) e dalla main (40). Anche se non viene vista dalla funzione funz_A, in programmi complessi potrebbe correre il rischio di essere modificata inopportunamente prima di essere utilizzata da altre funzioni !
Nell'esempio proposto, infatti, la main aveva impostato x al valore 8, ma dopo 2 chiamate alla funz_B la x ha assunto il valore 800.




4.3. Variabili di Istanza

La scrittura del codice con l'utilizzo delle classi consente di risolvere il problema della conservazione e della condivisione delle informazioni in maniera più elegante e sicura. Basta ricorrere alle variabili di istanza (variabili precedute dal prefisso self.).
Abbiamo già usato, tacitamente, questo tipo di variabili nel capitolo riguardante i collegamenti. Dovendo condividere delle stringhe si è fatto allora ricorso a variabili del tipo:

self.mioGenitore = Genitore                        # (10)
self.st1="Seconda Prova di Classe"                 # (12)
self.st2="Ciao Classe"                             # (14)

Nel programma che stiamo esaminando adesso, l'informazione da conservare e da condividere è molto semplice: il riferimento all'ultimo pulsante attivato. Questa informazione verrà conservata in una variabile di istanza denominata self.memPuls (18). Il lavoro svolto dal programma consiste nel presentare a video tre pulsanti di diverso colore (attivabili con il mouse [Psx] o tramite il tasto [Spazio]) e nel fornire conseguentemente due tipi di informazione:

Quando viene invocato un gestore di evento si ha così la dimostrazione che l'informazione viene realmente conservata e condivisa. Per semplicità, nel programma non è stato previsto alcun pulsante di chiusura e non è stata attivata l'azione del tasto [Invio].

from Tkinter import *

class AppBase:
  def __init__(self, Genitore):
    self.stA = " Pulsante Precedente:"               # (10)
    self.stB = "    Pulsante Premuto:"               # (12)
    self.scr = {'0':' NESSUNO ', '1':' VERDE ',      # (14)
        '2':' BIANCO ', '3':' ROSSO '}
    self.col = {'0':'yellow', '1':'green',           # (16)
        '2':'white', '3':'red'}
    self.memPuls = "0"                               # (18)
    self.quadro1 = Frame(Genitore)                   # (20)
    self.quadro1.configure(bg="#DFFFFF",             # (22)
	padx=4, pady=4)
    self.quadro1.pack()                              # (24)
    self.labelA = Label(self.quadro1, bg="black",    # (30)
        fg="yellow", text="")
    self.labelA.pack(padx=10, pady=4)                # (32)
    self.labelB = Label(self.quadro1, bg="black",    # (34)
        fg="yellow", text=self.stB + " NESSUNO ")
    self.labelB.pack(padx=10, pady=4)                # (36)
    self.puls1 = Button(self.quadro1,                # (40)
        command = self.puls1Press)
    self.puls1.configure(text = self.scr['1'],       # (42)
        bd=1, bg = "green")
    self.puls1.pack(side = LEFT)                     # (44)
    self.puls2 = Button(self.quadro1,                # (50)
        command = self.puls2Press)
    self.puls2.configure(text = self.scr['2'],       # (52)
        bd=1, bg = "white")
    self.puls2.pack(side = LEFT)                     # (54)
    self.puls3 = Button(self.quadro1,                # (60)
        command = self.puls3Press)
    self.puls3.configure(text = self.scr['3'],       # (62)
        bd=1, bg = "red")
    self.puls3.pack(side = LEFT)                     # (64)

  def gestLabel(self,n):                             # (70)
    self.labelA.configure(fg=self.col[self.memPuls], # (72)
        text=self.stA + self.scr[self.memPuls])
    self.memPuls = n                                 # (74)
    self.labelB.configure(fg=self.col[self.memPuls], # (76)
        text=self.stB + self.scr[self.memPuls])

  def puls1Press(self):                              # (81)
    self.gestLabel("1")
  def puls2Press(self):                              # (82)
    self.gestLabel("2")
  def puls3Press(self):                              # (83)
    self.gestLabel("3")

def main():                                          # (90)
    finestra = Tk()
    appBase = AppBase(finestra)
    finestra.title("Tk Prova")
    finestra.mainloop()

main()

Come d'abitudine, seguono alcune osservazioni di un qualche rilievo sulla struttura e sul codice del programma.






Corso Base Linux
Asm Linux
Python
GnuPlot
TkInter
wxPython
py-qt4-designer



Non si fa politica con la morale, ma nemmeno senza.
André Malraux

Valid CSS!
pagina generata in 0.001 secondi