【问题标题】:Indeterminate ttk Progressbar doesn't update unless forced不确定的 ttk 进度条不会更新,除非强制
【发布时间】:2015-01-22 07:30:22
【问题描述】:

我有一个 tkinter GUI,它允许用户在 sqlite 数据库上执行搜索。数据库不是静态的,因此不知道每次搜索需要多长时间。该应用程序是单线程的(我想保持这种方式)。因此,我想要一个进度条(或动画)来重新向用户保证在搜索进行时正在发生某些事情。乍一看,ttk.ProgressBar 似乎可以通过其indeterminate 模式来解决问题,但它似乎不像TkDocs. 中详述的那样工作

对于不确定的进度 TkDocs 状态...

...在操作开始时,您只需调用进度条的“start”方法,在操作结束时,您将调用它的“stop”方法。进度条会处理剩下的事情。

...但情况似乎并非如此。如果我在执行我的 sqlite 查询之前只使用.start(),并在完成后使用.stop(),进度条会出现但根本没有动画。

如果我在for 循环中执行sqlite select 语句并包含prog.step()prog.update_idletasks(),我可以强制它更新。但这会影响性能,并且只有在返回多行时才真正起作用,因为循环是 for row in select_statement:

那么,如何在不使用stepupdate_idletask 强制执行的情况下让不确定的进度条(或动画)在单个线程上进行动画处理?


代码。这不起作用...

prog = ttk.ProgressBar(root,mode='indeterminate')
...
prog.start()
result = None
try:
    conn = sqlite3.connect(database)
    result = conn.execute('select * from table where a=? and b=?',(var1,var2))
    result = result.fetchall()
    conn.close()
except:
    handle the exception
prog.stop()

工作正常,但很hacky。

prog = ttk.ProgressBar(root,mode='indeterminate')
...
prog.start()
result = None
try:
    for row in conn.execute('select * from table where a=? and b=?',(var1,var2)):
        result.append(row)
        prog.step()
        prog.update_idletasks()
    conn.close()
except:
    handle the exception
prog.stop()

【问题讨论】:

  • 你的程序有.mainloop()吗?
  • 是的。这一切都发生在用户从root 窗口打开的toplevel 窗口中,其mainloop 已被初始化。
  • 虽然您已经说过您希望保持单线程,但我想说,为了从 GUI 中获得平稳的反应,您最好在第二个线程中进行查询,这样您可以启动进度条,让主线程回到主循环。
  • 我同意詹姆斯的观点。请阅读this answer,如果您还没有完全开悟,请告诉我。 ;-]

标签: python python-3.x tkinter ttk


【解决方案1】:

因此,使用您的第二个工作代码块并重构进度条更新可以清理一切。

prog = ttk.ProgressBar(root,mode='indeterminate')
...
prog.start()

def progress():
    prog.step()
    prog.update_idletasks()

with sqlite3.connect(database) as conn:
     conn.set_progress_handler(handler=progress, n=1)
     database_query = conn.execute('select * from table where a=? and b=?',(var1,var2))
     result = database_query.fetchall()

【讨论】:

  • 但这和第二个例子有同样的问题吗,progress 只有在找到一行并添加到列表时才会被调用?如果扫描了一百万行并且只返回一行会发生什么?进度条会增加一次吗?
  • 啊,我明白你在找什么了。看起来 set_progress_handler 是您正在寻找的。 sqlite.org/c3ref/progress_handler.html我更新了我的答案以满足您的要求。
  • 这看起来很有希望,但目前我无法让它工作,因为该方法需要 progress 函数以外的输入,我有点难过这些价值观应该是什么。我会玩一玩的。
  • 是的,很难找到文档,很抱歉没有链接它! Here's the link,参数是处理函数,然后是每个函数调用之间的迭代次数。我用正确的约定更新了代码
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-12-01
  • 2013-09-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多