Когда мы вызываем
Во время обработки события могут генерироваться другие события, которые ставятся в конец очереди событий Qt. Если слишком много времени уходит на обработку одного события, интерфейс пользователя становится невосприимчивым к действиям пользователя. Например, любые сгенерированные оконной системой события во время сохранения файла на диск не будут обрабатываться до тех пор, пока весь файл не будет записан. В ходе записи файла приложение не будет отвечать на запросы оконной системы на перерисовку приложения.
Одно из решений заключается в применении многопоточной обработки: один процесс для работы с интерфейсом пользователя приложения и другой процесс для выполнения операции сохранения файла (или любой другой длительной операции). В этом случае интерфейс пользователя приложения сможет реагировать на события в процессе выполнения операции сохранения файла. Мы рассмотрим способы обеспечения такого режима работы в главе 18.
Более простое решение заключается в выполнении частых вызовов функции
Ниже приводится пример того, как мы можем сохранить работоспособность интерфейса пользователя при помощи функции
01 bool Spreadsheet::writeFile(const QString &fileName)
02 {
03 QFile file(fileName);
04 …
05 for (int row = 0; row < RowCount; ++row) {
06 for (int column = 0; column < ColumnCount; ++column) {
07 QString str = formula(row, column);
08 if (!str.isEmpty())
09 out << quint16(row) << quint16(column) << str;
10 }
11 qApp->processEvents();
12 }
13 return true;
14 }
При использовании этого метода существует опасность того, что пользователь может закрыть главное окно во время выполнения операции сохранения файла или даже выбрать повторно File | Save, что приведет к непредсказуемому результату. Наиболее простое решение заключается в замене вызова
qApp->processEvents();
на вызов
qApp->processEvents(QEventLoop::ExcludeUserInputEvents);
который указывает Qt на необходимость игнорирования событий мышки и клавиатуры.
Часто нам хочется показывать индикатор состояния процесса
01 bool Spreadsheet::writeFile(const QString &fileName)
02 {
03 QFile file(fileName);
04 …
05 QProgressDialog progress(this);
07 progress.setLabelText(tr("Saving %1").arg(fileName));
08 progress.setRange(0, RowCount);
09 progress.setModal(true);
10 for (int row = 0; row < RowCount; ++row) {
11 progress.setValue(row);
12 qApp->processEvents();
13 if (progress.wasCanceled()) {
14 file.remove();
15 return false;
16 }