Получение сообщений LCM через сигналы / слоты в C ++ с помощью Qt?

В моем приложении я получаю сообщения от LCM (Lightweight Communications and Marshalling), которые содержат данные для нескольких потребителей в приложении. Я представлял, как это работает с обработчиком LCM как синглтоном, так что есть один экземпляр, который может использовать каждый класс. Например, каждый потребительский класс будет иметь:

QObject::connect(LCMHandler::getInstance(), SIGNAL(messageReceived()),
this, SLOT(processMessage()));

куда lcmhandler.h является:

class LCMHandler : public QObject
{
Q_OBJECT
public:
static LCMHandler* getInstance();
LCMHandler();
~LCMHandler() {}

void handleMessage(const lcm::ReceiveBuffer* rbuf,
const std::string &chan,
const example::example_t *msg);

signals:
void messageReceived();

private:
static LCMReceiver* _instance;
};

А также lcmhandler.cpp является:

LCMHandler* LCMHandler::_instance = 0;

LCMHandler::LCMHandler()
{
lcm::LCM lcm;
if(lcm.good())
{
lcm.subscribe("MyChannel", &LCMHandler::handleMessage, this);
while(0 == lcm.handle());
} else {
std::cerr << "LCM Error" << std::endl;
}
}

LCMHandler* LCMHandler::getInstance() {
if (!_instance) {
_instance = new LCMHandler();
}
return _instance;
}

void LCMHandler::handleMessage(const lcm::ReceiveBuffer *rbuf,
const std::string &chan,
const hlelcm::transponder_t *msg)
{

std::cout << "Received message on channel " <<  chan.c_str() << std::endl;
emit messageReceived();
}

Приложение успешно печатает «Полученное сообщение на канале …» повторно; тем не менее, ничего не выполняется, в том числе код в классе потребителя processMessage(), предположительно потому, что приложение застревает в цикле handleMessage(...) и никогда не выполняет процедуру сигнал / слот (или обновляет компоненты пользовательского интерфейса). Итак, если реализация processMessage() является:

void Consumer::processMessage() {
std::cout << "Message received" << std::endl;
}

Это никогда не выполняется, пока handleMessage(...) петли бесконечно. Точно так же интерфейс Qt никогда не загружается, потому что handleMessage занят циклом.

Как лучше всего обрабатывать входящие сообщения? Должен ли я воздерживаться от использования синглтона для LCMHandler? Что мне нужно изменить, чтобы эта реализация работала?

1

Решение

Переместите содержимое вашего конструктора LCM в другую функцию:

LCMHandler::beginCommunication()
{
lcm::LCM lcm;
if(lcm.good())
{
//QObject base class call.
moveToThread( &_myLocalQThread );

_myLocalThread.start();

lcm.subscribe("MyChannel", &LCMHandler::handleMessage, this);

_isActive = true;

// This is blocking, we don't want it to interfere with
// the QApplication loop
while(0 == lcm.handle());
}
else
{
std::cerr << "LCM Error" << std::endl;
}

_isActive = false;
}

Затем что-то вроде этого, чтобы ваш цикл LCM происходил в другом потоке.

auto lcmHandler = LCMHandler::getInstance();

// I like to be explicit about the Qt::QueuedConnection. Default behavior should be thread safe, though.
connect( lcmHandler, &LCMHandler::messageReceived,
this, &Consumer::processMessage, Qt::QueuedConnection );

// Add a std::atomic< bool > _isActive to LCMHandler
if( not lcmHandler.isActive() )
{
lcmHandler.beginCommunication();
}

И затем убедитесь, что правильно закрыли свой QThread в деструкторе.

LCMHandler::~LCMHandler()
{
_myLocalQThread.quit();

_myLocalQThread.wait();
}
0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]