Russian Qt Forum
Ноябрь 24, 2024, 05:45 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1] 2   Вниз
  Печать  
Автор Тема: signal mapping  (Прочитано 12960 раз)
QCasper
Гость
« : Апрель 16, 2008, 17:27 »

Есть класс С1, у него есть два сигнала A и B без параметров. Требуется, чтобы по этим сигналам вызывались слоты A и B соответственно класса C2. Слоты класса С2 примают в качестве параметра int. Я посмотрел QSignalMapper, но, насколько я понял, с помощью него нельзя сделать так чтобы, один сигнал маппировался на один слот, а второй на другой.
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #1 : Апрель 16, 2008, 17:38 »

сделайте для слотов класса C2 параметры по умолчанию. Должно работать. Т.е. будет что -то вроде этого

Код:
class С1
{
signals:
    void A();
    void B();
};

class С2
{
public slots:
    void A(int param = 0);
    void B(int param = 0);
};

....

connect(c1, SIGNAL(A()), c2, SLOT(A()));
connect(c1, SIGNAL(B()), c2, SLOT(B()));
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
QCasper
Гость
« Ответ #2 : Апрель 16, 2008, 21:57 »

Прошу прощения, я не совсем удачно сформулировал вопрос. Допустим, что в классе С2 у меня один единственный слот с параметром типа int. Класс С1 имеет кучу сигналов: S1, S2, ... , Sn без параметров. Так вот мне нужно маппировать эти сигналы на слот класса С2 таким образом, чтобы в зависимости от сигнала S1, S2, ... или Sn, этот слот вызывался со значением параметра 1, 2, ... n соответственно.
Записан
Вячеслав
Гость
« Ответ #3 : Апрель 16, 2008, 22:35 »

А влоб - сделать еще один слот с параметром , а там switch'ем  звать кого надо ?
Все другое - IMHO будет еще веселее.....
QSignalMapper делает обратное  - собирает кучу простык сигналов в один ( с параметром) ....
Записан
QCasper
Гость
« Ответ #4 : Апрель 16, 2008, 23:15 »

Что делает QSignalMapper мне как раз понятно.
А switch это аццкое зло. Пример приведите, пожалуйста, если можно.
Записан
Sergeich
Гость
« Ответ #5 : Апрель 17, 2008, 02:07 »

Через стандартное API кутехи этого сделать нельзя. Можно в слоте узнать объект от которого поступил сигнал ( через QObject::sender, на этом и построен QSignalMapper ), но нельзя узнать имя имя сигнала. Нужен метод типа
const char* QObject::signal() . Отпишись троллям, возможно они это сделают (через полгода Улыбающийся ).
Как вариант: заведи в классе эмитирующем сигнал переменную типа int и перед эмитированием вставляй в ней нужное значение:
Код:
signalId = THIS_SIGNAL_ID;
emit thisSignal();
Потом в слоте
Код:
Mapper::onSignal() 
{
  Emitter* e = qobject_cast<Emitter*> sender();
  if (e) {
    int id = e->getSignalId();
    // emit blabla(id);
   // c2->slot(id);
   // invoke...... etc 
 }
}
« Последнее редактирование: Апрель 17, 2008, 02:15 от Sergeich » Записан
Sergeich
Гость
« Ответ #6 : Апрель 17, 2008, 02:27 »

Кстати, довольно интересная тема по поводу модели сигнал - слот. Действительно, если я могу спросить: -кто?
почему я не могу спросить:  -какого хуя? Улыбающийся
Записан
Alex03
Гость
« Ответ #7 : Апрель 17, 2008, 07:49 »

QCasper, а мне интересно зачем тебе это надо?
Приведи пример какойнить, можно абстрактный.
Записан
Tonal
Гость
« Ответ #8 : Апрель 17, 2008, 08:26 »

В PyQt это делается элементарно:
Код:
class C2:
  def connect2C1(self, c1):
    def gen_wrap(i):
       return lambda: self.slot(i)
    for i, signal in enumerate(('S1', 'S2', ... , 'Sn')):
       self.connect(c1, QtCore.SIGNAL(signal), gen_wrap(i))
Здесь с1 - объект класса С1.
В цикле выполняется связывание перечисленных сигналов с переходником который вызывает нужный нам слот С2.slot с порядковым номером сигнала.

Как это сделать на С++ что-то в голову не приходит.
Разве что хакнуть тот QMetaObject что генерится moc-ом...
Записан
QCasper
Гость
« Ответ #9 : Апрель 17, 2008, 09:04 »

QCasper, а мне интересно зачем тебе это надо?
Приведи пример какойнить, можно абстрактный.


Например для следующего. Системе требуется переключаться между состояниями. То есть существует метод setState(int state). Система должна переключаться между состояниями не просто так, а в ответ на возникновение некоторого события. Существует таблица (конфигурируемая), которая описывает зависимость состояний от событий. То есть грубо говоря это ассоциативный массив где событие ключ, а состояние -  значение. То есть эти сигналы, которые емитятся классом С1 это и есть те самые события и они и должны маппироваться в некий слот подобного содержания:

Код:
void setStateByEvent(int event) {
     setState(m_States[event]);
}

где m_States - та самая таблица.

Кстати, довольно интересная тема по поводу модели сигнал - слот. Действительно, если я могу спросить: -кто?
почему я не могу спросить:  -какого хуя? Улыбающийся

во во Улыбающийся
Записан
Tonal
Гость
« Ответ #10 : Апрель 17, 2008, 10:31 »

Нашел! :-)
Можно использовать обработку событий.
В Qt, при асинхронном сигнале посылается событие QMetaCallEvent QEvent::MetaCall.
У него есть id - индекс вызываемого.

Идея такая - для коннекта используем QMetaObject::connect(const QObject *sender, int signal_index, const QObject *receiver, int method_index, int type = 0, int *types = 0);
Где type = Qt::QueuedConnection, а method_index - наш номер состояния
Далее ловим событие QMetaCallEvent и вызываем обработчик с параметром. :-)

Единственное, что всё это - недокументированные потроха, так что при смене версии Qt можно нарваться. Улыбающийся

P.S. Корректное использование QMetaObject::connect см. в QObject::connect.

P.P.S. Может всё же через сообщения напрямую это замутить? Попроще выёдет. Улыбающийся
Записан
QCasper
Гость
« Ответ #11 : Апрель 17, 2008, 12:26 »

P.P.S. Может всё же через сообщения напрямую это замутить? Попроще выёдет. Улыбающийся

Это как? Улыбающийся
Записан
Tonal
Гость
« Ответ #12 : Апрель 17, 2008, 13:13 »

Вместо генерации сигналов кидать сендом или постом своего наследника QEvent.
Ну и обрабатывать его как тебе требуется. Улыбающийся
Записан
Вячеслав
Гость
« Ответ #13 : Апрель 17, 2008, 19:40 »

1) Народ , а давайте плиз без командного диалекта  языка ( какого .....)
2) Если слот позвали, а параметров у него нет - то и нефиг знать _почему_ его позвали.Иначе - ошибка проектирования IMHO
3)
Код:
class С2
{
public slots:
    void A(int param = 0);
    void B(int param = 0);
    void Common(int);
};

void C2::Common(int why)
{
switch(why)
 case valueA : A();break;
 case valueB : B();break;
default : errorHandler(why);
}
Ну тоже что делает metacall только сам Подмигивающий
Записан
QCasper
Гость
« Ответ #14 : Апрель 17, 2008, 20:18 »

2) Если слот позвали, а параметров у него нет - то и нефиг знать _почему_ его позвали.Иначе - ошибка проектирования IMHO

Не совсем понятно к чему это.

Код:
class С2
{
public slots:
    void A(int param = 0);
    void B(int param = 0);
    void Common(int);
};

void C2::Common(int why)
{
switch(why)
 case valueA : A();break;
 case valueB : B();break;
default : errorHandler(why);
}

И это.
Записан
Страниц: [1] 2   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.051 секунд. Запросов: 23.