Russian Qt Forum

Qt => Общие вопросы => Тема начата: wenny от Июнь 15, 2016, 15:22



Название: Callback в виде слота
Отправлено: wenny от Июнь 15, 2016, 15:22
Доброго времени суток. Я привык работать с калбэками, но решил не быдлокодить в qt, коли там предусмотрели сигналы/слоты. Есть MainForm и RealClass. MainForm создает поток и закидывает в него метод RealClass'а, который ждет определенного события и выполняет действие. Так вот это действие (связанное вообще со сторонними классами) я по ряду причин хотел бы не намешивать в RealClass, у которого есть свои обязанности, а задавать из контроллера (MainForm). Калбэки выглядят уж больно грубо, решил ограничиться слотами. Вижу я это в виде передачи ссылки на реализованный слот. Вопрос: как это организовать? Я пытался стащить типизацию у connect, но буквально ничего не вышло. Спасибо.


Название: Re: Callback в виде слота
Отправлено: Racheengel от Июнь 15, 2016, 16:08
Передать в слот параметр колбэка с помощью поинтера или ссылки?


Название: Re: Callback в виде слота
Отправлено: wenny от Июнь 15, 2016, 17:54
Передать в слот параметр колбэка с помощью поинтера или ссылки?
Не понял Вас.


Название: Re: Callback в виде слота
Отправлено: Old от Июнь 15, 2016, 18:02
Посмотрите на QtConcurrent или QRunnable. Но лучше на первое. :)


Название: Re: Callback в виде слота
Отправлено: wenny от Июнь 15, 2016, 18:13
Как скомпилить такую конструкцию?:

Код
C++ (Qt)
Class *object

Компилер уверяет, что понятия не имеет о такой штуке как Class.


Название: Re: Callback в виде слота
Отправлено: gil9red от Июнь 15, 2016, 19:45
Как скомпилить такую конструкцию?:

Код
C++ (Qt)
Class *object

Компилер уверяет, что понятия не имеет о такой штуке как Class.

Приинклудьте файл с таким классом или напишите сами.


Название: Re: Callback в виде слота
Отправлено: wenny от Июнь 15, 2016, 20:15
Такого файла, судя по всему, не существует. Это - царь-папа всех остальных классов, которые юзаются в QtConcurrent, и который я пытаюсь откуда-то взять.


Название: Re: Callback в виде слота
Отправлено: Old от Июнь 15, 2016, 20:49
Такого файла, судя по всему, не существует. Это - царь-папа всех остальных классов, которые юзаются в QtConcurrent, и который я пытаюсь откуда-то взять.
Я имел в виду не "смотреть как реализовано", а использовать сам QtConcurrent, что бы не надо было передавать callback.


Название: Re: Callback в виде слота
Отправлено: wenny от Июнь 15, 2016, 21:19
Совершенно не понял, каким образом смена способа запуска потока поможет логику перенести из RealClass в MainForm. Я лишь хочу, чтобы действие, выполняемое при определенных условиях, можно было передать в поток из MainForm, а не запихивать его в RealClass, который и является классом потока.


Название: Re: Callback в виде слота
Отправлено: Old от Июнь 15, 2016, 21:22
Совершенно не понял, каким образом смена способа запуска потока поможет логику перенести из RealClass в MainForm.
Вы сможете не ждать в потоке указатель на функцию для выполнения, а выполнять нужную функцию в потоке из пула, подготовленного QtConcurrent.


Название: Re: Callback в виде слота
Отправлено: wenny от Июнь 15, 2016, 21:24
Но указатель на эту функцию все равно ведь придется передавать.


Название: Re: Callback в виде слота
Отправлено: Old от Июнь 15, 2016, 21:27
Но указатель на эту функцию все равно ведь придется передавать.
Да. В тот момент, когда должны начаться вычисления.


Название: Re: Callback в виде слота
Отправлено: wenny от Июнь 15, 2016, 22:07
Я был бы Вам очень признателен за пример.


Название: Re: Callback в виде слота
Отправлено: Old от Июнь 15, 2016, 22:16
Я был бы Вам очень признателен за пример.
В тот момент, когда вы планировали передавать callback-функцию для выполнения в поток, выполняете:
Код
C++ (Qt)
// Функция для выполнения в рабочем потоке
void process( QByteArray param )
{
   ...
}
 
void start()
{
   QByteArray data = ...
   QtConcurrent::run( func, data );
}
 

В документации есть примеры.


Название: Re: Callback в виде слота
Отправлено: wenny от Июнь 16, 2016, 13:27
В тот момент, когда вы планировали передавать callback-функцию для выполнения в поток, выполняете:
Код
C++ (Qt)
// Функция для выполнения в рабочем потоке
void process( QByteArray param )
{
   ...
}
 
void start()
{
   QByteArray data = ...
   QtConcurrent::run( func, data );
}
 

В документации есть примеры.
Насколько я понимаю, речь идет о передаче определенного параметра. А мне нужно передать ссылку на целый метод, определенный вообще в другом классе. Передать переменную я бы смог и без калбэка.


Название: Re: Callback в виде слота
Отправлено: Old от Июнь 16, 2016, 13:53
Насколько я понимаю, речь идет о передаче определенного параметра. А мне нужно передать ссылку на целый метод, определенный вообще в другом классе. Передать переменную я бы смог и без калбэка.
Нет, вы не правильно понимаете.
Здесь вы запускаете функцию process в рабочем потоке, так же можно поступить и с любым методом любого объекта.


Название: Re: Callback в виде слота
Отправлено: wenny от Июнь 16, 2016, 13:55
Соорудил следующую конструкцию:
Код
C++ (Qt)
hipchatWorker = new HipchatWorker( hipchat, tray );
hipchatWorker->setCb( this, &stopCheckingNewMessages );

Код
C++ (Qt)
void HipchatWorker::setCb( TrayWindow* object, void (TrayWindow::*fn)() )
{
   object->fn(); // вызываю, как в js
}

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


Название: Re: Callback в виде слота
Отправлено: Racheengel от Июнь 16, 2016, 15:01
передавайте вместо поинтера на метод какой-нибудь ID, например,

void HipchatWorker::setCb( TrayWindow* object, int id)
{
    if (id == idStopCheckingNewMessages)
        object->stopCheckingNewMessages ();
    .... // тут другие допустимые id
}


Название: Re: Callback в виде слота
Отправлено: kambala от Июнь 16, 2016, 15:28
если я правильно понял цель: из RealClass пускать сигналы, в MainForm приконнектить к этим сигналам слоты требуемых объектов