Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: SABROG от Июль 24, 2007, 11:21



Название: ProcessEvents только для определенного окна
Отправлено: SABROG от Июль 24, 2007, 11:21
В асистанте есть пример QProgressDialog, там используется qApp->processEvents(). Мне не надо вызывать евенты всех окон моей программы, а только одного QProgressDialog. Дело в том, что QProgressDialog вызывается очень быстро, когда в моей программе идет работа с кучей мелких файлов, в итоге я не вижу диалога, однако интерфейс главного окна "размораживается", что может привести к нежелательным последствиям, т.к. все кнопочки нажимаются во время работы метода. Есть возможность вызывать processEvents только для определенного окна ?


Название: ProcessEvents только для определенного окна
Отправлено: Alex Forth от Июль 24, 2007, 11:27
Сделай модальный диалог


Название: ProcessEvents только для определенного окна
Отправлено: SABROG от Июль 24, 2007, 11:57
Он и так модальный. Просто класс QProgressDialog создается каждый раз заново в методе на каждый файл. Поэтому, когда он уничтожается, то главное окно тоже обновляется. Я просто убрал вызов qApp->processEvents() и QProgressDialog нормально отрисовывается и обновляется, проблема сама собой разрешилась. Видимо троли оставили пример со старых версий.


Название: ProcessEvents только для определенного окна
Отправлено: pastor от Июль 24, 2007, 12:04
Цитата: "SABROG"
Я просто убрал вызов qApp->processEvents() и QProgressDialog нормально отрисовывается и обновляется, проблема сама собой разрешилась. Видимо троли оставили пример со старых версий.



имхо повезло что обновляеться. На другой платформе может не проканать. processEvents() нужен, чтобы твой интерфейс не замёрз

ЗЫ: Приведи код, как ты создаешь и работаешь с QProgressDialog, а то несовсем ясно, что ты стремишся получить


Название: ProcessEvents только для определенного окна
Отправлено: SABROG от Июль 24, 2007, 12:55
Это метод выполнения SQL запросов из предварительно подготовленного QStringList'a. Соответственно для прогрессбара 100%=количеству запросов. И замуты с транзакциями, если хотябы один запрос выдаст ошибку, то все предыдущие запросы из QStringList'a аннулируются.

Код:

bool TForm::listExec(QSqlDatabase db, QStringList &list)
{
    sabQuery query(db);
        if (db.transaction())
        {
            QProgressDialog pd(tr("Operation in progress."), tr("Cancel"),0,list.size(),this);
            pd.setWindowModality(Qt::WindowModal);
            for (int i=0; i < list.size(); i++)
            {
                if (!query.exec(list.at(i)))
                {
                        if (!db.rollback())
                        {
                            qDebug(qPrintable(db.lastError().text()));
                        }
                    return false;
                }
                pd.setValue(i);
                //qApp->processEvents();
                    if (pd.wasCanceled())
                    {
                        if (!db.rollback())
                        {
                            qDebug(qPrintable(db.lastError().text()));
                        }
                    return false;
                    }
            }
            if (!db.commit())
            {
                qDebug(qPrintable(db.lastError().text()));
            }
            else
            {
                pd.setValue(list.size());
                return true;
            }
        }
    return false;
}


добавлено спустя 43 минуты:

 
Цитата: "pastor"

имхо повезло что обновляеться. На другой платформе может не проканать. processEvents() нужен, чтобы твой интерфейс не замёрз


Может дело не в везении, тут написано, что каждый модальный диалог имеет свой QEventLoop:

Цитировать

Generally speaking, no user interaction can take place before calling exec(). As a special case, modal widgets like QMessageBox can be used before calling exec(), because modal widgets use their own local event loop.


Таким образом я делаю вывод, что для модальных диалогов не нужен qApp->processEvents. Может я и ошибаюсь, хотелось бы, чтобы кто-нибудь проверил эту докадку на lunix'ах.


Название: ProcessEvents только для определенного окна
Отправлено: pastor от Июль 24, 2007, 16:17
Написана интересная вещи про setValue:

Цитировать

Warning: If the progress dialog is modal (see QProgressDialog::QProgressDialog()), this function calls QApplication::processEvents() ...


Это все объясняет :)


Название: ProcessEvents только для определенного окна
Отправлено: SABROG от Июль 24, 2007, 16:21
На самом деле не объясняет, я не вижу разницы между qApp->processEvents() и QApplication::processEvents(). Если между методами нет разницы, то почему главное окно ведет себя по-разному. Когда сам вызываю - то эвенты вызываются для главного окна тоже, когда сам не вызываю, то главное окно не обновляется и ведет себя как надо.

Я разобрался в чем прикол. В Ассистанте указан пример того как не заморживать главное окно при показе QProgressDialog. Для меня это вылилось в пользование главным окном во время переходов с одного файла на другой. Таким образом, достаточно просто убрать processEvents из этого кода, и в этом случае диалог будет обновляться как и раньше без проблем:

Код:

Using a modal QProgressDialog is simpler for the programmer, but you must call QApplication::processEvents() or QEventLoop::processEvents(ExcludeUserInput) to keep the event loop running to ensure that the application doesn't freeze. Do the operation in a loop, call setValue() at intervals, and check for cancellation with wasCanceled(). For example:
     QProgressDialog progress("Copying files...", "Abort Copy", 0, numFiles, this);
     progress.setWindowModality(Qt::WindowModal);

     for (int i = 0; i < numFiles; i++) {
         progress.setValue(i);
         qApp->processEvents();

         if (progress.wasCanceled())
             break;
         //... copy one file
     }
     progress.setValue(numFiles);


Название: Re: ProcessEvents только для определенного окна
Отправлено: lenny от Март 11, 2011, 19:14
UP
Таж фигня. progressBar обновляется и без processEvents(); Это очень хорошо!
имхо повезло что обновляеться. На другой платформе может не проканать. processEvents() нужен, чтобы твой интерфейс не замёрз
Такое и правда может быть?


Название: Re: ProcessEvents только для определенного окна
Отправлено: lenny от Март 11, 2011, 19:34
Извиняюсь, разобрался. Странно получается. Если в теле цикла меняешь что то на форме, то оно отрисовывается, пока не ткешь куда мышкой(вызовешь событие), потом все замирает. 1С 7 напоминает. Получается без QApplication::processEvents() никуда.