更新 Tkinter 列表框的更好方法

发布于 2024-11-06 14:06:03 字数 1219 浏览 3 评论 0原文

你好 所以首先我制作了一个程序来下载音乐并在列表框中显示已下载的百分比。

有点像这样,

    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%20Pilot%20--%203%20Rounds%20and%20A%20Sound.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 不起作用

Hi
so first of all i made a program that downloads music and displays the percent that has downloaded in a list box.

kind of like this

    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%20Pilot%20--%203%20Rounds%20and%20A%20Sound.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()

I wont show you the original program for it is over the limit of the post size.

On my original program if i move the window before i download an mp3 file it downloads less then 3 % and stops and if i then close the window it starts downloading again.

does anyone know why this is or if there is an alternative to displaying the percentage on the Tkinter window?
Please help

and update_idletasks doesent work

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

留蓝 2024-11-13 14:06:03

用于显示字符串的正确小部件是 标签。您可以使用 configure 方法在运行时更改文本:

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

其次,您将创建两个根窗口 - adminAdmin。奇怪的是,您将列表框放在一个列表框中,而将按钮放在另一个中。 Tk 的设计初衷并非如此。第三,您需要调用(单个)根窗口的 mainloop 方法(例如:Admin.mainloop

最后,关于您的评论,update_idletasks不起作用 - - 请定义“不起作用”。它实际上会更新显示。它不会让您在窗口运行时与窗口交互。

我根据上述注释对您的代码进行了更改(仅创建一个根,使用 Label 而不是 Listbox,并使用 update_idletasks 和程序运行完成,下载歌曲。

调用 update 的危险是:如果您在下载时单击“下载”按钮,那么下次 update< 时会发生什么? 无限循环,而外部循环将无法运行。

/code> 被调用,在该事件的服务中,您将进入一个 正确的解决方案涉及(至少)两种技术之一。一是创建一个线程来执行下载,并让它定期将信息发送回主循环,以便它可以更新进度条。二是利用现有的无限。循环——事件循环——通过使用 after 将作业放入事件队列来一次读取一个块。

互联网上有这两种方法的示例。

The proper widget for displaying a string is a Label. You can change the text at runtime with the configure method:

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

Second, you are creating two root windows - admin and Admin. And strangely, you are putting the listbox in one and the buttons in another. Tk isn't designed to work like that. Third, you need to call the mainloop method of your (single) root window (eg: Admin.mainloop)

Finally, as to your comment that update_idletasks doesn't work -- please define "doesn't work". It will in fact update the display. What it won't do is let you interact with the window while it is running.

I made changes to your code based on the above comments (created only one root, used a Label rather than Listbox, and used update_idletasks and the program ran to completion, downloading the song.

The danger of calling update is this: what if you click the "download" button while you are already downloading? What happens is the next time update is called, that button press will be serviced. In the servicing of that event you'll enter an infinite loop. While that inner infinite loop is running the outer one cannot run. You will have effectively frozen the first download.

The proper solution involves one of (at least) two techniques. One, create a thread to do the downloading, and have it periodically send information back to the main loop so it can update the progress bar. The second is to leverage the already existing infinite loop -- the event loop -- and do your reading of chunks one at a time by placing jobs on the event queue with after.

There are examples on the internet for both approaches.

快乐很简单 2024-11-13 14:06:03

我使用 ttk.Progressbar,您所要做的就是将一个变量与其关联并更新该特定变量。

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

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

i use a ttk.Progressbar, all you have to do is associate a variable to it and update that particular variable.

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

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

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文