首页 > 解决方案 > 在使用 python、tkinter 时出现错误“IndexError: list index out of range”

问题描述

我是 python 新手,我想知道为什么我的程序不工作。第 23 行的错误是“IndexError: list index out of range”(这个程序是为明天我最好朋友的生日准备的)

import datetime
import tkinter
from tkinter import *

t = Tk()
t.resizable(0, 0)
t.title("Sana's birthday!!!")
t.geometry('200x200')

current_date = datetime.date.today().strftime('%Y-%m-%d')
current_date_lst = current_date.split('-')

l1 = Label(t, text='Sana enter your birthday in yyyy-mm-dd format:').grid(row=1, column=1)
l2 = Label(t, text='Name of your birthday legend?:').grid(row=2, column=1)

b_date = tkinter.Entry(t)
b_date.grid(row=1, column=2)
name = tkinter.Entry(t)
name.grid(row=1, column=2)

b_date = b_date.get().split( '-' )

if current_date_lst[1] == b_date[1] and current_date_lst[2] == b_date[2]:
    age = int(current_date_lst[0]) - int(b_date[0])
    ordinal_suffix = {1: 'st', 2:'nd', 3:'rd', 11:'th', 12:'th', 13:'th'}.get(age % 10 if not 10<age<=13 else age % 14, 'th')
    print(f" It's {name}'s {age}{ordinal_suffix} Birthday!")
else:
    print('Sorry, today is not your birthday:(')

mainloop()

错误:

if current_date_lst[1] == b_date[1] and current_date_lst[2] == b_date[2]:
IndexError: list index out of range

标签: pythonlistdatetimetkinterindexing

解决方案


您的代码有两个问题:

  • 这样做时b_date.get().split( '-' ),还没有输入任何文本,所以你总是得到一个空字符串,从这里IndexError
  • b_date并且name都在第 1 行第 2 列上进行了网格化。因此,即使您认为自己是在b_date条目上书写,但实际上您是在条目上书写name

第二个问题由name.grid(row=2, column=2). 相反,要解决第一个问题,您需要确保仅在写入一些文本后才读取条目。

一种可能的解决方案:强制用户在输入一些文本后按下按钮。我更喜欢一种方法:对于输入的每个字符,检查字符串是否正常,如果是,则执行某些操作。

这里有一些示例代码:

import datetime
import tkinter
from tkinter import *

t = Tk()
t.resizable(0, 0)
t.title("Sana's birthday!!!")
t.geometry('200x200')

current_date = datetime.date.today().strftime('%Y-%m-%d')
current_date_lst = current_date.split('-')

l1 = Label(t, text='Sana enter your birthday in yyyy-mm-dd format:').grid(row=1, column=1)
l2 = Label(t, text='Name of your birthday legend?:').grid(row=2, column=1)

b_date = tkinter.Entry(t)
b_date.grid(row=1, column=2)
name = tkinter.Entry(t)
name.grid(row=2, column=2)

t.bind("<KeyRelease>", lambda e: show_string(b_date, name))

def show_string(b_date, name):
    
    b_date = b_date.get().split( '-' )
    name = name.get()
    
    if len(b_date)==3:
        if current_date_lst[1] == b_date[1] and current_date_lst[2] == b_date[2]:
            age = int(current_date_lst[0]) - int(b_date[0])
            ordinal_suffix = {1: 'st', 2:'nd', 3:'rd', 11:'th', 12:'th', 13:'th'}.get(age % 10 if not 10<age<=13 else age % 14, 'th')
            print(f"It's {name}'s {age}{ordinal_suffix} Birthday!")
        else:
            print('Sorry, today is not your birthday:(')

mainloop()

怎么了:

  • bind按下(实际上是释放键,以确保您正在寻找实际输入的字符串)到检查器功能show_string。查看如何将事件绑定到 tkinter 中的函数,例如这个答案
  • 你像往常一样分割你的字符串
  • 如果字符串与给定格式匹配,您确保仅继续您的详细说明。简单的方法:确保至少有两个“-”字符。最佳方法:检查字符串是否为“yyyy-mm-dd”格式
  • 请注意,您也在打印name. 您应该打印name.get()。此外,您正在控制台上打印它,而您可能有兴趣在 tkinter 中更新标签

祝你的朋友好运和生日快乐


推荐阅读