当前位置: 首页 > 知识库问答 >
问题:

Tkinter不确定进度条未运行

秦锐
2023-03-14

我目前正在为Python2.7创建Tkinter Gui,但无法使用进度条。我需要将较大的文件加载到我的程序中,这需要一些时间,所以我想获得一个进度条,向用户显示程序没有冻结加载文件。不幸的是,在加载文件时,我的进度条似乎没有更新:(我已经尝试为进度条创建一个新线程,但没有成功。所以我想知道,在一个沉重的函数调用期间,我需要做什么才能让一个不确定的进度条运行?

我的代码的相关部分是:

import Tkinter as tk
import ttk as ttk
import pandas as pd
import tkFileDialog as tfgiag

self.pb = ttk.Progressbar(frame, orient=tk.VERTICAL, mode='indeterminate')
mynewdata = tfgiag.askopenfilenames(parent=root,title='Choose a file',filetypes=[('CSV files', '.csv')])
self.t = threading.Thread(target = self.pb.start)
self.t.start()  
#read in each CSV file selected by the user
for myfile in root.tk.splitlist(mynewdata): 
    foo = pd.read_csv(myfile)    
    self.data.appendMainData(foo)
self.pb.stop()

共有2个答案

东方骏
2023-03-14

在每个self.pb.step(x)语句后使用self.frame.update_idletasks(),其中'x'代表进度条值增加的值

朱阳曜
2023-03-14

Python“线程”仍然被称为GIL的全局解释器锁按顺序锁定在一起。这基本上意味着,从同一个python进程生成的线程不会像您希望的那样并行运行。相反,他们都在主python进程上争取时间。

在你的例子中,如果有一个密集的进程你试图用once进程来监控,它可能占用了GIL,而不是将其释放到线程中。

一个选择:尝试使用readline方法,这样它就可以分割文件输入,足以插入进度条更新行。

openfile = open(filename, 'r')
for eachline in openfile.readlines():
    append_line(eachline)
    update_progressBar()

另一个可能更容易的选择是使用python的多处理模块将csv打开转移到另一个进程。这模拟了您可能更习惯的线程。我将启动一个新进程,读取csv,并将这些行附加到队列中。完成后,在队列中附加一个sentinel值,表示其已完成,以便主进程知道何时停止更新进度条,并加入生成的进程。比如:

import Tkinter as tk
import ttk as ttk
import pandas as pd
import tkFileDialog as tfgiag
from multiprocessing import Process, Queue

self.pb = ttk.Progressbar(frame, orient=tk.VERTICAL, mode='indeterminate')
mynewdata = tfgiag.askopenfilenames(parent=root,title='Choose a file',filetypes=[('CSV files', '.csv')])

csvqueue=Queue(1) #A mp-enabled queue with one slot to results.
#read in each CSV file selected by the user
offloadedProcess=Process(target=csvread, args=(filename, outputqueue))
offloadedProcess.start()
procNotDone=False
while procNotDone:
    result = getNewResultFromQueue(outputqueue) #pesudo code
    update_ProgressBar() #<--- this should get hit more often now
    if result.isLastValue:
        offloadedProcess.join() #Join the process, since its now done
    else:
        csvresults.append(result)


def csvreadOffload(filename, outputqueue):
    for myfile in root.tk.splitlist(mynewdata): 
        foo = pd.read_csv(myfile)    
        if foo is not END:#Pesudo code here
            outputqueue.append(foo)
        else:
            outputqueue.append('Empty results')#pseudo code
 类似资料:
  • 问题内容: 我试图将其插入数据库的一个表,但是此过程需要几分钟。 在我的应用程序尝试插入时,我希望有一个不确定的进度栏。为了有进度条,我想使用JavaFX,但是我不知道如何实现它,直到插入数据库过程结束为止,它才显示出来。 问题答案: JavaFX任务可能是解决之道。它们提供了一种在后台执行长时间运行的任务而不冻结用户界面的方法。 这是您可以尝试的示例: 如果您知道任务将包含多少部分,则此版本将更

  • 这是我第一次在C#中使用进度条。我的代码正在复制一些文件,我想通过进度条显示进度。 我不喜欢我的代码的一点是,我必须遍历所有文件来设置最大值...后来我再次经历同样的过程来复制文件。 我只是想不出一个方法来确保在酒吧里流利的进步而不这样做。我首先必须知道最大值对吗?或者有什么诀窍吗? 代码如下所示: > 设置最大值: 复制文件: 增加进度条: 私有静态无效记录器(字符串输出){log.Text=“

  • 我的kivy应用程序中有一个ProgressBar。我相信我需要使用,以确保从循环内部更新进度条。 以下代码是用于再现性目的的淡化版本。 ProgressBar类 主要类别: KV文件 此示例显示loading_pb.value按钮单击后代码循环时发生的变化。 进步吧。价值印刷输出 问题进度条的值似乎确实如预期的那样递增,但实际进度条直到循环结束时才立即改变。 相关的 无法更新kivy进度条 ki

  • 我试图用python模块tkinter创建一个带有输入框的窗口,来制作一个石头剪刀剪纸游戏。然而,每次按下按钮时,我都在努力使输入框更新到另一个值。 我正在纠结的是,如果我要编写作为输入(假设计算机响应始终为0): 那么我的输出将是这是正确的,但是,如果我的下一个输入是一些随机的东西,如,则所需的输出将是。然而,似乎第一个输入被保存并继续使用,因为输出仍然是。 另一方面,如果我们从输入开始,则输出

  • 使用一些额外的类和一些巧妙的浏览器特有的 CSS,样式化 HTML5 的<progress> 元素。确保你阅读了浏览器支持。 <progress class="progress" value="0" max="100">0%</progress> <progress class="progress" value="25" max="100">25%</progress> <progress c

  • 进度条 <div class="ui-progress"> <span style="width:50%"></span> </div> 图片上进度条 <ul class="ui-grid-halve"> <li> <div class="ui-grid-halve-img"> <span style="background-ima