Страницы

Поиск по вопросам

среда, 25 декабря 2019 г.

emit Qt signal from std::thread

#cpp #qt



Есть класс, отнаследованный от QThread, с переопределенным методом run() и вызовом
exec() в конце метода. В данном классе определены необходимые для работы методы.
Есть второй класс с определенными сигналами для вызова методов первого класса. Объект
данного класса планируется создавать для обеспечения интерфейса доступа к методом первого
класса, находящимся в другом потоке.
Есть 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 ¶m);

private:
    void run();
};

Cls_1()::Cls_1()
{

}

void Cls_1::run()
{
    ...

    exec();
}

void Cls_1::Method_1(const double ¶m)
{
    ;
}

class Cls_2 : public QObject
{

 Q_OBJECT

 public:
    Cls_2();
    virtual ~Cls_2(){};

    void Method_1(const double ¶m);

 signals: 
    void SignalMethod_1(const double ¶m);
}

Cls_2()::Cls_2()
{

}

void Cls_2::Method_1(const double ¶m)
{
    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);

    


Ответы

Ответ 1



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

Ответ 2



Можно использовать прямой запуск слота без сигнала: QMetaObject::invokeMethod(receiverObject, "slotName", Qt::QueuedConnection);

Комментариев нет:

Отправить комментарий