Модераторы: Daevaorn
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> интересные вещи с Qt4, странности работы с GUI 
:(
    Опции темы
X-3R1
Дата 28.4.2007, 01:59 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 28.4.2007

Репутация: 1
Всего: 2



Есть такой код
Код

connectButton->setDisabled(true);
statusStr = QString ("VPN started");
emit setStatus(statusStr);

...
//долгий цикл
for(...;...;...)
{
     ;
}


Проблема заключается в том, что пока цикл не отработает, свойство connectButton и сигнал setStatus не вступят в силу. Хотя по логике вещей 
Код

connectButton->setDisabled(true);
emit setStatus(statusStr);

должны выполняться в месте вызова.

Кто-нибудь уже сталкивался  с такой проблемой, или знает как всё расставить на свои места?
PM MAIL   Вверх
Ken
Дата 28.4.2007, 15:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Как вы хотели увидеть вступление в силу 
Код
 connectButton->setDisabled(true) 
?

Если вы хотите видеть изменение внешнего вида connectButton то этого не произойдет пока ваша подпрограмма не завершится и управление не вернется в цикл сообщений. Потому что перерисовка идет не сразу. Всего лишь вызывается метод invalidate () который просто генерирует сообщение о перерисовке.

Есть несколько простых правил: 1) Не использовать длинные вычисления в GUI потоке, постарайтесь как можно поскорее делать свои дела и вернуться в цикл сообщений; 2) Если длинные вычисления неизбежны, постарайтесь делить их на разные короткие фазы и активизировать их периодически, например, через таймер (
Код
 void timerEvent () 
). Каждая фаза быстро делает свою работу, сохраняет свое состояние для очередной фазы, обновляет прогресс-бар и т.д. и выходит. 3) Иногда разделить длинных вычислений довольно неудобно, это может сильно изородовать код, в таких случаюх используйте отдельные потоки для длинных вычислений.

Это сообщение отредактировал(а) Ken - 28.4.2007, 15:33
PM MAIL   Вверх
nickless
Дата 28.4.2007, 15:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Гентозавр
****


Профиль
Группа: Участник Клуба
Сообщений: 2976
Регистрация: 29.8.2005
Где: Germany

Репутация: 19
Всего: 181



Насколько я знаю emit работает асинхронно, т.е. слоты вполне могут быть вызваны когда до них дойдёт очередь, попробуй вызвать setStatus напрямую.


--------------------
user posted image

Real men don't use backups, they post their stuff on a public ftp server and let the rest of the world make copies
- Linus Torvalds
PM MAIL   Вверх
Ken
Дата 28.4.2007, 15:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Цитата(nickless @ 28.4.2007,  15:27)
Насколько я знаю emit работает асинхронно, т.е. слоты вполне могут быть вызваны когда до них дойдёт очередь, попробуй вызвать setStatus напрямую.

Не всегда. 

emit работает асинхронно только тогда когда connect сигнала и слота делается с аргументом Qt::QueuedConnection. Или Qt::AutoConnection и emit вызывается из другого потока. В остальных случаях emit прямо вызывает метод.

Это сообщение отредактировал(а) Ken - 28.4.2007, 15:38
PM MAIL   Вверх
X-3R1
Дата 28.4.2007, 16:20 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 28.4.2007

Репутация: 1
Всего: 2



Цитата(Ken @  28.4.2007,  13:19 Найти цитируемый пост)
) Иногда разделить длинных вычислений довольно неудобно, это может сильно изородовать код, в таких случаюх используйте отдельные потоки для длинных вычислений.


Т.е. для того чтобы реализовать то что задумал надо "вычисления" выполнять в основном потоке, а "текущее состояние" выводить в GUI в другом потоке?)

>попробуй вызвать setStatus напрямую
Вряд ли поможет, т.к. свойства connectButton приходят в силу также после "вычислений".

PM MAIL   Вверх
Ken
Дата 28.4.2007, 16:49 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 47
Регистрация: 31.3.2007

Репутация: 2
Всего: 4



Цитата(X-3R1 @ 28.4.2007,  16:20)
Т.е. для того чтобы реализовать то что задумал надо "вычисления" выполнять в основном потоке, а "текущее состояние" выводить в GUI в другом потоке?)

Длинных вычислений выполнять как раз в другом потоке надо чтобы долго не блокировать цикл сообщений.

Добавлено @ 17:01
Постарайтесь не использовать потоков если можете разделить свои вычисления на мелкие фазы. Потому что с появлением потоков вам придется заниматься еще с синхронизацией потоков, отлаживать таких програм иногда бывает непросто. Но если все таки решили использовать потоки то постарайтесь прямо не вызвать методы GUI объектов из вашего потока, вместо этого сгенерируйте сигналы (emit) и обязательно связывайте их с вашими слотами через Qt::QueuedConnection. Это будет гарантировать что все GUI методы будут вызваны в основном потоке (GUI потоке).

Это сообщение отредактировал(а) Ken - 28.4.2007, 17:04
PM MAIL   Вверх
X-3R1
Дата 28.4.2007, 17:33 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Шустрый
*


Профиль
Группа: Участник
Сообщений: 63
Регистрация: 28.4.2007

Репутация: 1
Всего: 2



2Ken, благодарю за помощь
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "С++:Общие вопросы"
Earnest Daevaorn

Добро пожаловать!

  • Черновик стандарта C++ (за октябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика(4.4мб).
  • Черновик стандарта C (за сентябрь 2005) можно скачать с этого сайта. Прямая ссылка на файл черновика (3.4мб).
  • Прежде чем задать вопрос, прочтите это и/или это!
  • Здесь хранится весь мировой запас ссылок на документы, связанные с C++ :)
  • Не брезгуйте пользоваться тегами [code=cpp][/code].
  • Пожалуйста, не просите написать за вас программы в этом разделе - для этого существует "Центр Помощи".
  • C++ FAQ

Если Вам понравилась атмосфера форума, заходите к нам чаще! С уважением, Earnest Daevaorn

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | C/C++: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.3542 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.