2010-09-13 119 views
13

我正在尝试构建检索表单,并且似乎遇到按钮问题...我是Python/tkinter GUI编程(一般GUI编程)的新手,并且借用了Hello World的骨架应用程序和sorta建立起来的。Tkinter按钮命令在运行程序时激活?

在下面的代码中,我设置了Browse按钮的“command”选项,当它被点击时调用我的类的内部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-i s-button-parameter-command-executed-when-declared) – nbro 2017-03-10 10:50:50

+0

@nbro我认为你有你的重复倒退,我在2010年问了这个问题,你把这个重复的标记为2011年被问到-_- – 2017-03-10 16:03:51

+0

The因为我将这篇文章标记为另一篇文章的副本,因为其他文章实际上包含更多信息,而且问题更简单。 – nbro 2017-03-10 16:08:01

回答

17

让您的事件处理lambda函数,这与任何参数来调用你的get_dir()你想:

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

您可以通过添加lambda部分来解释这是做什么的吗?我遇到了Tkinter文档中最小应用程序的问题,我想在按下按钮时将文本添加到窗口中。我有命令= label.grid()当它运行时添加一个标签,并添加lamba修复它。为什么没有立即执行lambda的命令?什么是lambda关键字在做什么? – Matt 2017-06-23 03:23:07

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

啊,我明白了!现在要弄清楚如何将参数传递给函数... – 2010-09-13 22:10:39

+1

@Doktor J:你不需要传递一个对你的xbPath的引用,看看我的回答 – volting 2010-09-13 22:13:42

3

你需要通过你的get_dir的参考方法

如此改变

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()并将它传递给适当的输入字段...你会怎么做? – 2010-09-14 14:05:37

+0

@Doktor J:传统的方法是为每个事件分别设置一个处理程序,所以在您的情况下为每个浏览按钮单独使用get_dir()方法,或者您可以实现浏览按钮+条目窗口小部件+ ..作为复合小部件,并让它自动完成所有你想要的东西,即得到一个路径处理它显示它等等。然后就像创建复合小部件的任意多个实例一样简单。 – volting 2010-09-14 14:38:08