2010-09-13 8 views
13

Ich versuche, ein Build-Retrieval-Formular zu machen, und habe Probleme mit den Schaltflächen ... Ich bin ein Anfänger bei Python/tkinter GUI-Programmierung (und GUI-Programmierung im Allgemeinen) und entlehnt das Skelett einer Hallo Welt app, und sorta baute das aus.Tkinter-Tastenbefehl wird beim Ausführen des Programms aktiviert?

Im folgenden Code habe ich die Option "command" meiner Browse-Schaltfläche gesetzt, um die interne Funktion get_dir() meiner Klasse aufzurufen, wenn darauf geklickt wird. Sobald ich jedoch versuche, die App auszuführen, wird die Funktion get_dir() aufgerufen und ich werde aufgefordert, ein Verzeichnis auszuwählen. Irgendwelche Ideen, warum das passiert und was ich tun kann, damit es sich richtig verhält?

from Tkinter import * 
import tkFont 
from tkFileDialog import askdirectory 

class App: 

    def __init__(self, master): 

     fontHead = tkFont.Font(family="Arial", size=10, weight=tkFont.BOLD) 
     fontBold = tkFont.Font(family="Arial", size=8, weight=tkFont.BOLD) 
     fontReg = tkFont.Font(family="Arial", size=8) 

     frameN = Frame(master) 
     frameN.grid(row=0,padx=5,pady=5) 

     frameXBH = Frame(frameN) 
     frameXBH.grid(row=0,columnspan=5,padx=5) 

     Canvas(frameXBH,borderwidth=0,relief="flat",height=1,width=20,background="#cccccc").grid(row=0) 
     Label(frameXBH, text="Xbox 360",font=fontBold,width=9).grid(row=0,column=1) 
     Canvas(frameXBH,borderwidth=0,relief="flat",height=1,width=440,background="#cccccc").grid(row=0,column=2,sticky="WE") 

     Label(frameN, text="Destination Path:",font=fontReg).grid(row=1,sticky="W") 
     xbPath = Entry(frameN,width=30,font=fontReg) 
     xbPath.grid(row=1,column=1,sticky="W") 
     xbBrowse = Button(frameN,text="Browse...",font=fontReg,command=self.get_dir(xbPath)) 
     xbBrowse.grid(row=1,column=2,sticky="W") 
     xbRel = Checkbutton(frameN,text="Release",font=fontReg) 
     xbRel.grid(row=1,column=3,sticky="W") 
     xbShip = Checkbutton(frameN,text="Ship",font=fontReg) 
     xbShip.grid(row=1,column=4,sticky="W") 

     Canvas(frameN,borderwidth=1,relief="groove",width=550,height=0).grid(row=2,columnspan=5,pady=10) 

     # SAVE AND CANCEL 

     btnSave = Button(frameN,text="Save",width=10) 
     btnSave.grid(row=3,column=3,sticky="E") 

     btnCancel = Button(frameN,text="Cancel",width=10) 
     btnCancel.grid(row=3,column=4,sticky="W") 

    def get_dir(self,box): 
     tmp = askdirectory(mustexist=1,title="Please select a destination") 
     tmp = tmp.replace("/","\\") 
     box.delete(0,END) 
     box.insert(0,tmp) 

root = Tk() 
root.resizable(0,0) 

app = App(root) 

root.mainloop() 
+0

Mögliche doppelte of [Warum wird der Button-Parameter "command" bei der Deklaration ausgeführt?] (http://stackoverflow.com/questions/5767228/why-i s-button-parameter-command-executed-when-deklariert) – nbro

+0

@nbro Ich denke, du hast dein Duplikat rückwärts, ich fragte dies im Jahr 2010, die, die Sie dieses ein Duplikat von wurde im Jahr 2011 -_- –

+0

Die Grund, warum ich diesen Beitrag als ein Duplikat des anderen markiert ist, weil der andere tatsächlich mehr Informationen enthält und diese Frage ist einfacher .. – nbro

Antwort

17

Ereignishandler Stellen eine Lambda-Funktion, die Ihre get_dir() Anrufe mit dem, was Argumente, die Sie wollen:

xbBrowse = Button(frameN, text="Browse...", font=fontReg, command=lambda : self.get_dir(xbPath)) 
+1

Können Sie erklären, was das bedeutet, indem Sie den Lambda-Teil hinzufügen? Ich hatte dieses Problem mit der minimalen Anwendung in der Tkinter-Dokumentation, wo ich dem Fenster Text hinzufügen wollte, wenn die Taste gedrückt wurde.Ich hatte den Befehl = label.grid() ein Label hinzufügen, als es lief, und das Hinzufügen von Lamba reparierte es. Warum wurde der Befehl ohne Lambda sofort ausgeführt? Was macht Lambda Keyword? – Matt

5

In dem obigen Code:

xbBrowse = Button(frameN,text="Browse...",font=fontReg,command=self.get_dir) 
+0

Ah, ich sehe! Jetzt, um herauszufinden, wie Parameter an die Funktion übergeben werden ... –

+1

@Doktor J: Sie müssen keine Referenz zu Ihrem xbPath übergeben, schauen Sie auf meine Antwort – volting

3

Sie benötigen eine Referenz Ihrer get_dir weitergeben müssen:

xbBrowse = Button(frameN,text="Browse...",font=fontReg,command=self.get_dir(xbPath)) 

Sie sind bereits die Funktion aufgerufen wird, sollen Sie einfach die Funktion übergeben werden Methode

so ändern

xbBrowse = Button(frameN,text="Browse...",font=fontReg,command=self.get_dir(xbPath)) 

zu

xbBrowse = Button(frameN,text="Browse...",font=fontReg, command=self.get_dir) 

Dann machen Sie Ihre Entry eine Instanzvariable Widget, so dass Sie es in Ihrem get_dir Methode zugreifen können.

z.B.

self.xbPath = Entry(frameN,width=30,font=fontReg) 

dann Ihre get_dir() Methode wird wie folgt aussehen:

def get_dir(self): 
    tmp = askdirectory(mustexist=1,title="Please select a destination") 
    tmp = tmp.replace("/","\\") 

    self.xbPath.delete(0,END) 
    self.xbPath.insert(0,tmp) 
+0

Ich beabsichtige, mehr als eine Schaltfläche zum Durchsuchen/Eintrag auf der Form, obwohl ich mehrere Tasten haben muss rufen Sie get_dir() und übergeben Sie das entsprechende Eingabefeld ... wie würden Sie das tun? –

+0

@Doktor J: Der übliche Weg ist, entweder einen separaten Handler für jedes Ereignis zu haben, also in Ihrem Fall eine separate Methode get_dir() für jede Schaltfläche Durchsuchen oder alternativ könnten Sie Ihre Schaltfläche browse + entry widget + .. als a implementieren Composite-Widget und haben es automatisch alle Dinge, die Sie wollen, dh einen Pfad Prozess es anzeigen etc. usw. Dann ist es so einfach wie das Erstellen so viele Instanzen Ihrer zusammengesetzten Widgets, wie Sie wollen. – volting

Verwandte Themen