лучший способ обновить список Tkinter

#python #tkinter #urllib2

#python #tkinter #urllib2

Вопрос:

Привет итак, прежде всего, я создал программу, которая загружает музыку и отображает процент загрузки в окне списка.

примерно так

     from Tkinter import *
from urllib2 import *
admin = Tk()
Admin = Tk()

listbox = Listbox(admin, bg="PURPLE")
listbox.pack()

def fores():
    chunks = 10000
    dat = ''
    song = '3 rounds and a sound'
    url = 'http://bonton.sweetdarkness.net/music/Blind Pilot -- 3 Rounds and A Sound.mp3'
    down = urlopen(url)
    downso = 0
    tota = down.info().getheader('Content-Length').strip()
    tota = int(tota)

    while 1:
        a = down.read(chunks)
        downso  = len(a)

        if not a:
            break
        dat  = a
        percent = float(downso) / tota
        percent = round(percent*100, 1)



        listbox.insert(END, percent)
        listbox.update()
        listbox.delete(0, END)
        listbox.insert(END, percent)
        listbox.update()






button = Button(Admin, text='Download', command=fores)
button.pack()
button = Button(Admin, text='Download', command=fores)
button.pack()
mainloop()
  

Я не буду показывать вам оригинальную программу, поскольку она превышает ограничение по размеру записи.

В моей оригинальной программе, если я перемещаю окно перед загрузкой mp3-файла, загрузка составляет менее 3% и останавливается, а если я затем закрываю окно, загрузка начинается снова.

кто-нибудь знает, почему это или есть ли альтернатива отображению процента в окне Tkinter? Пожалуйста, помогите

и update_idletasks не работают

Ответ №1:

Подходящим виджетом для отображения строки является метка. Вы можете изменить текст во время выполнения с помощью configure метода:

 self.progress = Label(...)
...
self.progress.configure(text="%s%% completed" % percent)
  

Во-вторых, вы создаете два корневых окна — admin и Admin . И, как ни странно, вы помещаете список в один, а кнопки в другой. Tk не предназначен для такой работы. В-третьих, вам нужно вызвать метод mainloop вашего (единственного) корневого окна (например: Admin.mainloop )

Наконец, что касается вашего комментария, который update_idletasks не работает — пожалуйста, определите «не работает». Это фактически обновит отображение. Чего он не будет делать, так это позволять вам взаимодействовать с окном во время его запуска.

Я внес изменения в ваш код на основе приведенных выше комментариев (создал только один root, использовал Label вместо Listbox и использовал update_idletasks , и программа завершилась, загрузив песню.

Опасность вызова update заключается в следующем: что, если вы нажмете кнопку «Загрузить», когда вы уже загружаете? Что произойдет, так это то, что при следующем вызове update нажатие кнопки будет обработано. При обслуживании этого события вы войдете в бесконечный цикл. Пока выполняется этот внутренний бесконечный цикл, внешний не может выполняться. Вы фактически заморозите первую загрузку.

Правильное решение включает в себя один из (как минимум) двух методов. Во-первых, создайте поток для выполнения загрузки и попросите его периодически отправлять информацию обратно в основной цикл, чтобы он мог обновлять индикатор выполнения. Второй способ — использовать уже существующий бесконечный цикл — цикл событий — и выполнять чтение фрагментов по одному, помещая задания в очередь событий с помощью after .

В Интернете есть примеры обоих подходов.

Ответ №2:

я использую ttk.Progressbar, все, что вам нужно сделать, это связать с ним переменную и обновить эту конкретную переменную.

http://docs.python.org/library/ttk.html#progressbar

http://www.tkdocs.com/tutorial/morewidgets.html#progressbar