Название: QueuedConnection Отправлено: Fess от Июнь 02, 2011, 06:10 Извиняюсь за тупой вопрос, но все же.. Объясните пожалуйста, в чем магия?
Минимальный пример: Код: #include <QtGui/QApplication> Каждые 3 секунды посылается сигнал на создание нового диалога и проходит через event loop. Диалог запускается как модальный и по идее выполнение главного потока должно останавливаться пока он не будет закрыт и не будет получен результат от exec(). Но вместо этого постоянно создаются новые диалоги. Если сделать соединение сигнал-слот DirectConnection, то в каждый момент может быть запущен только один диалог. Я хочу понять в чем причина такого поведения при QueuedConnection. Название: Re: QueuedConnection Отправлено: LisandreL от Июнь 02, 2011, 06:43 Диалог запускается как модальный и по идее выполнение главного потока должно останавливаться пока он не будет закрыт и не будет получен результат от exec(). Поток у них один и тот же. Весь GUI живёт в одном потоке.А разница, скорее всего в реализации QTimer. Для QTimer разница следующая: при прямом соединении он не выходит из QTimer::timerEvent, а так и стоит на emit timeout, а при соединении очереди - выходит. Почему не программа не заходит повторно в timerEvent, если в предыдущий раз не вышла? Видимо есть в обработчике событий некоторая защита... Название: Re: QueuedConnection Отправлено: Fess от Июнь 02, 2011, 07:29 QTimer здесь для примера. В моем случае сигналы приходили по сети из другого потока, но поведение аналогичное.
Мне интересно вот с этого момента: Цитировать Qt::QueuedConnection: управление вернулось в event loop, заметило что пришел упакованный в событие сигнал, запустило слот. Слот управление не возвращает и главный поток должен ждать выхода из exec. Однако, события продолжают приходить и слот выполняется снова и снова.The slot is invoked when control returns to the event loop of the receiver's thread. The slot is executed in the receiver's thread. Допустим, event loop работает в отдельном потоке, но слот-то каждый раз выполняется в одном и том же! Название: Re: QueuedConnection Отправлено: LisandreL от Июнь 02, 2011, 07:54 Слот управление не возвращает и главный поток должен ждать выхода из exec. Ну как вам объяснить? Ну нету там главного и неглавного потока. Весь гуй живёт в одном потоке, хоть 100500 модальных диалогов создайте. В модальном диалоге события обрабатываются, значит они обрабатываются и во всём потоке. Именно поэтому, скажем, неактивные (из-за модальности диалога) окна не перестают перерисовываться (то есть для них происходит paintEvent). Просто QEventLoop::ExcludeUserInputEvents в них не принимаются.Название: Re: QueuedConnection Отправлено: GreatSnake от Июнь 02, 2011, 11:30 Модальность окна ни в коей мере не влияет на генерацию событий, но влияет на доставку некоторых.
Название: Re: QueuedConnection Отправлено: Igors от Июнь 02, 2011, 12:04 Если кратко то "Qt так работает" :)
С DirectConnection вызов слота происходит через QMetaObject::activate, который захватывает мутекс объекта, поэтому дальнейшие сигналы (посылаемые ему через direct) не проходят пока мутекс не освобожден. С QueuedConnection вызов идет через placeMetaCall, который такой блокировки не имеет. Практически "этажерка" модальных диалогов ничего хорошего не обещает, лучше разобраться по одному, т.е. проверять уже выскочили с модальностью или как Edit: насчет мутекса это я загнул :) Там проверяется через signal_begin_callback/signal_end_callback - но суть та же |