【发布时间】: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:。
那么,如何在不使用step 和update_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