【问题标题】:Tkinter button bound to Enter immediately executes绑定到 Enter 的 Tkinter 按钮立即执行
【发布时间】:2015-03-02 10:35:25
【问题描述】:

非常感谢这些问题的答案:How to pass arguments to a Button command in Tkinter?Why is Button parameter “command” executed when declared?

但是,当我将按钮绑定为在按下 Enter 键时自动执行时,它会立即执行。我的代码是:

from Tkinter import *

import ttk

from timeAttendance_show_DTR_GUI import * 


def employee_toShow(leftFrame,rightFrame):  

        empNumberToShow = '1'
        beginDateToShow = '2014-06-01'
        endDateToShow = '2014-06-31'
        requiredReport='dtr'

        emp = IntVar()  #please don't mind yet other parts as I am still working on them bit by bit.
        ttk.Label(leftFrame, text='Enter Employee Number').pack()
        emp_entry = ttk.Entry(leftFrame, textvariable=emp)
        emp_entry.pack()

        emp_DTR = ttk.Button(leftFrame, text='Calculate', command=lambda: indiv_DTR(rightFrame, empNumberToShow, beginDateToShow, endDateToShow, requiredReport))

        emp_entry.focus()
        emp_DTR.pack()
        root.bind('<Return>', indiv_DTR(rightFrame, empNumberToShow, \
            beginDateToShow, endDateToShow, requiredReport))  # This is where i get the problem


def indiv_DTR(frame, empNumberToShow, beginDateToShow, endDateToShow, requiredReport):

        dtr, absent, frequencyOfLate, frequencyOfUndertime, totalMinutesLate, totalMinutesUndertime, \
            frequencyOfGracePeriod, gracePeriodTotal = initialization(empNumberToShow, beginDateToShow, endDateToShow, requiredReport)

        tree = ttk.Treeview(frame, height=31)
        tree['show'] = 'headings'

        tree["columns"]=('Date', 'Day', 'AmIn', 'AM Out', 'PM In', 'PM Out', 'OT In', 'OT Out', 'Late', 'Early Out', 'Remarks')


        tree.column('Date', width=60)
        tree.column('Day', width=45 )
        tree.column('AmIn', width=50)
        tree.column('AM Out', width=50)
        tree.column('PM In', width=50)
        tree.column('PM Out', width=50)
        tree.column('OT In', width=50)
        tree.column('OT Out', width=50)
        tree.column('Late', width=50)
        tree.column('Early Out', width=65)
        tree.column('Remarks', width = 95)

        tree.heading('Date', text='Date')
        tree.heading("Day", text="Day")
        tree.heading("AmIn", text="AM In")
        tree.heading('AM Out', text='AM Out')
        tree.heading('PM In', text = 'PM In')
        tree.heading('PM Out', text = 'PM Out')
        tree.heading('OT In', text = 'OT In')
        tree.heading('OT Out', text='OT Out')
        tree.heading('Late', text='Late')
        tree.heading('Early Out', text='Early Out')
        tree.heading('Remarks', text='Remarks')

        for i in dtr:
            tree.insert("" , 'end', text= '', \
                values=(i[0],i[1],i[2],i[3],i[4],i[5],i[6],i[7],i[8],i[9], i[10])) 
            tree.pack()

if __name__ == '__main__':

        employee_toShow(leftFrame,rightFrame)
        root.mainloop()

显然,这里只是一个新手(甚至不确定我的代码是否正确缩进)...任何帮助将不胜感激。

【问题讨论】:

    标签: python python-2.7 tkinter


    【解决方案1】:

    请阅读有关发布minimal code的信息。

    在这种情况下

        root.bind('<Return>', indiv_DTR(rightFrame, empNumberToShow,
                  beginDateToShow, endDateToShow, requiredReport))
    

    立即调用 indiv_DTR,因为这就是你说要做的!要延迟呼叫,您需要执行与 Button 呼叫相同的操作:前缀为 lambda :。但是,要真正“执行按钮”,也就是像按下按钮一样调用其回调,您应该使用 .invoke 方法。

        root.bind('<Return>', emp_DTR.invoke)
    

    (注意,不是emp_DTR.invoke())。这样,如果您在 Button 调用中更改 indiv_DTR 参数,您就不必记住在绑定调用中更改它们。

    第三种选择是首先定义回调

    def callback():
        return indiv_DTR(rightFrame, empNumberToShow,
                  beginDateToShow, endDateToShow, requiredReport)
    

    然后将callback 传递给Button 和bind 调用。我通常会先定义回调,即使我只会将回调传递给一个小部件构造函数一次,除非返回表达式真的很短。

    【讨论】:

    • 谢谢!第三个选项奏效了。调用方法没有。我按照上面的建议输入了它。
    【解决方案2】:

    当您为&lt;Return&gt; 调用root.bind 时,您将调用indiv_DTR(...) 的结果作为参数传递。这相当于以下内容:

    res = indiv_DTR(rightFrame, empNumberToShow, beginDateToShow, endDateToShow, requiredReport)
    root.bind('<Return>', res)
    

    这应该更清楚地表明该函数已被执行。

    要让绑定操作实际调用此函数,您需要传递方法名称。例如:

    def onReturn(ev):
        # call the indiv_DTR function
    
    root.bind('<Return>', onReturn)
    

    如果您需要将一些局部变量作为参数捕获到事件处理程序,您也可以提供一个 lambda 表达式。

    【讨论】:

      猜你喜欢
      • 2016-10-20
      • 2014-03-23
      • 1970-01-01
      • 2015-05-14
      • 1970-01-01
      • 2013-08-15
      • 2018-10-03
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多