Очередь нескольких вызовов QTimers в слоты

Я использую библиотеку, где мне нужно вызвать функцию триггера, которая начинает некоторую обработку (запускает поток, который выполняет работу) и немедленно возвращает результат. Затем, когда обработка заканчивается, выдается сигнал.

Это необходимо делать периодически, основываясь на разных параметрах. Поскольку другие вызовы функции триггера не должны выполняться во время обработки, мне нужно каким-то образом поставить их в очередь. Я думал об использовании 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()

Что было бы правильным способом сделать то, что я намерен?

Заранее спасибо.

1

Решение

Одним из простых решений является введение переменной-члена, например, bool m_isProcessing, начать обработку только если m_isProcess == falseзатем установите его на true когда вы начинаете обработку и сбрасываете его false когда обработка завершена. Так как слоты для вашего test QObject выполнить в графическом интерфейсе / главном потоке, вам не нужно беспокоиться о синхронизации между слотами таймера и слотом, который будет выполняться после завершения обработки.

Если вы хотите отслеживать события, происходящие во время обработки, вы можете использовать тот же метод: ввести переменную-член в test класс для отслеживания необходимой вам информации.

1

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

Кажется, что вы ищете Qt :: QueuedConnection.

Qt :: QueuedConnection 2 Слот вызывается, когда управление возвращается в цикл обработки событий получателя. Слот выполняется в потоке получателя.

Поэтому вы можете написать что-то вроде этого:

connect(&timer, SIGNAL(timeout()), SLOT(timerSlot()), Qt::QueuedConnection);
connect(&timer2, SIGNAL(timeout()), SLOT(timer2Slot()), Qt::QueuedConnection);

Для подробностей вы можете посмотреть в хорошо известном примере Мандельброта, как это делается там, хотя он использует рабочие потоки:

Пример Мандельброта

0

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