Как сделать много меток для текущей длины текста в текстовых виджетах tkinter

#python #tkinter

Вопрос:

я хочу сделать метки для текущей длины текста в текстовом виджете tkinter, но мой код выполняет последнее текстовое поле, так что мне нужно сделать?

 from tkinter import *

win=Tk()
win.geometry("700x350")

text_all=[]
label_all=[]
for i in range(1,11):
    text=Text(win, width=20, height=1, font=('Calibri 14'))
    text.grid(row=i-1,column=0)
    text_all.append(text)
    label=Label(win, text="Total Characters", justify=CENTER, font=('11'))
    label.grid(row=i-1, column=1)
    label_all.append(label)

for i in range(1,11):
    def update(event):
        label_all[i-1].config(text="Total Characters: " str(len(text_all[i-1].get("1.0", 'end-1c'))))
    
    text_all[i-1].bind('<KeyPress>', update)
    text_all[i-1].bind('<KeyRelease>', update)

win.mainloop()
 

Ответ №1:

При update() выполнении значение i будет последним присвоенным значением после цикла for, т. е. 10.

Вам необходимо записать требуемое значение i и передать это значение с update() помощью аргумента значение по умолчанию:

 for i in range(1, 11):
    def update(event, i=i):
        label_all[i-1].config(text="Total Characters: " str(len(text_all[i-1].get("1.0", 'end-1c'))))

    ...
 

Также вы можете объединить два цикла for в один:

 for i in range(1,11):
    def update(event, i=i):
        label_all[i-1].config(text="Total Characters: " str(len(text_all[i-1].get("1.0", 'end-1c'))))

    text=Text(win, width=20, height=1, font=('Calibri 14'))
    text.grid(row=i-1,column=0)
    text.bind('<KeyPress>', update)
    text.bind('<KeyRelease>', update)
    text_all.append(text)

    label=Label(win, text="Total Characters", justify=CENTER, font=('11'))
    label.grid(row=i-1, column=1)
    label_all.append(label)
 

Ответ №2:

Все, что мне нужно было сделать, чтобы ваш код заработал, — это удалить geometry инструкцию, чтобы можно Text было определить размер окна и изменить update(event) его на update(event, i = i):

Все остальное работает как есть!

 
from tkinter import *

win=Tk()
# remove and let text widget determine width of window

# win.geometry("700x350")

text_all=[]
label_all=[]
for i in range(1,11):
    text=Text(win, width = 40, height=1, font=('Calibri 14'))
    text.grid(row=i-1,column=0, sticky=EW)
    text_all.append(text)
    label=Label(win, text="Total Characters", justify=CENTER, font=('11'))
    label.grid(row=i-1, column=1, sticky=EW)
    label_all.append(label)

for i in range(1,11):
    def update(event, i = i):
        label_all[i-1].config(text="Total Characters: " str(len(text_all[i-1].get("1.0", 'end-1c'))))
    
    text_all[i-1].bind('<KeyPress>', update)
    text_all[i-1].bind('<KeyRelease>', update)

win.mainloop()
 

Комментарии:

1. Молодец, @lee. Счастливого кодирования.