我有一个简单的应用程序,它为您提供一个按钮,当按下按钮时,一些长时间运行的计算完成(不是在单独的线程中,不需要单独的线程,因为这些计算是唯一的原因该应用程序)。这些计算发生在for循环中,并且在每次迭代时,for look都会对主框架进行回调以更新它,以便显示当前的迭代次数(相同的下面填充的小规格)。
def _delay(self):
for i in range(15000):
self.update_stats(f'{i}', i)
def on_button_click(self, event):
self.init_completion_gauge(15000)
self._delay()
self.set_state_comparison_done()
def init_completion_gauge(self, maxval):
self.gauge.SetRange(maxval)
self.Layout()
self.Update()
def update_stats(self, current_iter, count):
self.label_current_iter.SetLabelText(
'\n'.join((f'Iter:', current_iter)))
self.gauge.SetValue(count)
self.label_percent_complete.SetLabelText(
f'{(count + 1) * 100 // self.gauge.GetRange()}%')
self.Layout()
self.Update()
当这个运行时,一切都会顺利进行几秒钟,然后应用程序会在标题栏中显示Not responding
并挂起,直到完成为止。我的意思不仅仅是双手而且没有错误。由于计算是在主循环中完成的,因此应用程序会阻止主循环直到它们完成,但我怀疑随机显示没有响应而不进行交互是正常的。计算完成后,应用程序运行正常,但它会在完全随机的点停止响应。
关于为什么会发生这种情况以及应该采取什么措施来解决这个问题的任何建议?
答案 0 :(得分:1)
GUI更新排队。
假设您的代码如下:
myLongTask
{
loop:
... do something
UpdateGUI()
end loop
}
每次调用UpdateGUI()
时,都会向操作系统发送一条消息,控件会立即返回并继续循环。
操作系统何时能够处理该消息的机会?它太忙于运行这个循环。
您可以使用wx.Yield
或更好地为长任务设置线程,该线程将消息发送到请求更新的操作系统。
查看更多here