2011-08-21 11 views
5

Desidero aggiungere 10 pulsanti a Tkinter, denominati da uno a dieci. Fondamentalmente ho usato il metodo della forza bruta, aggiungendo ogni pulsante mentre procedevo, nella funzione init della classe della mia applicazione. Funziona, ma voglio minimizzare il codice utilizzato, per essere più efficiente, come usare una struttura dati per contenere tutti i pulsanti.Come posso aggiungere un sacco di pulsanti al frame tkinter in modo efficiente?

Stavo pensando di utilizzare uno buttonBox per contenere tutti i pulsanti, ma non ero sicuro di poter manipolare il posizionamento tramite grid() per posizionare i pulsanti come volevo.

self.one = Button(frame, text="One", command=self.callback) 
self.one.grid(sticky=W+E+N+S, padx=1, pady=1) 

self.two = Button(frame, text="Two", command=self.callback) 
self.two.grid(sticky=W+E+N+S, row=0, column=1, padx=1, pady=1) 

self.three = Button(frame, text="Three", command=self.callback) 
self.three.grid(sticky=W+E+N+S, row=0, column=2, padx=1, pady=1) 

# ... 

self.ten = Button(frame, text="Ten", command=self.callback) 
self.ten.grid(sticky=W+E+N+S, row=1, column=4, padx=1, pady=1) 

Qualcuno può mostrarmi un modo per renderlo più efficiente, ad esempio una struttura dati?

risposta

4

Invece di nominare i pulsanti self.one, self.two, ecc., Sarebbe più comodo fare riferimento a essi indicizzando un elenco, ad esempio .

Se i pulsanti sono diversi cose, quindi è necessario esplicitamente pulsanti associati con callback. Per esempio:

name_callbacks=(('One',self.callback_one), 
       ('Two',self.callback_two), 
       ..., 
       ('Ten',self.callback_ten)) 
self.button=[] 
for i,(name,callback) in enumerate(name_callbacks): 
    self.button.append(Button(frame, text=name, command=callback)) 
    row,col=divmod(i,5) 
    self.button[i].grid(sticky=W+E+N+S, row=row, column=col, padx=1, pady=1) 

Se i pulsanti tutti fanno simili cose, allora si callback può essere sufficiente per servire tutti. Dal momento che la richiamata in sé non può prendere argomenti, è possibile impostare una fabbrica di callback per passare gli argomenti attraverso una chiusura:

def callback(self,i): # This is the callback factory. Calling it returns a function. 
    def _callback(): 
     print(i) # i tells you which button has been pressed. 
    return _callback 

def __init__(self): 
    names=('One','Two','Three','Four','Five','Six','Seven','Eight','Nine','Ten') 
    self.button=[] 
    for i,name in enumerate(names): 
     self.button.append(Button(frame, text=name, command=self.callback(i+1))) 
     row,col=divmod(i,5) 
     self.button[i].grid(sticky=W+E+N+S, row=row, column=col, padx=1, pady=1) 
+1

Grazie! Questo ha funzionato, ma ho dovuto cambiarlo in "self.button.append()" in modo che non causasse un IndexError. E la linea di fondo ho cambiato in self.button [i] .grid(), invece di self.one.grid(). Ha funzionato perfettamente :) – thatbennyguy

+0

@thatbennyguy: Ack! Grazie per le correzioni! – unutbu

+0

Solo una cosa ... come otterresti i pulsanti per richiamare comandi diversi? – thatbennyguy

1

Si potrebbe mettere le proprietà tutti i pulsanti in un dizionario, e poi anello su di esso per creare i tuoi pulsanti, ecco un esempio:

buttons = { 
    'one': {'sticky': W+E+N+S, 'padx': 1, 'pady': 1}, 
    'two': {'sticky': W+E+N+S, 'row': 0, 'column': 1, 'padx': 1, 'pady': 1}, 
    'three': {'sticky': W+E+N+S, 'row': 0, 'column': 2, 'padx': 1, 'pady': 1} 
} 
for b in buttons: 
    button = Button(frame, text=b.title(), command=self.callback) 
    button.grid(**buttons[b]) 
    setattr(self, b, button) 

Ciò consentirebbe anche di aggiungere facilmente nuovi pulsanti se necessario.

Problemi correlati