pythontkinter:使用多线程时进度条出现故障

2024-09-24 06:29:20 发布

您现在位置:Python中文网/ 问答频道 /正文

请运行以下示例。在

我已经为我的应用程序创建了一个进度条,按“打开”按钮就会弹出一个进度条。但是,进度条没有填满,并且脚本似乎在停止

bar.set(i)

调用ProgressBarLoop函数时。在

^{pr2}$

编辑:

尝试了达诺的答案后,它起作用了,但我得到了以下错误:

Exception in thread Thread-1:
Traceback (most recent call last):
  File "/mnt/sdev/tools/lib/python2.7/threading.py", line 551, in __bootstrap_inner
    self.run()
  File "/mnt/sdev/tools/lib/python2.7/threading.py", line 504, in run
    self.__target(*self.__args, **self.__kwargs)
  File "/home/jun/eclipse/connScript/src/root/nested/test.py", line 88, in ProgressBarLoop
    bar.set(i)
  File "/home/jun/eclipse/connScript/src/root/nested/test.py", line 61, in set
    self.setBar()
  File "/home/jun/eclipse/connScript/src/root/nested/test.py", line 64, in setBar
    self.canvas.coords(self.progressBar,0, 0, self.width * self.progress/100.0, self.height)
  File "/mnt/sdev/tools/lib/python2.7/lib-tk/Tkinter.py", line 2178, in coords
    self.tk.call((self._w, 'coords') + args)))
RuntimeError: main thread is not in main loop

Tags: 进度条inpyselfhomeliblinetools
1条回答
网友
1楼 · 发布于 2024-09-24 06:29:20

问题是,在启动线程后立即运行无限循环:

def onOpen(self, event = None):
   self.loading = True
   bar = ProgressBar(self, width=150, height=18)
   thread.start_new_thread(ProgressBarLoop, (self, bar))
   while(True):  # Infinite loop
      pass

因此,控件永远不会返回到Tk事件循环,因此进度条永远无法更新。如果删除循环,代码应该可以正常工作。在

另外,您应该使用^{}模块而不是{}模块,如Python docs中所建议的那样:

Note The thread module has been renamed to _thread in Python 3. The 2to3 tool will automatically adapt imports when converting your sources to Python 3; however, you should consider using the high-level threading module instead.

总而言之,以下是onOpen应该是什么样子:

^{pr2}$

编辑:

尝试从多个线程更新tkinter小部件有些麻烦。当我在三个不同的系统上尝试这个代码时,我得到了三个不同的结果。避免了任何线程化方法中的错误:

def ProgressBarLoop(window, bar, i=0):
    bar.configure(mode = 'percent', progressformat = 'ratio')
    if not window.loading:
        bar.hide()
        return
    bar.set(i)
    print "refreshed bar"
    i+=1
    if i == 101:
        # Reset the counter
        i = 0
    window.root.after(1, ProgressBarLoop, window, bar, i)

但实际上,如果我们不在ProgressBarLoop中使用无限循环,就根本不需要使用单独的线程。这个版本的ProgressBarLoop可以在主线程中调用,并且GUI不会被阻塞很长时间。在

相关问题 更多 >