Russian Qt Forum
Ноябрь 24, 2024, 10:29 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: ProcessEvents только для определенного окна  (Прочитано 10899 раз)
SABROG
Гость
« : Июль 24, 2007, 11:21 »

В асистанте есть пример QProgressDialog, там используется qApp->processEvents(). Мне не надо вызывать евенты всех окон моей программы, а только одного QProgressDialog. Дело в том, что QProgressDialog вызывается очень быстро, когда в моей программе идет работа с кучей мелких файлов, в итоге я не вижу диалога, однако интерфейс главного окна "размораживается", что может привести к нежелательным последствиям, т.к. все кнопочки нажимаются во время работы метода. Есть возможность вызывать processEvents только для определенного окна ?
Записан
Alex Forth
Гость
« Ответ #1 : Июль 24, 2007, 11:27 »

Сделай модальный диалог
Записан
SABROG
Гость
« Ответ #2 : Июль 24, 2007, 11:57 »

Он и так модальный. Просто класс QProgressDialog создается каждый раз заново в методе на каждый файл. Поэтому, когда он уничтожается, то главное окно тоже обновляется. Я просто убрал вызов qApp->processEvents() и QProgressDialog нормально отрисовывается и обновляется, проблема сама собой разрешилась. Видимо троли оставили пример со старых версий.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #3 : Июль 24, 2007, 12:04 »

Цитата: "SABROG"
Я просто убрал вызов qApp->processEvents() и QProgressDialog нормально отрисовывается и обновляется, проблема сама собой разрешилась. Видимо троли оставили пример со старых версий.



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

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

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
SABROG
Гость
« Ответ #4 : Июль 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'ах.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #5 : Июль 24, 2007, 16:17 »

Написана интересная вещи про setValue:

Цитировать

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


Это все объясняет Улыбающийся
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
SABROG
Гость
« Ответ #6 : Июль 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);
Записан
lenny
Гость
« Ответ #7 : Март 11, 2011, 19:14 »

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

Извиняюсь, разобрался. Странно получается. Если в теле цикла меняешь что то на форме, то оно отрисовывается, пока не ткешь куда мышкой(вызовешь событие), потом все замирает. 1С 7 напоминает. Получается без QApplication::processEvents() никуда.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.049 секунд. Запросов: 23.