поэтому у меня есть рабочий класс, который имеет 2 слота: StartWork () и StopWork (), StartWork () выполняет бесконечный цикл (он просто читает и читает входные данные с камеры без остановки), а метод StopWork () просто устанавливает bool переменная в false (поэтому цикл внутри StartWork () останавливается).
в соответствии с документацией QThread, лучший способ использовать их сейчас — это не подклассы, а перемещение рабочих в поток, вот что я делаю. проблема заключается в том, что запускаемый сигнал () из потока вызывается, но завершенный () сигнал никогда не вызывается.
слоты рабочего класса:
void StartWork () {running = true; в то время как (работает) {делать работу; }}
void StopWork () {running = false; }
QThread инициализация и соединение сигнал / слот:
thread = new QThread();
worker = new Worker();
worker.moveToThread(thread);
QObject::connect(thread, SIGNAL(started()), worker, SLOT(StartWork()));
QObject::connect(thread, SIGNAL(finished()), worker, SLOT(StopWork()));
и на моем QPushButton я делаю это:
if(pushStartStop->text().toLower() == "start")
{
pushStartStop->setText("Stop");
thread->start();
}
else
{
pushStartStop->setText("Start");
thread->quit();
}
thread-> start () работает нормально, вызывается StartWork () и все прекрасно (графический интерфейс работает без блоков и т. д.).
но thread-> quit () ничего не делает, он вызывается (потому что кнопка меняет текст), но это так. если я просто вызываю worker-> StopWork (), это работает, но тогда я не могу запустить его снова.
Я пытался с потоком -> выход (); но результаты одинаковы. Также я знаю, что подклассификация работает, но она выглядит ужаснее, и, согласно недавней документации Qt, подклассификация больше не является оптимальной.
заранее спасибо.
У вас есть вечный цикл:
void StartWork()
{
running = true;
while(running)
{
do work;
}
}
Эта функция будет зациклена, поэтому цикл обработки потока потока блокируется сразу после started()
, Таким образом, finished()
не может быть испущено
Решение 1:
Добавить функцию
void DoWork()
{
if(running)
{
do work
}
}
Для работника, и изменить
void StartWork()
{
running = true;
}
Затем просто подключите DoWork
к таймеру в теме.
Решение 2:
Изменить функцию
void StartWork()
{
running = true;
while(running)
{
do work;
QCoreApplication::processEvents();
}
}
С этим решением вам придется перезапустить поток, когда работник прекращает свою работу (StopWork()
принудительно завершит эту функцию, поэтому цикл обработки событий не будет обрабатывать события, и поток будет завершен).
Других решений пока нет …