2010-09-13 1 views
13

Я пытаюсь создать форму поиска и, похоже, проблемы с кнопками ... Я новичок в программировании GUI Python/tkinter (и вообще программирование графического интерфейса) и заимствовал скелет Hello World приложение, и sorta построили это.Команда кнопки Tkinter активируется при запуске программы?

В приведенном ниже коде я установил опцию «команда» моей кнопки «Обзор», чтобы вызвать внутреннюю функцию get_dir() моего класса при ее нажатии. Однако, как только я пытаюсь запустить приложение, вызывается функция get_dir(), и мне предлагается выбрать каталог. Любые идеи, почему это происходит, и что я могу сделать, чтобы заставить его вести себя правильно?

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

Возможный дубликат из [Почему параметр Button «команда» выполняется при объявлении?] (http://stackoverflow.com/questions/5767228/why-is-but ton-parameter-command-execute-when-declaration) – nbro

+0

@nbro Я думаю, что у вас есть дубликат в обратном направлении, я спросил об этом в 2010 году, тот, который вы отмечаете, дубликат был задан в 2011 году -_- –

+0

Причина, по которой я отмечен этот пост как дубликат другого, потому что другой фактически содержит больше информации, и этот вопрос проще. – nbro

ответ

17

Сделайте свой обработчик события функция лямбда, который вызывает вашу get_dir() с любыми аргументами вы хотите:

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

Можете ли вы объяснить, что это делает, добавив лямбда-часть? У меня была эта проблема с минимальным приложением в документах Tkinter, где я хотел добавить текст в окно при нажатии кнопки.У меня была команда = label.grid(), добавляющая метку, когда она запускается, и добавление lamba исправило ее. Почему команда без лямбды была немедленно выполнена? Что делает лямбда-ключевое слово? – Matt

5

В приведенном выше коде:

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

Вы вызываете функцию уже, вы должны быть просто передавая функции:

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

Ах, я вижу! Теперь, чтобы выяснить, как передать параметры функции ... –

+1

@Doktor J: Вам не нужно передавать ссылку на ваш xbPath, посмотрите на мой ответ – volting

3

Вам нужно передать ссылку на ваш get_dir метод

so change

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

в

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

Затем сделайте ваш Entry виджет переменную экземпляра, так что вы можете получить доступ к нему в методе get_dir.

например.

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

Тогда ваш метод get_dir() будет выглядеть следующим образом:

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

Я намерен иметь более одной кнопки/записи на форма, поэтому мне нужно, чтобы несколько кнопок вызывали get_dir() и передавали ей соответствующее поле ввода ... как бы вы это сделали? –

+0

@Doktor J: Обычный способ состоит в том, чтобы либо иметь отдельный обработчик для каждого события, поэтому в вашем случае отдельный метод get_dir() для каждой кнопки обзора, или, альтернативно, вы могли бы реализовать свою кнопку просмотра + виджет ввода + .. как составной виджет и автоматически выполнять все необходимые действия, т. е. получить путь, который он отображает, и т. д. Тогда это так же просто, как создание как можно большего количества экземпляров ваших составных виджетов. – volting