emit Qt signal from std::thread

333
20 октября 2017, 14:50
  1. Есть класс, отнаследованный от QThread, с переопределенным методом run() и вызовом exec() в конце метода. В данном классе определены необходимые для работы методы.
  2. Есть второй класс с определенными сигналами для вызова методов первого класса. Объект данного класса планируется создавать для обеспечения интерфейса доступа к методом первого класса, находящимся в другом потоке.
  3. Есть std::thread в котором создаются объекты этих классов и вызывается метод start() для первого класса. После создания объектов выполняется соединение сигналов с методами.

Суть вопроса в следующем, при выборе ConnectionType::QueuedConnection ничего не работает, при выборе ConnectionType::DirectConnection методы первого класса начинают вызываться, но выдается предупреждение, что осуществляется доступ из другого потока. Куда смотреть? Почему не работает с ConnectionType::QueuedConnection.

class Cls_1 : public QThread
{
    Q_OBJECT
public:
    Cls_1();
    virtual ~Cls_1(){};
    void Method_1(const double &param);
private:
    void run();
};
Cls_1()::Cls_1()
{
}
void Cls_1::run()
{
    ...
    exec();
}
void Cls_1::Method_1(const double &param)
{
    ;
}
class Cls_2 : public QObject
{
 Q_OBJECT
 public:
    Cls_2();
    virtual ~Cls_2(){};
    void Method_1(const double &param);
 signals: 
    void SignalMethod_1(const double &param);
}
Cls_2()::Cls_2()
{
}
void Cls_2::Method_1(const double &param)
{
    emit SignalMethod_1(param);
}

Код создания и подключения:

Cls_1 *obj_1 = new Cls_1();
obj_1->start();
_sleep(10000);
Cls_2 *obj_2 = new Cls_2();
QObject::connect(obj_2, &Cls_2::SignalMethod_1, obj_1, &Cls_1::Method_1, Qt::ConnectionType::DirectConnection);
obj_2->Method_1(1);
Answer 1

Можно использовать прямой запуск слота без сигнала:

QMetaObject::invokeMethod(receiverObject, "slotName", Qt::QueuedConnection);
Answer 2

Вы создаёте cls2 в контексте текущего потока (который std::thread). Чтобы этот объект был привязан к потоку obj_1, надо сделать одно из двух:

  1. Создавать cls2 изнутри метода Cls_1::run().
  2. Перепривязать созданный объект вызовом cls2->moveToThread(obj_1);.
READ ALSO
Ускорение ввода/вывода в с++

Ускорение ввода/вывода в с++

Доброго времени суток! Ситуация такова: имеется код на с++ для решения некторой задачиПри отправке решения в систему-проверяльщик, один из тестов...

286
Поиск k-ой порядковой статистики

Поиск k-ой порядковой статистики

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

290
Правильно ли реализован шаблон?

Правильно ли реализован шаблон?

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

235
ошибка при использовании typedef

ошибка при использовании typedef

В данном коде компилятор выдает следующую ошибку:

268