Я использую 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);
}
Было решено использование сигналов emit:
Добавлены сигналы
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);
}
Других решений пока нет …