绑定&lt; <listboxselect>&gt; </listboxselect>时无限循环或无操作

时间:2015-04-02 14:56:26

标签: python-3.x matplotlib tkinter listbox infinite-loop

我正在尝试使用选择tkinter Listbox的更改来绘制matplotlib图。我已将ListboxSelect绑定到一个回调函数,该函数应该获取在列表框中选择的行。然后它获取行信息并将其绘制在已存在的matplotlib图中。我的问题是,根据回调函数的最后一行是否被注释掉,尽管列表框选择发生了变化,但回调函数无限循环或仅触发一次。如何在每次更改列表框选择时只执行一次回调函数,然后每次更改时都执行回调函数?

from tkinter import *
import matplotlib.pyplot as plt
from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg

root = Tk()
root.title('Plotting Tool')
root.minsize(640,480)

scheduleWindow = Toplevel()
scheduleWindow.title('Schedule')
scheduleWindow.geometry("%dx%d%+d%+d" % (0, 400, 0, 100))

scheduleList = Listbox(scheduleWindow, selectmode = EXTENDED)

x = []

for i in range(0,21):
    scheduleList.insert(END, i)
    x.append(i)

scheduleList.pack(expand=True, fill = Y)

fig = plt.figure(tight_layout=True)
ax = fig.add_subplot(111, autoscale_on = True)
ax.set_xlim(0,20)

y = [0,1,1,2,3,5,8,13,21,34,55,89,144,233,377,610,987,1597,2584,4181,6765]

ax.plot(x,y)

canvas = FigureCanvasTkAgg(fig,root)
canvas.get_tk_widget().pack(side = TOP, fill = BOTH, expand = True)
canvas.show()

def grayzone():
    print(scheduleList.curselection())
    try:
        gray
    except:
        pass
    else:
        #clearing function to be added later

    if scheduleList.curselection() == ():
        gray = ax.axvspan( 0, 0,ymin=0, ymax=1,facecolor='gray',alpha=0.25)

    else:
        gray = ax.axvspan( scheduleList.curselection()[0], scheduleList.curselection()[-1],ymin=0, ymax=1,facecolor='gray',alpha=0.25)

    canvas.show()
    #scheduleList.bind('<<ListboxSelect>>', grayzone())

scheduleList.bind('<<ListboxSelect>>', grayzone())

1 个答案:

答案 0 :(得分:2)

您正在进行错误的绑定,并且超出了您的需要。您只需要添加一次绑定,并且需要为函数提供引用的绑定。相反,您从<{1}}内部调用函数,然后将结果提供给绑定。这就是你收到递归问题的原因:grayzone正在调用grayzone

grayzone之外执行此操作,并删除grayzone内的内容:

grayzone

请注意没有尾随括号。

另外,请注意,当事件触发时,tkinter将始终将事件对象传递给回调。您需要修改scheduleList.bind('<<ListboxSelect>>', grayzone) 才能接受。由于您实际上并未使用事件对象,并且希望能够在回调之外调用该函数,因此可以将其设为可选:

grayzone