【问题标题】:wxPython hanging at random points in sequential codewxPython 挂在顺序代码中的随机点
【发布时间】:2018-01-30 16:04:33
【问题描述】:

我有一个简单的应用程序,它为您提供一个按钮,当按下按钮时,会完成一些长时间运行的计算(不是在单独的线程中,不需要单独的线程,因为这些计算是唯一的原因应用程序)。这些计算发生在一个 for 循环中,并且在每次迭代中,for 外观都会对主框架进行回调以更新它,以便显示当前的迭代(与下面的小量表相同)。

    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 并挂起直到完成之前,一切都会顺利进行几秒钟。我并不是说只是手并且没有错误。由于计算是在主循环中完成的,它旨在让应用程序阻塞主循环直到它们完成,但我怀疑在没有交互的情况下随机显示不响应是正常的。计算完成后,应用程序运行正常,但它会在完全随机的点停止响应。

关于为什么会发生这种情况以及应该采取什么措施来解决这个问题的任何建议?

【问题讨论】:

  • 使用线程或 wxThread。不要在主(GUI)线程上做任何事情(尤其是长时间运行的)。
  • 为什么?我解释了为什么我没有在我的问题中使用线程,所以请告诉我为什么应该使用线程。此外,无论有无线程,行为都是完全相同的。这是我尝试的第一件事
  • ....因为使用线程会阻​​止您尝试解决的问题....

标签: python user-interface crash wxpython wxwidgets


【解决方案1】:

GUI 更新已排队。
假设您的代码如下所示:

myLongTask
{
    loop:
        ... do something
        UpdateGUI()
    end loop
}

每次调用UpdateGUI() 时都会向操作系统发送一条消息,然后控件立即返回并继续循环。

操作系统何时有机会处理该消息?运行那个循环太忙了。

您可以使用wx.Yield 或更好地为长任务设置一个线程,将消息发送到请求更新的操作系统。

查看更多here

【讨论】:

  • 所以它会因为队列已满而停止?意思可能是每个循环结束时的sleep 10 ms 可以解决问题并让操作系统完成它? (我实际上并没有考虑使用它,只是想了解根本原因)
  • @RaresDima,你误会了。不是队列变满了。主线程正忙于循环计算,它没有时间/资源来更新 GUI。这是不可能的。正如 Rip2 所建议的 - 使用 wx.Yield() 到 give the program an opportunity to update the GUI 或使用线程并将消息从工作线程发送到主线程以更新 GUI。基本上你没有给程序更新仪表的机会 - 希望这句话能清除它。
  • sleep 只保存当前线程。如果你只有一个线程(即主线程),它将保持,并且在 sleep-lap 期间不会做任何事情,也不会更新。
猜你喜欢
  • 1970-01-01
  • 2023-03-11
  • 2020-09-18
  • 1970-01-01
  • 2020-03-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-11-19
相关资源
最近更新 更多