Russian Qt Forum

Qt => Пользовательский интерфейс (GUI) => Тема начата: Winstrol от Июнь 25, 2009, 23:13



Название: Threads & GUI
Отправлено: 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()?


Название: Re: Threads & GUI
Отправлено: Makss от Июнь 25, 2009, 23:17
Цитировать
t1->moveToThread(t1);
    t2->moveToThread(t2);

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

и по подробнее напиши что ты хочешь всем этим получить, а то я посмотрел на код что-т не особо понял смысла во всём этом!!!


Название: Re: Threads & GUI
Отправлено: Winstrol от Июнь 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() получается отсутсвие модальности. Второе событие извлекается из очереди до закрытия модального диалога. Как-то так. А мне бы модальность...



Название: Re: Threads & GUI
Отправлено: ритт от Июнь 26, 2009, 00:27
добавь в диалог мутекс и связывай не с экзеком диалога, а со слотом, в котором мутекс будет блокироваться до выхода из слота, а выход из слота - по окончанию работы экзека


Название: Re: Threads & GUI
Отправлено: Winstrol от Июнь 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-потоке. Как реализовать?


Название: Re: Threads & GUI
Отправлено: ритт от Июнь 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)


Название: Re: Threads & GUI
Отправлено: Winstrol от Июнь 26, 2009, 14:59
QReadWriteLock, QMutex, QSemaphore - базовые механизмы синхронизации - выбирай тот, что более подходит для конкретной ситуации.
У меня всего один GUI поток :) Остальные сигналят слоты GUI потока, сиречь кладут QMetaCallEvent в очередь событий.

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


Название: Re: Threads & GUI
Отправлено: SABROG от Июнь 26, 2009, 15:23
Подключи сигналы к слоту в гуишном потоке и проверяй через QWidget::isVisible(), а там уже exec() или done() + exec(). Ну или show(), если тебе так удобней.