无法从另一个线程Qt

时间:2018-11-13 20:02:42

标签: multithreading qt qt5 qthread qtimer

我正在研究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文件

#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是worker类的子级,并且已移到线程中,为什么Qt抱怨从另一个线程停止它? 注意:我添加了日志来打印线程ID,在两种情况下它输出相同的值:

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

有人可以解释吗?我不明白这里发生了什么

预先感谢

2 个答案:

答案 0 :(得分:3)

我终于可以通过以下方法解决该错误:

  1. 将QTimer转换为指针
  2. 按照@Amfasis的建议添加slot stopWorker
  3. 在该插槽中不仅停止QTimer,而且将其删除

谢谢

答案 1 :(得分:1)

您应该在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!
    ...
}