Russian Qt Forum

Qt => Общие вопросы => Тема начата: UVV от Июль 28, 2014, 17:34



Название: Как обработать сигнал в главном Event Loop
Отправлено: UVV от Июль 28, 2014, 17:34
Привет.
Можно ли как-то выйти из локального Event Loop и обработать сигнал в главном?
Лень переписывать всю портянку ещё раз, вот изначальный вопрос: http://stackoverflow.com/questions/24933461/close-all-widgets-in-qt-except-for-some


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Old от Июль 28, 2014, 17:52
А мне лень копипастить вопрос в Гугл переводчик и пытаться понять, что он там на переводил. ;)


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: UVV от Июль 28, 2014, 18:02
А мне лень копипастить вопрос в Гугл переводчик и пытаться понять, что он там на переводил. ;)

Как ты работаешь без английского? :-\


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Old от Июль 28, 2014, 18:08
Как ты работаешь без английского? :-\
Если мне что-то не понятно, то я смотрю исходники. :)
Это наш основной язык для общения.


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: UVV от Июль 28, 2014, 18:16
Если мне что-то не понятно, то я смотрю исходники. :)
Это наш основной язык для общения.

И много "вас" там?


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Old от Июль 28, 2014, 18:23
И много "вас" там?
Знающих языки программирования? Не так много конечно, как знающих английский, но есть ещё. :)


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Igors от Июль 28, 2014, 18:58
Лень переписывать всю портянку ещё раз, вот изначальный вопрос: http://stackoverflow.com/questions/24933461/close-all-widgets-in-qt-except-for-some
Ответ на изначальный вопрос: перед тем как выполнять процедуру закрытия всех окон - надо проверить есть ли активное модальное окно. Если есть то процедуру отложить - ничем добрым она не кончится.

Можно ли как-то выйти из локального Event Loop и обработать сигнал в главном?
Не вижу как этот вопрос связан с изначальным. Какая разница из какого loop получен сигнал? Что Вы хотите?


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Bepec от Июль 28, 2014, 19:11
Вопрос связан с тем, что QMessageBox запускают собственный луп и плюют на остальные.

А ответ в принципе вот
Цитировать
Warning: Do not delete parent during the execution of the dialog. If you want to do this, you should create the dialog yourself using one of the QMessageBox constructors.


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Old от Июль 28, 2014, 19:30
перед тем как выполнять процедуру закрытия всех окон - надо проверить есть ли активное модальное окно. Если есть то процедуру отложить - ничем добрым она не кончится.
Никаких проблем не будет.
У меня есть комплекс, который при разрыве связи с сервером данных закрывает все открытые модальные диалоги, причём они отрабатывают так, как будто пользователь нажимал Cancel.
Т.е. все обработчики корректно отрабатывают и главное окно замораживается, до восстановления соединения. Количество последовательно открытых модальных диалогов значения не имеет.


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Bepec от Июль 28, 2014, 19:39
Хоть способ приведите как вы все модальные закрываете :)


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Old от Июль 28, 2014, 19:49
Хоть способ приведите как вы все модальные закрываете :)
Код
C++ (Qt)
#ifndef DIALOGCLOSER_H
#define DIALOGCLOSER_H
 
#include <QObject>
 
class DialogCloser : public QObject
{
Q_OBJECT
public:
explicit DialogCloser( QObject *parent = 0 );
 
signals:
void finished();
 
public slots:
void start();
};
 
#endif // DIALOGCLOSER_H
 

Код
C++ (Qt)
#include "dialogcloser.h"
#include <QApplication>
#include <QWindow>
#include <QCloseEvent>
 
DialogCloser::DialogCloser( QObject *parent ) :
QObject( parent )
{
}
 
void DialogCloser::start()
{
QWindow *wnd = QApplication::modalWindow();
if( wnd )
{
QCloseEvent ev;
QApplication::sendEvent( wnd, &ev );
QMetaObject::invokeMethod( this, "start", Qt::QueuedConnection );
}
else
{
deleteLater();
emit finished();
}
}
 

Использовать так:
Код
C++ (Qt)
void ConnectManager::beginDeactivate()
{
       DialogCloser *cls = new DialogCloser;
       connect( cls, SIGNAL(finished()), SLOT(deactivate()) );
       cls->start();
}
 

После закрытия всех диалогов, будет вызван слот deactivate(). Сам объект closer убивается сам.


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Bepec от Июль 28, 2014, 20:24
Благодарю. Метод modalWindow вижу в первый раз, но теперь запомнил :)


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: UVV от Июль 28, 2014, 20:41
...

Спасибо, занятно, но не выстреливает ввиду:
http://qt-project.org/doc/qt-5/qguiapplication.html
Цитировать
Since:   Qt 5.0
Желательно бы для 4.6-4.8.

Есть несколько вопросов.
1. Это работает только для своих диалогов. Есть ли у тебя обработка QMessageBox::warning и т.п.?
2. Нельзя было сразу ответить на вопрос без ответвления всторону от темы? =)


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: Old от Июль 28, 2014, 20:51
Желательно бы для 4.6-4.8.
Нужно подумать, думаю можно сделать и без этого метода.


1. Это работает только для своих диалогов. Есть ли у тебя обработка QMessageBox::warning и т.п.?
Это работает с любыми диалогами.

2. Нельзя было сразу ответить на вопрос без ответвления всторону от темы? =)
Я до конца не знал, что же нужно в конечном итоге. Почему и напмсал сообщение, что бы ты по русски написал, что же хочешь получить. :)


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: kambala от Июль 28, 2014, 21:04
QApplication::activeModalWidget()


Название: Re: Как обработать сигнал в главном Event Loop
Отправлено: UVV от Июль 29, 2014, 11:49
Всем спасибо. Я отписал ответ в той теме на stackoverflow.
В двух словах: получилось закрыть сначала модальные, а потом обычные. Моя проблема была в том, что в цикле поиска модальных присутствовал тест на
Код:
!w->objectName().isEmpty()
, который фильтровал MessageBox'ы.
Поскольку QWidget::close() использует deleteLater, то виджеты удаляются в правильном порядке.