Я использую библиотеку, где мне нужно вызвать функцию триггера, которая начинает некоторую обработку (запускает поток, который выполняет работу) и немедленно возвращает результат. Затем, когда обработка заканчивается, выдается сигнал.
Это необходимо делать периодически, основываясь на разных параметрах. Поскольку другие вызовы функции триггера не должны выполняться во время обработки, мне нужно каким-то образом поставить их в очередь. Я думал об использовании QEventLoop («loop»), но пока безуспешно.
Пожалуйста, посмотрите на этот кусок кода:
test::test()
{
connect(&timer, SIGNAL(timeout()), this, SLOT(timerSlot()));
connect(&timer2, SIGNAL(timeout()), this, SLOT(timer2Slot()));
connect(&library, SIGNAL(processingFinished()), &loop, SLOT(quit()));
timer.setInterval(2000);
timer.start();
timer2.setInterval(4000);
timer2.start();
}
void test::timerSlot()
{
loop.exec();
startProcessing(some_parameters);
}
void test::timer2Slot()
{
loop.exec();
startProcessing(some_other_parameters);
}
Проблема в том, что когда во время обработки вызывается loop.exec (), я получаю сообщение:
QEventLoop::exec: instance xxxxxx has already called exec()
Что было бы правильным способом сделать то, что я намерен?
Заранее спасибо.
Одним из простых решений является введение переменной-члена, например, bool m_isProcessing
, начать обработку только если m_isProcess == false
затем установите его на true
когда вы начинаете обработку и сбрасываете его false
когда обработка завершена. Так как слоты для вашего test QObject
выполнить в графическом интерфейсе / главном потоке, вам не нужно беспокоиться о синхронизации между слотами таймера и слотом, который будет выполняться после завершения обработки.
Если вы хотите отслеживать события, происходящие во время обработки, вы можете использовать тот же метод: ввести переменную-член в test
класс для отслеживания необходимой вам информации.
Кажется, что вы ищете Qt :: QueuedConnection.
Qt :: QueuedConnection 2 Слот вызывается, когда управление возвращается в цикл обработки событий получателя. Слот выполняется в потоке получателя.
Поэтому вы можете написать что-то вроде этого:
connect(&timer, SIGNAL(timeout()), SLOT(timerSlot()), Qt::QueuedConnection);
connect(&timer2, SIGNAL(timeout()), SLOT(timer2Slot()), Qt::QueuedConnection);
Для подробностей вы можете посмотреть в хорошо известном примере Мандельброта, как это делается там, хотя он использует рабочие потоки: