Russian Qt Forum

Qt => Общие вопросы => Тема начата: Гурман от Июнь 13, 2011, 22:08



Название: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 13, 2011, 22:08
насколько гарантировано их совпадение?

вопрос возник вот из-за чего: нужно динамически иметь возможность менять подключение сигналов и слотов, причем вручную, для чего нужно знать, какие сигналы подключены к конкретному слоту, и к каким слотам подключен конкретный сигнал (чтобы показывать соединение на экране и иметь возможность его менять)

в Qt 4.7 нет нативного способа проверить есть ли соединение между двумя QMetaMethod, входящими в конкретные QMetaObject (увы... увы...) - есть два способа это сделать

1) отслеживать подключения в методе QObject::connectNotify
2) проверять отключением, и если disconnect вернул true, то подключать заново

1й способ выглядит более правильным, но очень громоздким, фактически придется дублировать всю информацию о соединениях сигналов и слотов, правда только о тех, которые нужны

2й способ выглядит хаком, но очень простой и не требует хранения дополнительной информации, правда он возможен только если в connect( object, SIGNAL(somesignal(int,float))... соединялке передается гарантированно тоже самое, что получается от object->metaObject()->method( i /*гарантирует верный метод по индексу*/).signature(), которая возвращает в данном случае const char* с содержимым "somesignal(int,float)"

иначе говоря, есть ли гарантия, что если было сделано однажды (предположим сигнал и слот у объектов единственные)

Код:
connect( object1, SIGNAL(somesignal(float)), object2, SLOT(someslot(float)));
и потом делается
Код:
disconnect( object1, object1->metaObject()->method(0).signature(), object2, object2->metaObject()->method(0).signature() );
то будут разомкнуты только и исключительно те же сигнал и слот, что были соединены?


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Авварон от Июнь 13, 2011, 23:09
Ви таки извгащенец.
Не проще самому эмулировать сигналы/слоты через invokeMethod? Я делал именно так.


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 13, 2011, 23:47
не проще, поскольку сигналы-слоты сделаны с учетом распараллеливания (разные способы доставки), а оно будет, значит в своем механизме тоже придется это делать

то есть, скорее извращение - делать дубль того механизма, который уже есть и работает


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Авварон от Июнь 14, 2011, 00:13
Ну да, гораздо проще использовать сигналы слоты для того, для чего он не предназначены.
и инвок метод тоже тред сэйв да будет известно.


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: LisandreL от Июнь 14, 2011, 01:03
не проще, поскольку сигналы-слоты сделаны с учетом распараллеливания (разные способы доставки), а оно будет, значит в своем механизме тоже придется это делать
QMetaObject::invokeMethod принимает такой же параметр Qt::ConnectionType type, что и подкючение, что и коннект, т.е. хотите - прямой вызов, хотите - через сообщения, хотите - автоматически.


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 14, 2011, 05:25
Цитировать
использовать сигналы слоты для того, для чего он не предназначены

чево??? а для чего они предназначены? ну-ка, ну-ка...  ;D

Цитировать
QMetaObject::invokeMethod принимает такой же параметр Qt::ConnectionType

да при чем тут вообще invokeMethod?... это более низкого уровня механизм, который само по себе мою задачу не решает (сигнал-слоты через него наверняка и работают), значит мне не подходит, а механизм сигналов-слотов подходит, раз он делает ровно то, что мне нужно, значит он для этого и предназначен...

мне надо только иметь возможность наружными по отношению к объектам средствами иметь возможность динамически менять соединения сигналов и слотов - а раз есть connect и disconnect, значит все пучком, не хватает только areconnected и whereconnected

и вообще - если у кого есть что ответить по сути первого сообщения, просьба ответить, а не уводить в сторону, мне это не требуется


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: SASA от Июнь 14, 2011, 10:56
Я бы сделал первым способом.
Отнаследовался бы от QObject, завёл бы в этом классе словарик типа QMap<QString, QList<QPointer<QObjeсt> > >. Т.е. на каждый слот хранить список подключенных и менять его в нотифае. + пару методов получения инфы из этого словаря. А все остальные классы отнаследовать от этого класса. Весь механизм в одном месте. Не больше 100 строчек кода.

Объекты конектятся на уровне Qobject, а не QMetaObject. QMetaObject - набор статичной информации, поэтому механизм надо реализовывать в наследнике QObject.


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: GreatSnake от Июнь 14, 2011, 12:06
Может кто не заметил
Код
C++ (Qt)
int QObject::receivers ( const char * signal ) const [protected]
Цитата: assistant
Returns the number of receivers connected to the signal.


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 14, 2011, 12:48
заметил, только толку от этого никакого нет, это только количество приемников, но не сами приемники, и нет возможности узнать ни количество передатчиков, ни сами передатчики


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: GreatSnake от Июнь 14, 2011, 13:17
заметил, только толку от этого никакого нет, это только количество приемников, но не сами приемники, и нет возможности узнать ни количество передатчиков, ни сами передатчики
Спасибо троллям за заботу о нас :(
Тут, имхо, 2 варианта:
  • пиши свой connect()
  • используй QObjectPrivate


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: m_ax от Июнь 14, 2011, 13:34
Цитировать
вопрос возник вот из-за чего: нужно динамически иметь возможность менять подключение сигналов и слотов, причем вручную, для чего нужно знать, какие сигналы подключены к конкретному слоту, и к каким слотам подключен конкретный сигнал (чтобы показывать соединение на экране и иметь возможность его менять)
ИМХО, но слот - он сам по себе и он не обязан знать какие сигналы его вызывают. Это, я бы сказал, несколько противоречит самому патерну механизма сигнал-слот.
С другой стороны, сигнал (он же передатчик, он же sender) вполне может предоставить информацию о том к каким слотам подключён (например вернуть список указателей на методы (слоты)).

Может boost::signals  для вас будет более гибким в этом отношении..


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 14, 2011, 14:00
Цитировать
лот - он сам по себе и он не обязан знать какие сигналы его вызывают

тем не менее, sender-а узнать легко, правда, увы, только после того, как сигнал пришел

Цитировать
С другой стороны, сигнал (он же передатчик, он же sender) вполне может предоставить информацию о том к каким слотам подключён (например вернуть список указателей на методы (слоты)).

может... я этого ждал где-то с Qt версии 2.х... пока не дождался, приходится корячится

Цитировать
Может boost::signals  для вас будет более гибким в этом отношении..

неее... нельзя смешивать кофе с чаем, невкусно...

а сигнал-слот - великий механизм! (правда недоделанный) я в первом посте не написал очень важный момент - все объекты, и посылающие сигналы, и принимающие их, находятся не в теле приложения, а это плагины, загружаемые динамические библиотеки, соответственно напрямую они вызывать функции друг друга не могут, и к "материнскому приложению" тоже напрямую обращаться не могут, но через сигнал-слоты - запросто, и в отличие от "интерфейсов", если что-то не так, то приложение не рушится



Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 14, 2011, 14:28
ВОТ ЗАРАЗА! то, что дают макросы SIGNAL и SLOT, отличается от сигнатур... макросы добавляют перед именем метода целое число (по-моему, это порядковый номер в таблице методов), а сигнатура возвращает просто имя с параметрами

не, можно конечно и подстроку в сигнатуре поискать... а, не! все гораздо проще

но похоже придется все-таки перейти от 2-го способа, который я уже практически сделал, к первому... изменений не много будет


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: GreatSnake от Июнь 14, 2011, 14:58
ВОТ ЗАРАЗА! то, что дают макросы SIGNAL и SLOT, отличается от сигнатур... макросы добавляют перед именем метода целое число (по-моему, это порядковый номер в таблице методов), а сигнатура возвращает просто имя с параметрами
это тип METHOD/SLOT/SIGNAL, потому можешь смело делать +1


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 14, 2011, 15:29
да, я это вспомнил...


Название: Re: сигнатуры сигналов/слотов в метаметоде и
Отправлено: iks от Июнь 14, 2011, 15:46
Ну по простому, сигнал сам по себе, слот тоже живет отдельной жизнью, они связаны через посредника который слушает определеный сигнал, из указаного ему места и тупо отправляет в слот.
У меня есть проги где несколько виджетов получают инфу от одного сигнала, но там передоваемая инфа, QList и слот принимая ее уже смотрит если первая строка не совпадает с его меткой то он не обращает внимания на то что пришло, если совпала то обрабатывает


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 14, 2011, 17:59
не понятно, к чему все это iks написал, но явно не в ту степь

-----

в общем, пока сделал вариант 2, вроде работает - для тестирования приложение грузит в себя 2 почти одинаковые DLL, в каждой по объекту-истчнику, и он же приемник, приложение формирует при загрузке список загруженных объектов, и привязывается к объектам, чтобы обслуживать связывание сигналов и слотов

когда какому-то объекту вдруг приспичит поменять привязку сигнала, он дергает сигнал, по которому в приложении создается объект, получающий сигнатуру того сигнала или слота, подключение которого надо поменять, он формирует список всех противоположных (для сигнала - слотов, для слота - сигналов) методов других загруженных объектов, и показывает список в листвиджете, в окошке, с флажками вкл-выкл (флажки ессно устанавливаются по состоянию подклчюено или нет)

можно поменять состояния флажков, указав тем самым, новые подключения для текущего сигнала или слота, нажать ОК, и все новые соединения будут установлены, а снятые разорваны...

чтобы все это работало, надо соблюдать одно требование: должны совпадать не только параметры сигнала и слота, которые могут быть соединены, но и их имена - проверка допустимости соединения производится по совпадению имен функций, это специально, чтобы нельзя было соединить абы что с абы чем, только из-за совпадения параметров

пока поиграюсь с таким вариантом, но потом как-нибудь, наверно все-таки переделаю на 1й вариант, с отдельной таблицей, он даст важный бонус - возможность показа не имен классов и методов в них, а произвольные смысловые названия, в том числе, по-русски, но самое главное - соединения так будет проще сохранять и загружать при запуске

мораль - динамически переключать сигналы и слоты друг с другом, по прямому указанию пользователя - не является нерешаемой задачей, и делается относительно несложно

можно будет потом как-нибудь и графический редактор наваять, чтобы просто можно было линии тянуть и ими соединять... и даже нужно будет


Название: Re: сигнатуры сигналов/слотов в метаметоде и SIGNAL/SLOT макросы
Отправлено: Гурман от Июнь 15, 2011, 14:50
.опа - чтобы при соединении сохранять о нём информацию, надо написать надстройки над QObject::connect() и QObject::disconnect, над разными вариантами, то есть, сделать класс-надстройку над самом QObject, а это применимо только в небольшом числе случаев, если объект наследует QObject напрямую (вариант переписывания QObject в исходниках Qt не рассматривается в принципе, поскольку система может пойти на сертификацию)

никаких других вариантов нет, от connectNotify нет никакого толка, поскольку он никак не получает информацию о подключаемом слоте

есть только один вариант узнать, подключен ли сигнал к слоту - это "2-й способ", описанный выше - прошерстить таблицу объектов, для каждого проверить подключение к его метаметодам, правда есть оказывается способ сделать это немного элегантнее - не отключать и потом подключать снова, а попытаться подключить с параметром Qt::UniqueConnection, тогда если уже подключено, то повторная попытка вернет ошибку, а если ошибки нет, то отключить