移动Tkinter窗口时程序停止

2 投票
1 回答
606 浏览
提问于 2025-04-16 17:06

你好!

我写了一个音乐下载程序,运行得很好,它会告诉你下载进度百分比。但是如果我稍微移动一下窗口,下载就会停止。

我又写了一个小脚本,可以下载网上指定的mp3文件,移动窗口的时候它不会停止,随便怎么动都没问题。

我之所以不分享我的代码,是因为它实在太长了,大约有1500行。不过我可以分享这个小脚本,用来下载一个文件。

有没有人知道为什么我的程序会停止工作呢?

这个小脚本是:

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

listbox = Listbox(admin, bg="PURPLE")
listbox.pack()
def __init__(self, master):

        def replay():
            Admin.destroy()
            os.system('WhaleWire.exe')

        frame = Frame(master)
        frame.pack()




        image1 = PhotoImage(file="whalewire.gif")
        w = image1.width()
        h = image1.height()

        master.geometry("%dx%d+0+0" % (w, h))

        # tk.Frame has no image argument

        panel1 = Label(master, image=image1)
        panel1.pack(side='top', fill='both', expand='yes')

        panel1.image = image1
        self.e = Entry(frame)
        self.e.grid(row=0, column=0)



        b = Button(frame, text='Search', command=self.whale)
        b.grid(row=0, column=1)
        def library():
            path = 'C:\WhaleWire\Downloaded'
            aw=[]
            for infile in glob.glob( os.path.join(path,'*.mp3') ):
                libr = infile.split('Downloaded',1)


                aw.append('\n')
                aw.append(infile)
                la = Label(Admin,width=100,height=50, text=aw).grid(row=0,column=7)
                b2s = Button(Admin,text='Search', command=replay).grid(row=0,column=8)
        b11 = Button(frame, text='Library', command=library)
        b11.grid(row=0, column=3)   
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()

1 个回答

2

很可能你遇到的问题是因为你在调用 update。除非你非常清楚这样做的后果,否则最好不要这样做。调用 update 会让程序进入一个新的事件循环。简单来说,你就会在一个无限循环里再套一个无限循环。

试试把你的 update 改成 update_idletasks,看看这样能不能解决你的问题。这个 update 的变体只处理一些“空闲”事件,比如屏幕重绘,出问题的可能性要小得多。

另外,你完全不需要写“update; insert; delete; update”这样的代码。这不会有什么明显的效果。在删除操作后,只需要调用一次 update_idletasks 就足够了。

最后,你可以通过重新安排你的代码来完全避免使用 update_idletasks。写一个函数来读取一小块数据并更新进度条。如果还没有到达文件末尾(EOF),就用 after 在几毫秒后再次调用这个函数。当到达文件末尾时,它就会停止调用自己。这样做的好处是你不需要自己创建一个可能无限的循环,事件循环每次迭代时都会被保证进入一次。一旦检测到文件末尾,你就可以再用 after 调用一个函数来进行最后的处理。

撰写回答