problem with tkinter

max(01)* max2 at fisso.casa
Wed Mar 30 14:47:31 CEST 2005


Eric Brunel wrote:
> On Tue, 29 Mar 2005 22:32:59 +0200, Pierre Quentel 
> <quentel.pierre at wanadoo.fr> wrote:
> 
>> Instead of indexing self.lab by strings, you can index them by the
>> attributes themselves : self.lab[self.i], and change line 23 into
>>
>>       for var in (self.s, self,i)
> 
> 
> I really think this is asking for trouble: I suppose that the i and s 
> attributes are meant to change at some point in the future, and you're 
> mapping their *values* to the corresponding labels. So if the value 
> changes, you won't be able to get the label again.
> 
>> For your example, I wouldn't have used the "text" option in the
>> definition of the labels, then "textvariable" in the callback method
>> (procedi) ; I would have used only "text" and no IntVar or StringVar,
>> just an integer and a string :
> 
> 
> I would have done exactly the contrary, as it is far more easier to use. 
> Using the textvariable option in Label's does not require you to 
> remember the labels, but only the variables used to hold their contents. 
> I'd also use two mappings: the first mapping a name to a Tkinter 
> variable for the label variables, and the second for the values to give 
> to these variables later.
> 
> Here is my version of the class code:
> 
> class MiaApp:
>      def __init__(self, genitore):
>         self.mioGenitore = genitore
>         ## Mapping for variables
>         self.variables = {
>           "i" : StringVar(),
>           "s" : StringVar()
>         }
>         ## Mapping for future variable values
>         self.values = {
>           "i" : 42,
>           "s" : "Baobab"
>         }
>         ## Now, create the labels
>         for var in self.variables.values():
>           ## Default text
>           var.set("[vuota]")
>           ## Create label
>           lb = Label(self.mioGenitore, width=30, relief=RIDGE, 
> textvariable=var)
>           lb.pack()
>         ## The button is no more remembered in an attribute, as it does 
> not seem to be needed
>         but = Button(self.mioGenitore, text = "Vai!", command = 
> self.procedi)
>         but.pack()
> 
>      def procedi(self):
>        ## Just change the variable values
>        for varName in self.variables.keys():
>          self.variables[varName].set(self.values[varName])
> 

your technique is most interirting and clean, i must say.

nevertheless, i cannot find a natural way to "modularize" it, in such a 
way that the machinery of the method might be isolated from the code 
that uses it.

consider for example the following two programs:

....

$ cat Miodialogo.py
from Tkinter import *

class MioDialogo(Toplevel):
   def __init__(self, genitore, chiamante):
     Toplevel.__init__(self, genitore)
     self.wm_title("Valori delle variabili")

     self.mioGenitore = genitore
     self.mioChiamante = chiamante

     self.fonteVar = ("Helvetica", 14)

     self.quadro_grande = Frame(self)
     self.quadro_grande.pack(expand = YES, fill = BOTH)

     self.titolo = Label(self.quadro_grande)
     self.titolo.configure(
       text = "Valori delle variabili:",
       width = 20,
       font = self.fonteVar
       )
     self.titolo.pack(side = TOP, fill = X)

   def mostraVariabili(self, *argomenti):
     lung = 1
     for i in argomenti:
       if len(i) > lung:
         lung = len(i)

     self.dq = {}
     self.dn = {}
     self.dv = {}
     for i in argomenti:
       self.dq[i] = Frame(self.quadro_grande)
       self.dq[i].pack(
         side = TOP,
         anchor = W,
         fill = X
         )

       self.dn[i] = Label(self.dq[i])
       self.dn[i].configure(
         text = i + ": ",
         width = lung + 2,
         anchor = W
         )
       self.dn[i].pack(
         side = LEFT
         )

       self.dv[i] = Label(self.dq[i])
       self.dv[i].configure(
         textvariable = eval("self.mioChiamante." + i),
         anchor = W
         )
       self.dv[i].pack(
         side = LEFT,
         expand = YES,
         fill = X
         )

     self.vaBene = Button(self.quadro_grande)
     self.vaBene.configure(
       text = "Va Bene",
       command = self.pulsanteVaBenePremuto,
       default = ACTIVE
       )
     self.vaBene.bind(
       "<Return>",
       self.pulsanteVaBenePremuto_a
       )
     self.vaBene.focus_force()
     self.vaBene.pack(
       side = BOTTOM,
       pady = 2
       )

   def pulsanteVaBenePremuto(self):
     self.destroy()
     self.mioChiamante.var.configure(state = NORMAL)

   def pulsanteVaBenePremuto_a(self, evento):
     self.pulsanteVaBenePremuto()

$ cat spunta-4.py
from Tkinter import *
from Miodialogo import *

class MiaApp:
   def __init__(self, genitore):

     self.mioGenitore = genitore

     self.fonte = ("Helvetica", 12)

     self.quadro_grande = Frame(genitore)
     self.quadro_grande.pack(expand = YES, fill = BOTH)

     self.msg = Label(self.quadro_grande)
     self.msg.configure(
       font = self.fonte,
       wraplength = "10c",
       justify = LEFT,
       text = u"Sono qui sotto presentati tre pulsanti a spunta. \
Premendo un pulsante, se ne varia lo stato di selezione e si \
imposta una variabile a un valore che indica lo stato del \
pulsante stesso. Premendo il pulsante \u00ABMostra \
Variabili\u00BB si possono vedere i valori correnti delle \
variabili."
       )
     self.msg.pack(side = TOP)

     self.pulsanti = Frame(self.quadro_grande)
     self.pulsanti.pack(side = BOTTOM, fill = X, padx = "2m")

     self.pulsanti_spunta = Frame(self.quadro_grande)
     self.pulsanti_spunta.pack(side = TOP, fill = X, padx = "2m")

     self.annulla = Button(self.pulsanti)
     self.annulla.configure(
       text = "Annulla",
       command = self.mioGenitore.destroy
       )
     self.annulla.pack(side = LEFT, expand = YES)


     self.var = Button(self.pulsanti)
     self.var.configure(
       text = "Mostra Variabili",
       command = self.pulsanteMostraVariabiliPremuto,
       default = NORMAL
       )
     self.var.pack(side = LEFT, expand = YES)

     self.tergicristalli = IntVar()
     self.b1 = Checkbutton(self.pulsanti_spunta)
     self.b1.configure(
       text = "Tergicristalli a posto",
       variable = self.tergicristalli,
       relief = FLAT
       )
     self.b1.pack(
       side = TOP,
       pady = 2,
       anchor = W
       )

     self.freni = IntVar()
     self.b2 = Checkbutton(self.pulsanti_spunta)
     self.b2.configure(
       text = "Freni a posto",
       variable = self.freni,
       relief = FLAT
       )
     self.b2.pack(
       side = TOP,
       pady = 2,
       anchor = W
       )

     self.autista = IntVar()
     self.b3 = Checkbutton(self.pulsanti_spunta)
     self.b3.configure(
       text = "Autista sobrio",
       variable = self.autista,
       relief = FLAT
       )
     self.b3.pack(
       side = TOP,
       pady = 2,
       anchor = W
       )

   def pulsanteMostraVariabiliPremuto(self):
     if self.var.cget("state") == ACTIVE:
       self.var.configure(state = DISABLED)
       self.dialogo = MioDialogo(self.mioGenitore, self)
       self.dialogo.mostraVariabili("tergicristalli",
                                    "freni",
                                    "autista")

radice = Tk()
radice.wm_title("Dimostrazione Pulsanti a Spunta")
radice.wm_iconname("spunta")
miaApp = MiaApp(radice)
radice.mainloop()

....

the program spunta-4.py uses the module Miodialogo.py, which can be 
usedby any other program simply passing along strings containing the 
names of the attributes to be displayed.

i cannot find a similar way to modularize your technique (maybe it is my 
fault).

thanks again

macs



More information about the Python-list mailing list