2016-06-16 2 views
0

私はChris Meyers Tkinter tutorialを働いていて、奇妙な例外に気づいています。私はプログラムと「ロード」リストボックス内の項目のいずれかを実行し、情報を更新すると、私はどこにでもボックスにカーソルを残せば、私は次のエラーを取得する:テキストボックスにカーソルを置くと、「インデックスが範囲外です」というエラーが表示されるのはなぜですか?

IndexError: tuple index out of range

しかし、私はの外をクリックした場合ボックスと完全に正常に動作する更新ボタンをクリックします。なぜこのようなことが起こり、どのように私がそれを守ることができるかについてのアイディアはありますか?ここでは、完全なプログラムです:

from Tkinter import * 
from phones import * 

def whichSelected() : 
    print "At %s of %d" % (select.curselection(), len(phonelist)) 
    return int(select.curselection()[0]) 

def addEntry() : 
    phonelist.append ([nameVar.get(), phoneVar.get()]) 
    setSelect() 

def updateEntry() : 
    phonelist[whichSelected()] = [nameVar.get(), phoneVar.get()] 
    setSelect() 

def deleteEntry() : 
    del phonelist[whichSelected()] 
    setSelect() 

def loadEntry () : 
    name, phone = phonelist[whichSelected()] 
    nameVar.set(name) 
    phoneVar.set(phone) 

def makeWindow() : 
    global nameVar, phoneVar, select 
    win = Tk() 

    frame1 = Frame(win) 
    frame1.pack() 

    Label(frame1, text="Name").grid(row=0, column=0, sticky=W) 
    nameVar = StringVar() 
    name = Entry(frame1, textvariable=nameVar) 
    name.grid(row=0, column=1, sticky=W) 

    Label(frame1, text="Phone").grid(row=1, column=0, sticky=W) 
    phoneVar= StringVar() 
    phone= Entry(frame1, textvariable=phoneVar) 
    phone.grid(row=1, column=1, sticky=W) 

    frame2 = Frame(win)  # Row of buttons 
    frame2.pack() 
    b1 = Button(frame2,text=" Add ",command=addEntry) 
    b2 = Button(frame2,text="Update",command=updateEntry) 
    b3 = Button(frame2,text="Delete",command=deleteEntry) 
    b4 = Button(frame2,text=" Load ",command=loadEntry) 
    b1.pack(side=LEFT); b2.pack(side=LEFT) 
    b3.pack(side=LEFT); b4.pack(side=LEFT) 

    frame3 = Frame(win)  # select of names 
    frame3.pack() 
    scroll = Scrollbar(frame3, orient=VERTICAL) 
    select = Listbox(frame3, yscrollcommand=scroll.set, height=6) 
    scroll.config (command=select.yview) 
    scroll.pack(side=RIGHT, fill=Y) 
    select.pack(side=LEFT, fill=BOTH, expand=1) 
    return win 

def setSelect() : 
    phonelist.sort() 
    select.delete(0,END) 
    for name,phone in phonelist : 
     select.insert (END, name) 

win = makeWindow() 
setSelect() 
win.mainloop() 

は、ここ

phonelist = [ 
    ['Meyers, Chris', '343-4349'], 
    ['Smith, Robert', '689-1234'], 
    ['Jones, Janet', '483-5432'], 
    ['Barnhart, Ralph','683-2341'], 
    ['Nelson, Eric', '485-2689'], 
    ['Prefect, Ford', '987-6543'], 
    ['Zigler, Mary', '567-8901'], 
    ['Smith, Bob',  '689-1234'] 
] 

答えて

6

これはphones.pyの内容ですのでselect.curselection() - リストボックスで選択した項目のインデックスを返します。 - レコードリストから移動すると、空のタプルが返されます( - )。

この場合、テキストボックスをクリックして更新すると、選択したレコードリストがクリアされます。

def whichSelected() : 
    print "At %s of %d" % (select.curselection(), len(phonelist)) 
    return int(select.curselection()[0]) 

そして、あなたははIndexError取得する直前に、なぜ、それがある:範囲エラーのうちタプルインデックスを、あなたも

At() of 8 
Exception in Tkinter callback 
Traceback (most recent call last): 
    File "C:\Python27\lib\lib-tk\Tkinter.py", line 1536, in __call__ 
    return self.func(*args) 
    File "main.py", line 13, in updateEntry 
    phonelist[whichSelected()] = [nameVar.get(), phoneVar.get()] 
    File "main.py", line 6, in whichSelected 
    return int(select.curselection()[0]) 
IndexError: tuple index out of range 

あなたが「ロード」を押すと、レコードの詳細がで表示されるを参照してください適切な入力フィールド(この場合はテキストボックス)。選択したレコードはまだ選択されています(select.curselection()にはアイテムのインデックスがあります)。

一度レコードを更新すると、setSelect()も呼び出してレコードのリストを更新します。

def updateEntry() : 
    phonelist[whichSelected()] = [nameVar.get(), phoneVar.get()] 
    setSelect() 

def setSelect() : 
    phonelist.sort() 
    select.delete(0,END) 
    for name,phone in phonelist : 
     select.insert (END, name) 

は、あなたが以前にやったのと同じレコードを更新するには、select.curselectionは()今更新するレコードを認識できるように、再度、該当する記録をクリックする必要があります。

これを手動で実行しないようにするには、以前の既知の場所を保存するためにselection_set()を試すことができます。たとえば、次のようなものがあります。

def updateEntry() : 
    phonelist[whichSelected()] = [nameVar.get(), phoneVar.get()] 
    setSelect (index=whichSelected()) 

def setSelect (index=0) : 
    if not len(phonelist): 
     index = None 
    phonelist.sort() 
    select.delete(0,END) 
    for name,phone in phonelist : 
     select.insert (END, name) 
    if index is not None: 
     select.selection_set(index) 

これは、まだ選択されている前の既知の項目を設定します。また、他のすべての操作でリストの最初の項目が選択されます。音韻リストが空の場合はもちろん、何も選択しません(したがって、index = None)

関連する問題