tkinter bind方法支持参数传递

接上一篇博文(Listbox 与 Scrollbar 联动设置),接下来该说说事件的事情了。
还是先上代码:

from tkinter import *
from tkinter import messagebox

class Win_Program:
    def __init__(self):
        self.master = Tk()
        self.master.state("zoomed") # 窗口最大化
        self.master.title("demo")
        self.master.grid()
        self.databases = list()
        self.var = StringVar()
        for i in range(40):
            self.databases.append("database"+str(i))

    def get_db_configure(self):
        top = Toplevel(self.master)
        top.title("数据库配置")
        top.resizable(0,0)  # 大小不可变
        # 创建的Toplevel对象 在最上层
        top.attributes("-toolwindow", 1)
        top.wm_attributes("-topmost", 1)
        top.grid()
        sb = Scrollbar(top)
        sb.grid(row=0, rowspan=20, sticky=E+NS, padx=10, pady=5, column=1)
        lb = Listbox(top, listvariable=self.var, width=65, yscrollcommand=sb.set, selectmode=SINGLE, height=20)
        lb.bind(sequence='<Double-Button-1>', func=self.handler_adaptor(self.handler, lb=lb, top=top))
        for i in range(len(self.databases)):
            lb.insert(0, self.databases[i])
        lb.grid(row=0, rowspan=20, column=0, padx=5, pady=5)
        # Listbox 滚动时,通过lb.yview方法 通知到 Scrollbar 组件
        sb.config(command=lb.yview)

        return top

    def widget_to_center(self, master, width, height):
        # 获取屏幕长/宽
        self.width = self.master.winfo_screenwidth()
        self.height = self.master.winfo_screenheight()
        x = self.width / 2 - width / 2
        y = self.height / 2 - height / 2
        master.geometry('%dx%d+%d+%d' % (width, height, x, y))
        master.grid()
        print(self.width, self.height, x, y)

    def handler(self, event, top, lb):
        """事件处理函数"""
        content = lb.get(lb.curselection())
        return messagebox.showinfo(title="Hey, you got me!", message="I am {0}".format(content), parent=top)

    def handler_adaptor(self, fun,  **kwds):
        """事件处理函数的适配器,相当于中介,那个event是从那里来的呢,我也纳闷,这也许就是python的伟大之处吧"""
        return lambda event, fun=fun, kwds=kwds: fun(event, **kwds)

if __name__ == "__main__":
    win_program = Win_Program()
    win_program.widget_to_center(win_program.get_db_configure(), 500, 400)
    mainloop()

在上一篇文章中,我们能展示所有数据库配置了。接下来需要一个事件绑定,来完成选择配置的过程。绑定事件用bind方法,事件绑定有很多,一般通过鼠标/键盘能实现的操作,都可以绑定,比如:单击,双击,组合键ctrl+c,组合键 ctrl_v等。在我们这个案例中,双击选中是一个实用的操作。故:

lb.bind(sequence='<Double-Button-1>', func=self.handler_adaptor(self.handler, lb=lb, top=top))

需要注意的是,bind方法sequence入参是描述鼠标、键盘的操作事件,func入参可传入一个调用函数,但传递的函数必须是一个带event参数的方法,而且只能有这么一个参数。举个例子:
定义如下函数:

    def no_other_argues(self, event):
        print("You got me!")

bind方法func入参可换成这样:

lb.bind(sequence='<Double-Button-1>', func=self.no_other_argues)

双击,可以在运行代码窗口看到输出。

重点来了

但很多时候,不支持传递参数的bind方法,并不能满足我们的需求。若需要bind方法的func入参支持多参数,该如何解决呢?这个只能曲线救国了,需要定义一个函数中介:

    def handler_adaptor(self, fun,  **kwds):
        """事件处理函数的适配器,相当于中介,那个event是从那里来的呢,我也纳闷,这也许就是python的伟大之处吧"""
        return lambda event, fun=fun, kwds=kwds: fun(event, **kwds)

然后再定义自己真正要执行的函数:

    def handler(self, event, top, lb):
        """事件处理函数"""
        content = lb.get(lb.curselection())
        return messagebox.showinfo(title="Hey, you got me!", message="I am {0}".format(content), parent=top)

如此,bind方法就能支持参数传递了。

最终效果如下:
20180628

  • 9
    点赞
  • 33
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
Tkinter中的bind方法用于将事件与处理函数绑定在一起。当相应的事件发生时,绑定的处理函数将被调用。 一个例子是在捕获鼠标点击事件时可以使用bind方法。 然而,Tkinterbind方法只能传递函数,不能直接传递参数,这对于一些需要传递参数的情况来说是不方便的。 但是有很多方法可以解决这个问题,比如使用lambda表达式、使用partial函数或者使用自定义的类来传递参数。这些方法可以让我们在Tkinter中传递参数并绑定事件。 例如,如果你想要创建一个列表,并为列表中的每一项绑定一个方法,可以使用lambda表达式来传递参数。 lambda表达式可以在绑定方法时接收并传递参数,使得每一项都可以绑定到不同的方法。 另外,你还可以使用partial函数,它允许你创建一个新的函数,该函数可以接收额外的参数。通过使用partial函数,你可以将参数传递给绑定的处理函数。 总之,虽然Tkinterbind方法本身不能直接传递参数,但你可以使用lambda表达式、partial函数或自定义类等方法来实现在Tkinter中传递参数并绑定事件的需求。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* [详解python tkinter教程-事件绑定](https://download.csdn.net/download/weixin_38723192/13994606)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] - *2* *3* [Python tkinter bind三种方法传参,不用lambda表达式也可以(任何人都会)](https://blog.csdn.net/2301_77245958/article/details/129770324)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_1"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值