Индикатор выполнения над getOpenFileName

В моем приложении у меня есть следующая строка, которая открывает диалоговое окно файла. Как только я получаю имя файла, я делаю кучу обработки, которая занимает довольно много времени, и как только это будет сделано, рабочая область готова для пользователя.

filename, _ = QtGui.QFileDialog.getOpenFileName(self, 'Open file', os.curdir, "*.cws")

Диалоговое окно файла - это модальное окно (по умолчанию), которое прекрасно, потому что не позволяет пользователю делать глупости, пока рабочая область еще не готова к использованию. Я хочу поместить индикатор выполнения где-нибудь, чтобы дать представление о том, сколько было обработано. Я сделал еще одно диалоговое окно, которое отображает индикатор выполнения и некоторую другую информацию.

Теперь, так как диалоговое окно файла является модальным, оно просто застыло, пока обрабатывается мое рабочее пространство, а диалоговое окно прогресса появляется только после того, как все сделано.

Я смотрел на настройку диалогового окна файла, чтобы не модальное, но я не думаю, что это возможно. Я подумал, может быть, заставить его закрыться, и сразу же появится диалоговое окно моего прогресса и перенять модальность. Как программно закрыть диалоговое окно файла? Я не знаю, как получить ссылку на форму.

Или, может быть, у вас есть лучшее предложение о том, как решить эту проблему?

1 ответ

Как упомянул thuga, цикл обработки событий вашего приложения застрял из-за тяжелой обработки. Таким образом, события (и особенно события рисования) не обрабатываются во время работы, что приводит к зависанию графического интерфейса.

На мой взгляд, у вас есть 2 варианта:

Принудительно обрабатывать события (не очень стильно, но может работать):

Это зависит от того, как выполняется ваша "тяжелая обработка". Предполагая, что код, висящий в цикле, находится "под вашими руками" (не в сторонней lib). Вы можете добавить в него как можно больше вызовов QApplication.processEvents.

Если обработка основана на цикле, она может выглядеть следующим образом:

for item in itemList:
    ...processitem...
    QtGui.QApplication.processEvents()

Это основной недостаток добавления зависимостей в GUI в части кода, о которых не следует знать. Если ваш код не основан на цикле, вам придется добавить несколько вызовов processEvents, которые будут загрязнять код обработки.

Хватит вешать цикл событий (более сложный, но более понятный)

Это означает, что вам придется иметь дело с потоками и / или подпроцессами, как предложил Thuga. Это решение предполагает, что код GUI и бизнес-код достаточно хорошо разделены.

Вы можете взглянуть на эту статью из Qt Quarterly, которая дает некоторые основные моменты по этой проблеме. Из-за Python Global Interpreter Lock (GIL) вы можете не увидеть лучшие результаты с потоками. Рассмотрите возможность использования многопроцессорной библиотеки.

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