Russian Qt Forum

Qt => Общие вопросы => Тема начата: Igors от Декабрь 08, 2014, 12:12



Название: Слот/сигнал без явного источника
Отправлено: Igors от Декабрь 08, 2014, 12:12
Добрый день

Не раз возникает ситуация когда механизм слот/сигнал удобен, но нет явного "источника". Напр я хочу что-то обновить в окне, но сделать это из сугубо расчетной ф-ции которая к QObject не имеет отношения. Как Вы это решаете?

Спасибо


Название: Re: Слот/сигнал без явного источника
Отправлено: Old от Декабрь 08, 2014, 12:15
Позвать метод слот напрямую или использовать QMetaObject::invokeMethod


Название: Re: Слот/сигнал без явного источника
Отправлено: Пантер от Декабрь 08, 2014, 12:43
Позвать метод слот напрямую или использовать QMetaObject::invokeMethod
Еще есть способ через QTimer::singleShot, если задержку надо сделать. Но лучше QMetaObject::invokeMethod (если нужно через ивент систему) или прямой вызов.


Название: Re: Слот/сигнал без явного источника
Отправлено: Igors от Декабрь 08, 2014, 12:49
Напрямую все прелести теряются - надо искать получателя, проверять существует ли он и.т.д. InvokeMethod лучше но также "вываливает все кишки наружу" - не хотелось бы


Название: Re: Слот/сигнал без явного источника
Отправлено: Пантер от Декабрь 08, 2014, 12:54
Тогда через коллбэки. Тем более, в 11 стандарте лямбды появились, что упрощает жизнь.


Название: Re: Слот/сигнал без явного источника
Отправлено: Bepec от Декабрь 08, 2014, 13:03
Создать пару методов, которые в зависимости от аргументов посылают нужный сигнал/ы.


Название: Re: Слот/сигнал без явного источника
Отправлено: GreatSnake от Декабрь 08, 2014, 13:20
Я создаю в производном от QApplication нужные мне методы и вызываю их через QMetaObject::invokeMethod( QCoreApplication::instance(), ... ).


Название: Re: Слот/сигнал без явного источника
Отправлено: Igors от Декабрь 08, 2014, 18:04
Ну а почему не банальный синглтон (унаследованный от QObject)? По крайней мере так расчеты могут ничего не знать о наличии Qt. Или это я "перемудрил"?


Название: Re: Слот/сигнал без явного источника
Отправлено: GreatSnake от Декабрь 08, 2014, 18:08
Ну а почему не банальный синглтон (унаследованный от QObject)?
Дык QApplication как раз оный и есть )


Название: Re: Слот/сигнал без явного источника
Отправлено: Old от Декабрь 08, 2014, 18:14
Ну а почему не банальный синглтон (унаследованный от QObject)? По крайней мере так расчеты могут ничего не знать о наличии Qt. Или это я "перемудрил"?
Мне кажется да.
Почему нельзя расчетные функции положить в класс наследник QObject и использовать штатную систему?
Все равно функции придется модифицировать для сигналинья.


Название: Re: Слот/сигнал без явного источника
Отправлено: _OLEGator_ от Декабрь 08, 2014, 18:23
Может наведет на нужные мысли:
http://www.prog.org.ru/topic_24458_0.html

Там есть класс CXEventMachine, с помощью которого можно подписаться на произвольное событие (используется механизм сигналов/слотов). Событие испускается также с помощью этого класса и раздается всем подписанным.

Подписывание на событие:
Код
C++ (Qt)
CXEventMachine::subscribe(this, PRISM_EVENT(SelectData), PRISM_METHOD(setSelectData()));

Причем SelectData это по сути текстовая метка, это не сигнал и не слот. setSelectData - это слот.

Испускание события:
Код
C++ (Qt)
CXEventMachine::postEvent(PRISM_EVENT(SelectData));

Это события без параметров.

Есть возможность использовать до 3х параметров в событии:
Код
C++ (Qt)
CXEventMachine::postEvent<QString>(PRISM_EVENT(SelectData), "test");


Название: Re: Слот/сигнал без явного источника
Отправлено: Гурман от Декабрь 08, 2014, 19:29
А что мешает поместить расчет в QObject, запустить его в QThread и связать сигнал окончания этой нити с обновлением окна? Я бы так и сделал... Заодно, если расчёт долгий, будет выполняться где-то в фоне, в идеале на выделенном для этого системой ядре.


Название: Re: Слот/сигнал без явного источника
Отправлено: Пантер от Декабрь 08, 2014, 22:06
Ну а почему не банальный синглтон (унаследованный от QObject)? По крайней мере так расчеты могут ничего не знать о наличии Qt. Или это я "перемудрил"?
А зачем синглтон городить там, где он не нужен?


Название: Re: Слот/сигнал без явного источника
Отправлено: GreatSnake от Декабрь 09, 2014, 11:46
Ну а почему не банальный синглтон (унаследованный от QObject)? По крайней мере так расчеты могут ничего не знать о наличии Qt. Или это я "перемудрил"?
А зачем синглтон городить там, где он не нужен?
Иногда удобно, использовать что-то одно в качестве "прокси-ретранслятора".


Название: Re: Слот/сигнал без явного источника
Отправлено: Igors от Декабрь 09, 2014, 14:33
.. Заодно, если расчёт долгий, будет выполняться где-то в фоне, в идеале на выделенном для этого системой ядре.
Чтобы "закрепить ядро" за ниткой - надо сильно постараться, и, насколько помню, такая возможность есть только в unix

Иногда удобно, использовать что-то одно в качестве "прокси-ретранслятора".
Да, примерно такие соображения. Ладно, пока не горит постараюсь осмыслить предложенное _OLEGator_

Спасибо за ответы


Название: Re: Слот/сигнал без явного источника
Отправлено: Гурман от Декабрь 09, 2014, 15:31
Чтобы "закрепить ядро" за ниткой - надо сильно постараться, и, насколько помню, такая возможность есть только в unix

Не надо ничего закреплять, вы же не в реал-тайме. Система сама даст нити ядро, если есть возможность. Я специально проверял - гонял несколько QThread на 4-х ядерном процессоре, смотрел загрузку ядер. В вениках если есть свободное ядро, то новая нить запускается на нём. Прямо видно в таск-менеджере. Если есть 2 ядра и запускаются 2 нити, то они занимают эти 2 ядра. Если одна нить останавливается, то вторая продолжает работать на своём ядре. Думаю, в *nix точно также будет.

А если свободного ядра нет, то закреплять бесполезно - по идее, ядро дадут только в QNX, да и то там какие-то тонкости были.

Зато если ядро есть, а с современными многоядерными процессорами это вполне вероятно, то вычислитель в отдельной QThread получит целиком ядро, будет работать быстрее.


Название: Re: Слот/сигнал без явного источника
Отправлено: Igors от Декабрь 09, 2014, 16:01
Не надо ничего закреплять, вы же не в реал-тайме. Система сама даст нити ядро, если есть возможность. Я специально проверял - гонял несколько QThread на 4-х ядерном процессоре, смотрел загрузку ядер. В вениках если есть свободное ядро, то новая нить запускается на нём. Прямо видно в таск-менеджере. Если есть 2 ядра и запускаются 2 нити, то они занимают эти 2 ядра. Если одна нить останавливается, то вторая продолжает работать на своём ядре. Думаю, в *nix точно также будет.

А если свободного ядра нет, то закреплять бесполезно - по идее, ядро дадут только в QNX, да и то там какие-то тонкости были.

Зато если ядро есть, а с современными многоядерными процессорами это вполне вероятно, то вычислитель в отдельной QThread получит целиком ядро, будет работать быстрее.
С этим никто не спорит. "Закрепить" имелось ввиду что данная нитка исполняется ТОЛЬКО на данном ядре (и ни каком другом). Это сделать непросто (да и не видно зачем). А в общем случае ОС перебрасывает нитку с одного ядра на другое как хочет.


Название: Re: Слот/сигнал без явного источника
Отправлено: Гурман от Декабрь 09, 2014, 16:48
]С этим никто не спорит. "Закрепить" имелось ввиду что данная нитка исполняется ТОЛЬКО на данном ядре (и ни каком другом). Это сделать непросто (да и не видно зачем). А в общем случае ОС перебрасывает нитку с одного ядра на другое как хочет.

Ну и пусть себе перебрасывает. Нужно же было окно вовремя обновлять - чем не вовремя, когда считающая нить завершится? А на каком ядре, другое дело - если повезет, то на отдельном. Если затык был в том, что считающий код ничего про Qt знать не должен - ну и пусть не знает. Я в таком случае сделаю такой код в отдельной DLL, если считающий, так вообще с расширением .c, без ++, а в конструкторе некоего QObject эта считающая DLL будет вручную загружаться. Дальше тривиально...