2015-04-02 32 views
0

我試圖在tkinter Listbox的選擇中使用更改來繪製matplotlib圖。我將ListboxSelect綁定到一個回調函數,該函數應該獲取在Listbox中選擇的行。然後獲取行信息並將其繪製在已存在的matplotlib圖中。我的問題是,取決於如果回調函數的最後一行被註釋掉,回調函數無限循環或只觸發一次,儘管更改了列表框選擇。我如何才能讓它只在每次更改Listbox選項時執行一次回調函數,然後在每次更改時都執行它?綁定時出現無限循環或無動作<< ListboxSelect >>

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()) 

回答

2

你正在做的綁定不正確,超過你的需要。您只需添加綁定一次,並且您需要將綁定引用添加到一個函數。相反,你是grayzone內部調用函數,然後給出綁定的結果。這就是爲什麼你會遇到遞歸問題:grayzonegrayzone

做這樣的外grayzone,取出一個是內部grayzone

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

注意沒有尾隨括號。

另外,請注意,當事件觸發時,tkinter將始終將一個事件對象傳遞給回調函數。您需要修改grayzone才能接受。既然你不實際使用的事件對象,並要能夠調用回調之外的功能,你可以把它可選:

def grayzone(event=None): 
    ... 
+0

我有這樣做,是我得到這個錯誤中發現的問題。 TypeError:grayzone()需要0個位置參數,但有1個被給出 – Tikkanen 2015-04-02 15:50:02

+0

@Tikkanen:正確:當事件觸發時,它將事件對象傳遞給被調用的函數。你需要修改'grayzone'來接受這個參數。我會更新我的答案以反映這一點。 – 2015-04-02 16:02:49

+0

非常好。看起來我需要多讀一些所謂的功能。謝謝。 – Tikkanen 2015-04-02 16:25:06

相關問題