Версия для печати темы

Нажмите сюда для просмотра этой темы в обычном формате

Форум на CrossPlatform.RU _ Qt Общие вопросы _ Есть ли метод, чтобы узнать соединен ли сигнал со слотом?

Автор: ViGOur 26.11.2008, 20:10

Цитата(kwisp @ 26.11.2008, 17:58) *
всем привет.
может я собираюсь написать об очевидной штуке, но однако меня она удивила.

1. если соединить один и тот же сигнал с одним и тем же слотом несколько раз(n), и вызвать сигнал один раз, то
слот вызовется столько раз сколько соединений с этим сигналом мы сделали(n)....

2. если разъединить сигнал со слотом - то рушатся все соединения этого сигнала с этим слотом.

... известен ли кому нибудь метод узнать соединен ли сигнал со слотом и если соединен то сколько раз???
Для этого как я понимаю нужно использовать класс: http://crossplatform.ru/documentation/qtdoc4.3/qmetaobject.php.

Автор: kwisp 26.11.2008, 20:14

я вот поискал в QMetaObject и не нашел:(....
и больше того начал крутить функции данного класса. у меня в 4,4,3 версии QMetaObject::indexOfSlot(SLOT(myslot())) всегда возвращает -1не зависимо от того соединен слот или нет есть он или нет. короче странное что то...
я остановился на том что нет механизма узнать соединен ли слот с сигналом и сколько таковых соединений.

Автор: ViGOur 26.11.2008, 20:19

тоесть примерно при таком вызове:

Цитата(cpp)
this->metaObject()->indexOfSlot(SLOT(myslot()));
???

нужно будет завтра самомы проверить, а то qt под рукой нет.

Автор: kwisp 26.11.2008, 20:24

да вызов и такой пробовал и не только такой.

Автор: ViGOur 1.12.2008, 17:54

Цитата(kwisp @ 26.11.2008, 20:14) *
QMetaObject::indexOfSlot(SLOT(myslot())) всегда возвращает -1

Оказалось все просто, нужно вызывать так:
QMetaObject::indexOfSlot( "myslot()")
:)

Автор: kwisp 1.12.2008, 18:41

Цитата(ViGOur @ 1.12.2008, 17:54) *
Оказалось все просто, нужно вызывать так:
QMetaObject::indexOfSlot( "myslot()")
:)


прикольно получается.
жаль что это все равно не поможет мне узнать колличество соединений между сигналом и слотом.:(

Автор: ViGOur 1.12.2008, 19:36

Цитата(kwisp @ 1.12.2008, 18:41) *
жаль что это все равно не поможет мне узнать колличество соединений между сигналом и слотом.
У меня пока получилось только получить все методы объекта, с сигналами и слотами с помощью QMetaObject, поэтому думаю нужно капать в другую сторону, как будет время капну... :)

Автор: kwisp 5.12.2008, 10:16

из переписки с технической поддержкой:
"
...
Unfortunately we dont have any such convenience function which tells how
many times a signal is being connected with a slot.

Indeed I dont see any good use case for such function.

I can create a suggestion task for our developers if I get some generic
good use case for such functionality.


Regards,
I. Omair

--
Irfan Omair
Support Engineer
Nokia Inc, Redwood City
http://www.trolltech.com
"

думаю тему можно закрыть. :)

Автор: kuler 5.12.2008, 16:36

а в чем собсна проблема? это как в анекдоте: бабка врачу: сынок я когда делаю вот так (нагибается), то у меня спина болит. Врач: дык не делайте так. Следующий!

Автор: Litkevich Yuriy 5.12.2008, 18:00

Цитата(kuler @ 5.12.2008, 19:36) *
а в чем собсна проблема?
в этом:
Цитата(kwisp @ 26.11.2008, 20:58) *
если соединить один и тот же сигнал с одним и тем же слотом несколько раз(n), и вызвать сигнал один раз, то
слот вызовется столько раз сколько соединений с этим сигналом мы сделали

Автор: kuler 5.12.2008, 18:42

Цитата(Litkevich Yuriy @ 5.12.2008, 18:00) *
Цитата(kuler @ 5.12.2008, 19:36) *
а в чем собсна проблема?
в этом:
Цитата(kwisp @ 26.11.2008, 20:58) *
если соединить один и тот же сигнал с одним и тем же слотом несколько раз(n), и вызвать сигнал один раз, то
слот вызовется столько раз сколько соединений с этим сигналом мы сделали


ну так я ж и ответил - не фиг соединять по пять раз

Автор: Litkevich Yuriy 5.12.2008, 21:02

Цитата(kuler @ 5.12.2008, 21:42) *
не фиг соединять по пять раз
это можно и случайно сделать

Автор: kwisp 6.12.2008, 20:06

Цитата(kuler @ 5.12.2008, 18:42) *
ну так я ж и ответил - не фиг соединять по пять раз


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

и вообще ты хочешь сказать ты это раньше знал или для тебя это было очевидно и ясно как день???

Автор: kuler 8.12.2008, 15:51

Цитата(kwisp @ 6.12.2008, 20:06) *
для тебя это было очевидно и ясно как день??


"если соединить один и тот же сигнал с одним и тем же слотом несколько раз(n), и вызвать сигнал один раз, то
слот вызовется столько раз сколько соединений с этим сигналом мы сделали(n)...." - про это не знал
Цитата(kwisp @ 26.11.2008, 20:14) *
я остановился на том что нет механизма узнать соединен ли слот с сигналом и сколько таковых соединений.

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

Автор: kwisp 8.12.2008, 17:54

несогласен, зачем свой счетчик если в библиотеке все для этого есть и разработчикам просто метод дописать надо???
думаю это задача разработчиков, следить за колличеством соединений.

а мне так проще разъединить и соединить по новой, разъединение убивает все предыдущие соединения. тем более что в моем проекте происходит это не часто.

если честно я и класс и тупое сопоставление каждого коннекта со счетчиком слабо себе представляю...

kuler, ты наверное не знаешь но тема перенесена из "Секреты и интересные возможности Qt" - это просто обнаруженная интересная штука, а во все не проблема.

Автор: kuler 18.12.2008, 16:29

из мануала про connect
A signal is emitted for every connection you make, so if you duplicate a connection, two signals will be emitted. You can always break a connection using disconnect().

Автор: Litkevich Yuriy 27.12.2008, 18:19

предлагаю этой темой и тем чем вызвана данная дискусия пополнить ЧаВО: http://wiki.crossplatform.ru/index.php/Сигналы_и_слоты_(Qt)

Автор: Константин 11.2.2009, 6:30

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

Q_SIGNALS:
    void doSomething(int state, const QVariant& param0, const QVariant& param1));

в противном же случае советую использовать customEvent:
Цитата
void QObject::customEvent ( QEvent * event ) [virtual protected]

This event handler can be reimplemented in a subclass to receive custom events. Custom events are user-defined events with a type value at least as large as the QEvent::User item of the QEvent::Type enum, and is typically a QEvent subclass. The event is passed in the event parameter.

Автор: kwisp 11.2.2009, 9:25

Константин,
здравствуйте.
у меня два вопроса к вам.

Цитата
....для задачи, описанной kwisp, ...

1. Из каких источников вы знаете мою задачу и можете ли её сформулировать яснее?
Цитата
...сигналы-слоты - не совсем верный подход...

2. Почему для моей задачи "не совсем верный"(звучит так же как чуть чуть беременна :) ) подход?

заранее спасибо.

Автор: berserk 11.2.2009, 9:46

а в слоте счетчик описать нельзя?

Автор: Litkevich Yuriy 11.2.2009, 9:58

Цитата(berserk @ 11.2.2009, 12:46) *
а в слоте счетчик описать нельзя?
можно, если ты слот сам пишешь, здесь и сейчас. А если он от стандартного виджета или самописаной библиотечки? Не переделывать же ее.

Автор: kwisp 11.2.2009, 9:59

berserk,
примерчик подскажешь, мне уже не нужно, просто ради интерса....

Автор: Константин 11.2.2009, 9:59

1.

Цитата(kwisp @ 6.12.2008, 20:06) *
к примеру: в зависимости набора событий, на определенный хот кей программа должна реагировать по разному, короче в зависимости от обстоятельств у меня сигнал высылаемый фильтром событий клавиатуры соединяется то с одним обработчиком(слотом) то с другим то с третим, при это с остальными разъединяется.

задача-пример, если угодно.

2. "не совсем верный подход" потому, что он в общем случае верный и реализуется проще, но в конкретных случаях этот подход неоптимален (частое "передёргивание" коннектов - не есть гут)

Автор: kwisp 11.2.2009, 10:12

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

Цитата
частое "передёргивание" коннектов - не есть гут

100% так
но
кто сказал что оно частое?

+

тема называется "Есть ли метод, чтобы узнать соединен ли сигнал со слотом?"
а не "Как мне сделать то то и то то??? помогите есть ли у кого идеи."

внимание вопрос:
метод есть?
уже выснили что стандартного нет.
или все же есть?

Автор: Litkevich Yuriy 11.2.2009, 10:18

Мысль вслух:
1) когда мы в своей программе создаем соединения, то все эти соединения описываются в файле moc_***.cpp.
2) когда мы создаем несколько одинаковых соединений, то слот будет вызван столько раз сколько соединений - значит счетчик есть.

Может стоит попытаться работать с этими moc_***.cpp файлами?

Автор: kwisp 11.2.2009, 10:28

Litkevich Yuriy,

Цитата
значит счетчик есть.

думаю не факт.
смотрел исходники moc???
там не все гладко.

да и вообще нужно ли это? если только для интересу. :)

получается надо просто написать ИЗБЕГАЙТЕ РЕАЛИЗАЦИИ ДИНАМИЧЕСКОЙ МАШИНЫ СОСТОЯНИЙ с помощью сигналов и слотов дабы избежать проблем с много кратным соединением.
используйте колбэки что угодно но не сигналы и слоты даже если соединения редко используемые.

я приводил ответ троллех-тех.поддержки. "нету и не зачем" я так понял.

хотя если спмостоятельно написать мини патч и отправить тролям с подробным обоснованием нафига это надо. думаю они будут рады и даже скажут спасибо. :)

Автор: kuler 11.2.2009, 10:46

разве нельзя создать маленький класс в котором будет счетчик и через который будет производиться коннект, а потом наследовать от него?

Автор: kwisp 11.2.2009, 10:57

Цитата(kuler @ 11.2.2009, 10:46) *
разве нельзя создать маленький класс в котором будет счетчик и через который будет производиться коннект, а потом наследовать от него?


напиши если тебе интеерсна эта тема.
а я будет время залезу в мок и посмотрю что там.

Автор: Константин 11.2.2009, 11:10

Цитата(Litkevich Yuriy @ 11.2.2009, 10:18) *
Мысль вслух:
1) когда мы в своей программе создаем соединения, то все эти соединения описываются в файле moc_***.cpp.
2) когда мы создаем несколько одинаковых соединений, то слот будет вызван столько раз сколько соединений - значит счетчик есть.

Может стоит попытаться работать с этими moc_***.cpp файлами?

1. соединения не описываются нигде. QObject::connect соединяет сигнал со слотом (или с сигналом) рантайм - по имени/индексу сигнала/слота
2. счётчика как такового нет, есть список коннектов, в котором при желании можно было бы посчитать определённые индексы


Цитата(kwisp @ 11.2.2009, 10:28) *
я приводил ответ троллех-тех.поддержки. "нету и не зачем" я так понял.

хотя если спмостоятельно написать мини патч и отправить тролям с подробным обоснованием нафига это надо. думаю они будут рады и даже скажут спасибо. :)

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

Автор: kwisp 11.2.2009, 11:35

Константин,
действительно, а смогу ли я обосновать необходимость такового счетчика???
я думаю что смогу.
есть функция QObject::connect() и QObject::disconnect() следовательно предполагается возможность динамического соединение и разъединение сигналов и слотов??? не правда ли??? почему я не могу узнать сколько раз вызовется мой слот при одном вызове сигнала господа трольтеховцы (0-вообще не соединен на данный момент, 1,2,3 ... 10)???
вот и все обоснование. только конечно более литературно написать.

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

вообще не хочу разводить полемику по данному поводу ,Константин, изначально был просто пост
в теме "секреты и интересные возможности Qt" где я описал найденный минисекрет и отсутсвие может быть ненужной возможности. вот и все это просто интересный факт а не способ и метод решения моей задачи моя машина уже как сто лет написана без динамических соединений. а обнаружен факт случайно и в ассистенте 3 версии как минимум не описан.
просто факт как есть и все.
говорю же если кому интересно может рыть и писать в этой теме свои решения это странности.

Автор: berserk 11.2.2009, 11:41

Цитата(kwisp @ 11.2.2009, 9:59) *
berserk,
примерчик подскажешь, мне уже не нужно, просто ради интерса....


Книжка "QT. Профессиональное программирование на С++" стр 45 (немного под себя только модифицировать). Больше примеров не знаю... Самому написать щас некогда.

Автор: kwisp 11.2.2009, 11:56

Цитата(berserk @ 11.2.2009, 11:41) *
Книжка "QT. Профессиональное программирование на С++" стр 45 (немного под себя только модифицировать). Больше примеров не знаю... Самому написать щас некогда.


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

Автор: berserk 11.2.2009, 12:01

Цитата(kwisp @ 11.2.2009, 11:56) *
Цитата(berserk @ 11.2.2009, 11:41) *
Книжка "QT. Профессиональное программирование на С++" стр 45 (немного под себя только модифицировать). Больше примеров не знаю... Самому написать щас некогда.


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

сколько конектов произошло, столько раз и слот получит сигнал (в слоте счётчик), но если нужно посчитать сколько коннектов было с конкретным сигналом такой способ не пойдёт...

ЗЫ: если я правильно понял задачу

Автор: kwisp 11.2.2009, 12:05

berserk,
думаю счетчик в слоте ничем не поможет. ну выяснил ты что сигнал вызывает слот 2 или третий раз что не выполнишь действия которые в слоте? а после разъединения счетчик в слоте надо будет сбрасывать...
както не доконца понятна идея....

Автор: berserk 11.2.2009, 12:13

Цитата(kwisp @ 11.2.2009, 12:05) *
berserk,
думаю счетчик в слоте ничем не поможет. ну выяснил ты что сигнал вызывает слот 2 или третий раз что не выполнишь действия которые в слоте? а после разъединения счетчик в слоте надо будет сбрасывать...
както не доконца понятна идея....


Ну может и неправильно :( , я 2 дня как qt изучаю...

Автор: Константин 11.2.2009, 12:25

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

Цитата
олучается надо просто написать ИЗБЕГАЙТЕ РЕАЛИЗАЦИИ ДИНАМИЧЕСКОЙ МАШИНЫ СОСТОЯНИЙ с помощью сигналов и слотов дабы избежать проблем с много кратным соединением.
используйте колбэки что угодно но не сигналы и слоты даже если соединения редко используемые.

к чему крайности? а то проще написать ИЗБЕГАЙТЕ ИСПОЛЬЗОВАНИЯ КУТЭ В СВОИХ ПРОЕКТАХ. а можно и проще - ИЗБЕГАЙТЕ ПРОГРАММИРОВАНИЯ...

Автор: kwisp 11.2.2009, 12:48

Константин,
>какой смысл отрабатывать слот по десять раз на одно(!) событие?

действительно если ты соединил случайно два раза один и тот же сигнал с одним и тем же слотом зачем отрабаотывать 2 раз.??? а так сделали трольтехи! вот зачем это не понятно.
т.е. в соединении присутствует не только тот факт что соединено или нет(логика bool) а соединено и сколько раз соединено(уже сложнее).

почему не могу узнать сколько раз соединено???
почему не могу узнать соединенно ли вообще???

вот это точно крайности, к чему это?

Цитата
ИЗБЕГАЙТЕ ИСПОЛЬЗОВАНИЯ КУТЭ В СВОИХ ПРОЕКТАХ. а можно и проще - ИЗБЕГАЙТЕ ПРОГРАММИРОВАНИЯ...


ты же избегаешь много кратного соединения, не так ли???
к чему наша дисскусия?. я предлагаю её прекратить.
кто хочет будет использовать динамическое соединение разъединение и будет считать свои соединения сам.


все что хотел по теме сказать сказал.

Автор: kuler 11.2.2009, 13:06

Цитата(kwisp @ 11.2.2009, 11:35) *
они взялись реализовать сигналы слоты взялись сделать как коннект так и дисконнект ну и уже бы и предоставили возможность узнать сколько соединений

а еще в qtablewidget нельзя узнать есть ли столбец с заданным названием. К чему я это? к тому что не все сделано как нада и полностью. Некоторые вещи еще и глючат

Автор: Константин 11.2.2009, 13:12

Цитата(kwisp @ 11.2.2009, 12:48) *
узнать соединенно ли вообще

QObject::connectNotify(...)

Цитата(kwisp @ 11.2.2009, 12:48) *
ты же избегаешь много кратного соединения, не так ли???

а ты и не писал про "избегайте многократных соединений", изречение было иным.

Цитата(kwisp @ 11.2.2009, 12:48) *
если ты соединил случайно два раза один и тот же сигнал с одним и тем же слотом зачем отрабаотывать 2 раз.?

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

тема бессмысленна с самого начала

Цитата(kuler @ 11.2.2009, 13:06) *
а еще в qtablewidget нельзя узнать есть ли столбец с заданным названием.

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

Автор: SABROG 11.2.2009, 13:29

Цитата(Константин @ 11.2.2009, 13:12) *
возьми модель-источник и пройдись по заголовкам. или проблема в том, что нет готовой функции?


Это имхо специфичная задача, для чего создавать такой метод мне не понятно.

    QTableWidgetItem *item;
    for (int i=0, int cols = tableWidget->columnCount(); i < cols; i++)
    {
        item = tableWidget->horizontalHeaderItem(i);
        if (!item->text().compare(QLatin1String("header col 1")))
        {
            qDebug() << "header is presented";
            break;
        }
    }

Автор: Litkevich Yuriy 11.2.2009, 13:31

Цитата(kuler @ 11.2.2009, 16:06) *
а еще в qtablewidget нельзя узнать есть ли столбец с заданным названием. К чему я это? к тому что не все сделано как нада и полностью. Некоторые вещи еще и глючат
так, это уже из другой оперы!

Автор: kwisp 11.2.2009, 13:50

Константин,

Цитата
а ты и не писал про "избегайте многократных соединений", изречение было иным.

.... я писал
Цитата
дабы избежать проблем с много кратным соединением.


Цитата
тема бессмысленна с самого начала


не пиши в ней. какие проблемы? кому то, не буду показывать пальцем, так не кажется.

бессмысленные темы перенесли в треп и юмор:)

Цитата
для конечных состояний не должно быть случайностей. либо ты соединил, либо нет. соединил два раза - тебе виднее, но и эффект получишь для двух раз.


тогда для разъединений должна таже логика действовать. пусть мне виднее и я соединил 2 раз тогда должен и разъединитиь 2 раза однако разъединение убивает все соединения а не одно.

Автор: kuler 11.2.2009, 13:59

SABROG, а по нормальному это выглядит bool table->ExistColumn("colname")

Автор: SABROG 11.2.2009, 14:39

Цитата(kuler @ 11.2.2009, 13:59) *
SABROG, а по нормальному это выглядит bool table->ExistColumn("colname")


Строить логику программы сравнивая текст в компонентах изначальное не правильно. А какое будет у тебя название колонки, если для английского языка там будет одно, для русского - другое, для арабского - третье? Для таких целей обычно используют setData()/data().

Автор: kuler 11.2.2009, 17:48

Цитата(SABROG @ 11.2.2009, 14:39) *
Для таких целей обычно используют setData()/data().

предположим, а есть bool table->FindData(data)?

Автор: Litkevich Yuriy 11.2.2009, 18:39

пожалуй я эту тему закрою, а то во флуд превратилась.
В "Трёп" пока переносить не буду, может современем подчищу и открою заново.
Связанное с темой обсуждение http://www.forum.crossplatform.ru/index.php?showtopic=2141

Форум Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)