2012-12-18 14 views
6

Sto provando a creare una GUI di base usando ttk/Tkinter.Python & ttk Uso di labelFrames per pulire un frame

Ho un tracciato un'interfaccia grafica di base che ha i giusti componenti di base, ma quando provo rendendolo anche più elegante/spazio fuori, io sto raggiungere il mio limite di ottenere contenitori TTK a giocare bene ...

Esempi:

from Tkinter import * 
import ttk 

class MakeGUI(object): 
    def __init__(self,root): 
     self.root = root 
     self.root.title("Text Comparitor") 
     ## build frame 
     self.mainframe = ttk.Frame(self.root, padding="3 3 12 12") 
     self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
     self.mainframe.columnconfigure(0, weight=1) 
     self.mainframe.rowconfigure(0, weight=1) 
     self.mainframe.pack() 
     ## text labels 
     ttk.Label(self.mainframe, text="Conversion Truth Tester", font=("Helvetica", 32)).grid(column=1, row=1, sticky=E) 
     self.mainframe.pack(side="bottom", fill=BOTH, expand=True) 
     self.mainframe.grid() 
     ttk.Label(self.mainframe, text="Source Filename:").grid(column=1, row=2, sticky=W) 
     ttk.Label(self.mainframe, text="Source Text:").grid(column=1, row=3, sticky=W) 
     ttk.Label(self.mainframe, text="Converted Text:").grid(column=1, row=4, sticky=W) 
     ttk.Label(self.mainframe, text="Cleaned Source:").grid(column=1, row=5, sticky=W) 
     ttk.Label(self.mainframe, text="Cleaned Converted:").grid(column=1, row=6, sticky=W) 
     ttk.Label(self.mainframe, text="Details:").grid(column=1, row=7, sticky=W) 
     ## buttons 
     self.close = ttk.Button(self.mainframe, text="Close",command=self.closeFrame).grid(column=1, row=9, sticky=SE) 
     self.next = ttk.Button(self.mainframe, text="Next",command=self.nextPara).grid(column=1, row=9, sticky=S) 
     self.next = ttk.Button(self.mainframe, text="Prev",command=self.prevPara).grid(column=1, row=9, sticky=SW) 

    def closeFrame(self): 
     self.root.destroy() 

    def nextPara(self): 
     pass 

    def prevPara(self): 
     pass 

def main(): 
    root = Tk() 
    makeGUI = MakeGUI(root) 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

che si traduce in: http://imgur.com/a/CwpCU#0

ho cercato di aggiungere un oggetto contenitore 2 °, un telaio di un'etichetta per contenere gli oggetti etichetta di testo, che si traduce in movimento i tasti più in alto (e quindi presumo di non riferirmi al labelfo rame nella rete correttamente:

from Tkinter import * 
import ttk 

class MakeGUI(object): 
    def __init__(self,root): 
     self.root = root 
     self.root.title("Text Comparitor") 
     ## build frame 
     self.mainframe = ttk.Frame(self.root, padding="3 3 12 12") 
     self.mainframe.grid(column=0, row=0, sticky=(N, W, E, S)) 
     self.mainframe.columnconfigure(0, weight=1) 
     self.mainframe.rowconfigure(0, weight=1) 
     self.mainframe.pack() 
     ## text labels 
     ttk.Label(self.mainframe, text="Conversion Truth Tester", font=("Helvetica", 32)).grid(column=1, row=1, sticky=E) 
     self.lfdata = ttk.Labelframe(self.root, labelwidget=self.mainframe, text='Label')# 
     self.lfdata.grid() 
     ttk.Label(self.lfdata, text="Source Filename:").grid(column=1, row=2, sticky=W) 
     ttk.Label(self.lfdata, text="Source Text:").grid(column=1, row=3, sticky=W) 
     ttk.Label(self.lfdata, text="Converted Text:").grid(column=1, row=4, sticky=W) 
     ttk.Label(self.lfdata, text="Cleaned Source:").grid(column=1, row=5, sticky=W) 
     ttk.Label(self.lfdata, text="Cleaned Converted:").grid(column=1, row=6, sticky=W) 
     ttk.Label(self.lfdata, text="Details:").grid(column=1, row=7, sticky=W) 

     ## buttons 
     self.close = ttk.Button(self.mainframe, text="Close",command=self.closeFrame).grid(column=1, row=9, sticky=SE) 
     self.next = ttk.Button(self.mainframe, text="Next",command=self.nextPara).grid(column=1, row=9, sticky=S) 
     self.next = ttk.Button(self.mainframe, text="Prev",command=self.prevPara).grid(column=1, row=9, sticky=SW) 

    def closeFrame(self): 
     self.root.destroy() 

    def nextPara(self): 
     pass 

    def prevPara(self): 
     pass 

def main(): 
    root = Tk() 
    makeGUI = MakeGUI(root) 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

che si traduce in: http://imgur.com/a/CwpCU#1 nota lo scambio di posizioni tra i pulsanti etichette abd, e solo su aspetti visibili della labelframe.

Sto cercando di ottenere la versione 2 per "sembrare" una versione più carina del primo.

Eventuali puntatori - Ho letto le varie risorse/documenti e non riesco a trovare nulla che si adatti al mio esempio (molto probabilmente - Sto facendo qualcosa di sciocco ...) e nulla di ciò che ho provato ha ha funzionato ancora - incluso pack(), grid() e altri frammenti che ho trovato in altri esempi correlati.

+0

E' meglio non usare rete e imballare in una finestra. Preferisco la griglia. Inoltre penso che le variabili del pulsante (con la griglia di default) non memorizzeranno ciò che ti aspetti. Grid non restituisce un riferimento all'oggetto per quanto mi ricordo. – Gonzo

+0

@Phelix I widget _Tkinter_ possono utilizzare diversi gestori di geometrie all'interno della stessa finestra ** purché non condividano lo stesso genitore **. _pack_ può compiere certe cose con meno codice; quindi non raccomanderei di usare solo _grid_. –

risposta

10

Ci sono molti posti che richiedono aggiustamenti, commentiamoli (probabilmente dimenticherò qualcosa, quindi assicurati di controllare il codice in fondo).

Prima di tutto, l'applicazione di pesi a colonne/righe nel frame non lo farà espandere mentre ridimensionate la finestra. Devi farlo in root. Dopodiché potresti voler farlo nell'inquadratura, per soddisfare le tue aspettative sul layout dopo un ridimensionamento. Nel tuo caso, ciò che ha più senso è che ogni colonna ha lo stesso peso> 0 e solo la seconda riga ha un peso> 0. Il ragionamento per le colonne è che hai 3 pulsanti e vorrai che tutti si espandano in lo spazio libero allo stesso modo. Per la seconda parte, si tratta di un'osservazione diretta considerando che si dispone di un Labelframe nella seconda riga. Dare un peso> 0 per qualsiasi altra fila ti darà un layout molto strano. Problemi di ponderazione fatti.

La prossima cosa che ho notato è stata la tua etichetta in alto con un font più grande. Certamente vuoi che si estenda su 3 colonne (di nuovo, questo numero 3 è correlato alla fila di pulsanti che creerai in un secondo momento). Potresti anche volere che il testo sia centrato in queste 3 colonne (non sono sicuro delle tue preferenze qui).

Ora il Labelframe creato. È semplicemente sbagliato, l'opzione labelwidget non significa quello che pensi che faccia. Specifica un widget Label da utilizzare come etichetta per questa cornice di etichette. Pertanto, specificare il frame principale per questo parametro non ha senso. Forse vuoi specificare del testo per essere visibile in una certa posizione nella cornice dell'etichetta. Inoltre, questo frame label deve essere gridato anche con un columnspan di 3.

Per la "griglia" in generale, si consiglia di specificare l'opzione in_, in modo da rendere chiaro in relazione a quale widget si sta "gridando". Con ciò, diventa ovvio iniziare da column=0, row=0 ogni volta che si approfondisce il livello di parenting di widget.

Ecco come ho regolato il tuo codice:

import Tkinter 
import ttk 

class MakeGUI(object): 
    def __init__(self,root): 
     self.root = root 
     self.root.title(u"Title") 
     ## build frame 
     self.mainframe = ttk.Frame(self.root, padding=(6, 6, 12, 12)) 
     self.mainframe.grid(sticky='nwse') 
     for column in range(3): 
      self.mainframe.columnconfigure(column, weight=1) 
     self.mainframe.rowconfigure(1, weight=1) 

     ## text labels 
     ttk.Label(self.mainframe, text=u"Label Title", anchor='center', 
       font=("Helvetica", 32)).grid(in_=self.mainframe, 
         column=0, row=0, columnspan=3, sticky="ew") 

     self.lfdata = ttk.Labelframe(self.mainframe, padding=(6, 6, 12, 12), 
       text='Labelframe') 
     self.lfdata.grid(column=0, columnspan=3, row=1, sticky='nsew') 
     info = (u"Source Filename", u"Source Text", u"Converted Text", 
       u"Cleaned Source", u"Cleaned Converted", u"Details") 
     for i, item in enumerate(info): 
      ttk.Label(self.lfdata, text=u"%s:" % item).grid(in_=self.lfdata, 
        column=0, row=i, sticky='w') 

     ## buttons 
     btn = (u"Close", u"Next", u"Prev") 
     for i, item in enumerate(btn): 
      ttk.Button(self.mainframe, text=item).grid(in_=self.mainframe, 
        column=i, row=3) 

def main(): 
    root = Tkinter.Tk() 
    root.columnconfigure(0, weight=1) 
    root.rowconfigure(0, weight=1) 
    makeGUI = MakeGUI(root) 
    root.mainloop() 

if __name__ == '__main__': 
    main() 

Ecco come appare quando il programma si avvia e dopo un po 'di ridimensionamento:

enter image description hereenter image description here

+1

Wow. Grazie mille per averlo fatto. Ci ho provato e ho scoperto alcuni dei miei errori, ma mi hai davvero aiutato a capire molto meglio come funziona. Apprezzo davvero il tuo tempo. –