Как общаться двумя потоками, используя «интерфейс класса» с Qt и C ++ - PullRequest
0 голосов
/ 29 августа 2018

Я использую Qt, и я пытаюсь вызвать метод из основного потока (перейдите на другую вкладку), когда событие ocorr в другом потоке (библиотека pjsip получает вызов).

Я создаю класс, чтобы использовать интерфейс, ваше имя "SipHandlerController". Я расширяю этот класс в своем основном классе (главное окно из Qt в моем коде имеет имя Start).

Мой класс используется в потоке из pjsip для "приема вызова". У класса от pjsip до обработчика этого события тоже есть свойство типа «SipHandlerController», это свойство получает экземпляр моего основного класса (это выполняется в другом потоке, чтобы манипулировать всем пользовательским интерфейсом). Когда событие «получить вызов» вызывается потоком pjsip, он действительно вызывает метод из моего основного потока (метод для реализации SipHandlerController), но получает ошибку и приложение не работает:

Ошибка ASSERT в QCoreApplication :: sendEvent: "Невозможно отправить события объектам, принадлежащим другому потоку. Текущий поток 0x0x26545658. Приемник 'pageDialer' (типа 'QWidget') создан в потоке 0x0x2071ab68", файл kernel \ qcoreapplication. CPP, строка 576

Мой интерфейс

#ifndef SIP_HANDLER_CONTROLLER_H
#define SIP_HANDLER_CONTROLLER_H

#include <pjsua2.hpp>

using namespace pj;

class SipHandlerController
{
public:
    virtual void onSipIncomingRinging(Call * call) = 0;
};

#endif // SIP_HANDLER_CONTROLLER_H

Моя реализация в классе от pjsip для прослушивания события

void SipLine::onIncomingCall(OnIncomingCallParam &iprm){
    SipCall *call = new SipCall(*this, iprm.callId);
    call->setHandler(this->handler);

    if(this->handler != nullptr){
        // Here is call the method from main thread
        this->handler->onSipIncomingRinging(call);
    }
}

Мой заголовок из основного класса (реализующий класс "SipHandlerController", этот класс является моим основным потоком).

class Start : public QMainWindow, public SearchHandler, public FooterHandler, public SipHandlerController, public PhonebookHandler
{
    Q_OBJECT

public:
    explicit Start(QWidget *parent = nullptr);
    ~Start();
    virtual void onSipIncomingRinging(Call * call);
}

Источник из моей основной реализации SipHandlerController. (nav - это QStackedWidget), вызывается метод onSipIncomingRinging, но в этот момент приложение не работает.

void  Start::onSipIncomingRinging(Call * call){
    this->call = call;
    ui->nav->setCurrentIndex(NavigationTabs::RINGING);
}

1 Ответ

0 голосов
/ 29 августа 2018

Было решено с помощью излучаемых сигналов:

Добавлены сигналы

class Start : public QMainWindow, public SearchHandler, public FooterHandler, public SipHandlerController, public PhonebookHandler
{
    Q_OBJECT
   public:
        explicit Start(QWidget *parent = nullptr);
        ~Start();
        virtual void onSipIncomingRinging(Call * call);
    signals:
        void onSipIncomingRingingEvent(Call * call);
}

Реализация была изменена, чтобы излучать сигнал

void Start::onSipIncomingRinging(Call * call){
    emit onSipIncomingRingingEvent(call);
}

Слот смены внешнего интерфейса

void Start::on_Start_onSipOutgoingRingingEvent(Call * call)
{
    this->call = call;
    ui->nav->setCurrentIndex(NavigationTabs::CONTACT);
}
...