wxPython висит в случайных точках в последовательном коде

У меня есть простое приложение, которое представляет вам кнопку, когда кнопка нажата, некоторые длительные вычисления выполняются (не в отдельном потоке, нет необходимости в отдельном потоке, так как эти вычисления являются единственной причиной приложения), Эти вычисления выполняются в цикле 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 в строке заголовка и висит, пока не завершится. Я не имею в виду только руки и не показывает ошибки. Поскольку вычисления выполняются в основном цикле, оно предназначено для того, чтобы приложение блокировало основной цикл до тех пор, пока они не будут выполнены, но я сомневаюсь, что это нормально, чтобы случайным образом показывать отсутствие ответа без взаимодействия с ним. После того, как вычисления сделаны, приложение ведет себя нормально, но перестает отвечать в совершенно случайных точках.

Любой совет относительно того, почему это происходит и что нужно сделать, чтобы это исправить?

1 ответ

Обновления GUI стоят в очереди.
Давайте предположим, что ваш код выглядит так:

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

Каждый раз, когда вы звоните UpdateGUI() сообщение отправляется в ОС, и элемент управления немедленно возвращается и продолжает цикл.

Когда ОС имеет возможность обрабатывать это сообщение? Он слишком занят выполнением этого цикла.

Вы могли бы использовать wx.Yield или лучше установить поток для длинной задачи, который отправляет сообщения ОС, запрашивающие обновление.

Подробнее здесь

Другие вопросы по тегам