Russian Qt Forum
Март 11, 2010, 15:52 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

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

Страниц: [1]
  Печать  
Автор Тема: Threads & GUI  (Прочитано 835 раз)
Winstrol
Самовар
**
Offline Offline

Сообщений: 133


Просмотр профиля
« : Июнь 25, 2009, 23:13 »

Господа, есть такая проблема.
Код
C++ (Qt)
 
struct Thread : QThread
{
   Q_OBJECT
signals:
   void sig();
protected:
   void run ()
   {
       emit sig();
       exec();
   }
};
...
QDialog* dlg;
...
 
{
 
   dlg=new QDialog();
   dlg->setWindowModality(Qt::ApplicationModal);
   dlg->show();
 
   Thread *t1,*t2;
   t1 = new Thread();
   t2 = new Thread();
   t1->moveToThread(t1);
   t2->moveToThread(t2);
   QObject::connect(t1,SIGNAL(sig()),dlg,SLOT(exec()));
   QObject::connect(t2,SIGNAL(sig()),dlg,SLOT(exec()));
   t1->start();
   t2->start();
   return;
}
 

Имеются два потока, отсылающих сигналы в GUI поток.
В GUI-слоте получаю рекурсивный вызов.
Warning: QDialog::exec: Recursive call detected

Как сделать блокировку обработки сообщений в очереди главного окна после первого вызова exec()?
Чтобы в очереди сообщений открытого модально QDialog'a не обрабатывался второй вызов exec()?
Записан
Makss
Чайник
*
Offline Offline

Сообщений: 50


Просмотр профиля
« Ответ #1 : Июнь 25, 2009, 23:17 »

Цитировать
t1->moveToThread(t1);
    t2->moveToThread(t2);

а тебе не кажется это лишним?

и по подробнее напиши что ты хочешь всем этим получить, а то я посмотрел на код что-т не особо понял смысла во всём этом!!!
« Последнее редактирование: Июнь 25, 2009, 23:27 от Makss » Записан
Winstrol
Самовар
**
Offline Offline

Сообщений: 133


Просмотр профиля
« Ответ #2 : Июнь 25, 2009, 23:38 »

Цитировать
t1->moveToThread(t1);
    t2->moveToThread(t2);

а тебе не кажется это лишним?
http://vingrad.ru/blogs/sabrog/2009/06/11/qt-45-movetothread-ili-metod-myunhgauzena/

и по подробнее напиши что ты хочешь всем этим получить, а то я посмотрел на код что-т не особо понял смысла во всём этом!!!
Есть основной GUI-поток и два дочерних (методы Thread::run). Они сигналят друг другу. Когда два потока отсылают сигнал GUI-потоку, добавляется два события в очередь. Когда извлекается первое и запускается QDialog::exec() получается отсутсвие модальности. Второе событие извлекается из очереди до закрытия модального диалога. Как-то так. А мне бы модальность...

« Последнее редактирование: Июнь 25, 2009, 23:39 от Winstrol » Записан
Константин
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2304



Просмотр профиля
« Ответ #3 : Июнь 26, 2009, 00:27 »

добавь в диалог мутекс и связывай не с экзеком диалога, а со слотом, в котором мутекс будет блокироваться до выхода из слота, а выход из слота - по окончанию работы экзека
Записан

qt4.6.0+
Gentoo ~amd64 / winxpprosp2

Qt - Qt Development Frameworks; QT - QuickTime
/* кто этого не знает - идиот! */
Winstrol
Самовар
**
Offline Offline

Сообщений: 133


Просмотр профиля
« Ответ #4 : Июнь 26, 2009, 08:24 »

добавь в диалог мутекс и связывай не с экзеком диалога, а со слотом,
На самом деле у меня так и есть. Пример умышленно рафинирован.
в котором мутекс будет блокироваться до выхода из слота, а выход из слота - по окончанию работы экзека
Цитировать
void QMutex::lock ()
Locks the mutex. If another thread has locked the mutex then this call will block until that thread has unlocked it.
Calling this function multiple times on the same mutex from the same thread is allowed if this mutex is a recursive mutex. If this mutex is a non-recursive mutex, this function will dead-lock when the mutex is locked recursively.

Попытаюсь еще упростить задачу. Есть два не GUI-потока, которые периодически инспирируют отображение модального(-ых) диалога в GUI-потоке. Как реализовать?
Записан
Константин
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2304



Просмотр профиля
« Ответ #5 : Июнь 26, 2009, 14:05 »

Цитировать
void QMutex::lock ()
Locks the mutex. If another thread has locked the mutex then this call will block until that thread has unlocked it.
Calling this function multiple times on the same mutex from the same thread is allowed if this mutex is a recursive mutex. If this mutex is a non-recursive mutex, this function will dead-lock when the mutex is locked recursively.

QReadWriteLock, QMutex, QSemaphore - базовые механизмы синхронизации - выбирай тот, что более подходит для конкретной ситуации.

в твоём случае, возможно, следует пойти по проторенному пути - стэк с инфой для диалога, защищённый локером - после закрытия первого диалога открывается второй и т.д. (см. QMessageBox)
Записан

qt4.6.0+
Gentoo ~amd64 / winxpprosp2

Qt - Qt Development Frameworks; QT - QuickTime
/* кто этого не знает - идиот! */
Winstrol
Самовар
**
Offline Offline

Сообщений: 133


Просмотр профиля
« Ответ #6 : Июнь 26, 2009, 14:59 »

QReadWriteLock, QMutex, QSemaphore - базовые механизмы синхронизации - выбирай тот, что более подходит для конкретной ситуации.
У меня всего один GUI поток Улыбающийся Остальные сигналят слоты GUI потока, сиречь кладут QMetaCallEvent в очередь событий.

в твоём случае, возможно, следует пойти по проторенному пути - стэк с инфой для диалога, защищённый локером - после закрытия первого диалога открывается второй и т.д. (см. QMessageBox)
Меня бы и стандартная очередь событий устроила бы. Я почему-то думал, что модальные диалоги блокируют обработку старой очереди и начинают свою локальную очередь.
Записан
SABROG
phpBB Супер
******
Offline Offline

Сообщений: 1054



Просмотр профиля
« Ответ #7 : Июнь 26, 2009, 15:23 »

Подключи сигналы к слоту в гуишном потоке и проверяй через QWidget::isVisible(), а там уже exec() или done() + exec(). Ну или show(), если тебе так удобней.
Записан

Национальная группа Russian Federation на QtCentre.
Qt: 4.6.2 GCC: 4.4.0TDM
We'd get - widget!
Страниц: [1]
  Печать  
 
Перейти в:  

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