Таймеры нельзя остановить из другого потока Qt - PullRequest
0 голосов
/ 13 ноября 2018

Я работаю над приложением Qt.Там я использую два потока, один для GUI и один для обработки.

У меня есть рабочий класс, в котором QTimer имеет класс члена.

.h файл:

#ifndef MAINWINDOW_H
#define MAINWINDOW_H

#include <QMainWindow>
#include <QTimer>
#include <QThread>

class Worker : public QObject
{
  Q_OBJECT
 public:
  Worker();
  QTimer t;
 public slots:
  void process();
  void startWorker();
};

namespace Ui {
 class MainWindow;
}

class MainWindow : public QMainWindow
{
  Q_OBJECT

  public:
   explicit MainWindow(QWidget *parent = nullptr);
   ~MainWindow();

 private:
   QThread workerThread;
   Worker wt;
 };

 #endif // MAINWINDOW_H

cpp file

#include "mainwindow.h"
#include <QDebug>
#include <iostream>

Worker::Worker() : t(this)
{
 connect(&t, SIGNAL(timeout()), this, SLOT(process()));
}

void Worker::process()
{
  std::cout << "triggering timer" << std::endl;
}

void Worker::startWorker()
{
  t.start(1000);
}

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent)
{
  wt.moveToThread(&workerThread);
  qDebug() << "worker thread " << wt.thread();
  qDebug() << "timer thread " << wt.t.thread();
  connect(&workerThread, SIGNAL(started()), &wt, SLOT(startWorker()));
  connect(&workerThread, &QThread::finished, &workerThread, &QObject::deleteLater);
  workerThread.start();
}

MainWindow::~MainWindow()
{
 workerThread.quit();
 workerThread.wait();
}

Я могу запустить поток без ошибок.Однако, когда я закрываю приложение, я получаю предупреждающее сообщение.

QObject::killTimer: Timers cannot be stopped from another thread 
QObject::~QObject: Timers cannot be stopped from another thread

Если QTimer является потомком рабочего класса, и он был перемещен в поток, почему Qt жалуется на остановку его из другого потока?Примечание. Я добавил журналы для печати идентификатора потока, и в обоих случаях он выдает одно и то же значение:

worker thread  QThread(0x72fdf0)
timer thread  QThread(0x72fdf0)

Может кто-нибудь объяснить, пожалуйста?Я не понимаю, что здесь происходит

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

Ответы [ 2 ]

0 голосов
/ 14 ноября 2018

Я наконец-то смог исправить ошибку:

  1. Преобразование QTimer в указатель
  2. Добавление слота stopWorker в соответствии с предложением @ Amfasis
  3. В этом слоте не только остановить QTimer, но и удалить его

Спасибо всем

0 голосов
/ 14 ноября 2018

Вы должны остановить таймер до того, как QObject удалит его сам

в файле .h, добавить деструктор:

class Worker : public QObject
{
    Q_OBJECT
public:
    Worker();
    ~Worker();
private:
    QTimer t;
public slots:
    void process();
    void startWorker();
    void stopWorker(); //this line was added
};

в файле .cpp, добавить:

Worker::stopWorker()
{
    t.stop();
}

и в конструкторе

MainWindow::MainWindow(QWidget *parent) :
    QMainWindow(parent)
{
    ...
    connect(&workerThread, &QThread::finished, &wt, &Worker::stopWorker); //add this line!
    ...
}
...