Читаем QT 4: программирование GUI на С++ полностью

Ниже приводится пример того, как мы можем сохранить работоспособность интерфейса пользователя при помощи функции processEvents, причем за основу взят программный код сохранения файла в приложении Spreadsheet:

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 на необходимость игнорирования событий мышки и клавиатуры.

Часто нам хочется показывать индикатор состояния процесса QProgressDialog в ходе выполнения продолжительной операции. QProgressDialog имеет полоску индикатора, информирующую пользователя о ходе выполнения операции приложением. QProgressDialog также содержит кнопку Cancel, которая позволяет пользователю прекратить выполнение операции. Ниже приводится программный код, применяющий данный подход при сохранении файла приложения Электронная таблица:

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 }

17 for (int column = 0; column < ColumnCount; ++column) {

18 QString str = formula(row, column);

19 if (!str.isEmpty)

20 out << quint16(row) << quint16(column) << str;

21 }

22 }

23 return true;

24 }

Мы создаем QProgressDialog, в котором RowCount является общим количеством шагов. Затем при обработке каждой строки мы вызываем функцию setValue для обновления состояния индикатора. QProgressDialog автоматически вычисляет процент завершения операции путем деления текущего значения индикатора на общее количество шагов. Мы вызываем функцию QApplication::processEvents для обработки любых событий перерисовки либо нажатия пользователем кнопки мышки или клавиши клавиатуры (например, чтобы разрешить пользователю нажимать кнопку Cancel). Если пользователь нажимает кнопку Cancel, мы прекращаем операцию сохранения файла и удаляем файл.

Мы не вызываем для QProgressDialog функцию show, так как индикатор состояния сам делает это. Если оказывается так, что операция выполняется быстро, прежде всего из-за малого размера файла или высокого быстродействия компьютера, QProgressDialog обнаружит это и вообще не станет выводить себя на экран.

Перейти на страницу:
Нет соединения с сервером, попробуйте зайти чуть позже