如何从tkinter中的另一个模块调用事件

时间:2017-09-29 01:17:32

标签: python-2.7 tkinter

我出于这样的原因制作了测试应用程序。我试图让ButtonRelease-1事件在另一个文件中调用一个函数。我在尝试运行应用程序时获得了语法。

TypeError:listb()只需要2个参数(给定1个)

这是相当严格的前进语法,但我无法在这种特定情况下修复它。我基本上只是让事件得到点击信息打印。这是不起作用的事件,因为其他文件中的函数没有重新组合事件?

无论如何,好奇如何修复此代码以使其正常工作。该函数必须保留在另一个文件中。如果它在同一个文件中,但这不容易,这将很容易。

start.py

from Tkinter import *
import example_funcs as EF


class Page_three(Frame):

    def __init__(self):
        Frame.__init__(self)
        self.pack()
        self.listboxs()

    def listboxs(self):
        self.z = Listbox(self)
        self.z.grid()
        for item in range(1,10):
            self.z.insert(END, item)
        self.z.bind("<ButtonRelease-1>", EF.listb(self))

root = Tk()
app = Page_three()
app.mainloop()

example_funcs.py

from Tkinter import *
import Tkinter as tk

def listb(self, event):
    selection = self.z.curselection()
    print selection

self被使用,因此变量可以在函数内部调用,如果不调用self作为实例,它将具有找不到我的列表框变量的语法。

1 个答案:

答案 0 :(得分:1)

传递EF.listb(self)并不能达到您想要的效果。它不会将self参数部分绑定到您调用它的实例,然后让event参数通过回调填充。相反,它只是立即调用函数(在bind调用之前)并且您得到关于使用错误数量的参数的错误。

有几种不同的方法可以解决这个问题。

一种选择是使用self手动将listb参数绑定到functools.partial函数:

import example_funcs as EF
import functools

class Page_three(Frame):
    ...
    def listboxs(self):
        ...
        self.z.bind("<ButtonRelease-1>", functools.partial(EF.listb, self))   # bind self

另一种方法是让listb成为您班级中的实际方法,以便您可以在self上将其作为方法引用。这看起来像这样:

import example_funcs as EF

class Page_three(Frame):
    ...
    def listboxs(self):
        ...
        self.z.bind("<ButtonRelease-1>", self.listb)   # refer to a method without calling it

    listb = EF.listb   # add the function from the other module as a method on this class

如果listb没有在其他任何地方使用,那么在另一个模块中定义它并将其复制到这里将是非常愚蠢的。您应该将定义移动到此类中,而不是在事后添加对它的引用。另一方面,如果在几个不同的类中使用listb,则表明类应该使用某种继承来共享方法,而不是粗略地复制对一个定义的引用。