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

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

Страниц: [1]   Вниз
  Печать  
Автор Тема: Threads & GUI  (Прочитано 6099 раз)
Winstrol
Гость
« : Июнь 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
Гость
« Ответ #1 : Июнь 25, 2009, 23:17 »

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

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

и по подробнее напиши что ты хочешь всем этим получить, а то я посмотрел на код что-т не особо понял смысла во всём этом!!!
« Последнее редактирование: Июнь 25, 2009, 23:27 от Makss » Записан
Winstrol
Гость
« Ответ #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 » Записан
ритт
Гость
« Ответ #3 : Июнь 26, 2009, 00:27 »

добавь в диалог мутекс и связывай не с экзеком диалога, а со слотом, в котором мутекс будет блокироваться до выхода из слота, а выход из слота - по окончанию работы экзека
Записан
Winstrol
Гость
« Ответ #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-потоке. Как реализовать?
Записан
ритт
Гость
« Ответ #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)
Записан
Winstrol
Гость
« Ответ #6 : Июнь 26, 2009, 14:59 »

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

в твоём случае, возможно, следует пойти по проторенному пути - стэк с инфой для диалога, защищённый локером - после закрытия первого диалога открывается второй и т.д. (см. QMessageBox)
Меня бы и стандартная очередь событий устроила бы. Я почему-то думал, что модальные диалоги блокируют обработку старой очереди и начинают свою локальную очередь.
Записан
SABROG
Гость
« Ответ #7 : Июнь 26, 2009, 15:23 »

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


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