QThread:在线程仍在运行时被销毁?

时间:2014-07-26 06:51:50

标签: c++ qt signals-slots qthread qwt

当我按下运行按钮时,我想启动QThread。但编译器输出以下错误:

QThread: Destroyed while thread is still running
ASSERT failure in QThread::setTerminationEnabled(): "Current thread was not started with QThread.", file thread\qthread_win.cp.

我不知道我的代码有什么问题。

任何帮助都将不胜感激。

这是我的代码:

SamplingThread::SamplingThread( QObject *parent):
   QwtSamplingThread( parent ),
   d_frequency( 5.0 )
{
   init();
}

MainWindow::MainWindow( QWidget *parent ):
QMainWindow( parent )
{.......
  .....
   run= new QPushButton ("Run",this);
   stop= new QPushButton("Stop",this);
   connect(run, SIGNAL(clicked()),this, SLOT (start()));
}

MainWindow::start
{
   SamplingThread samplingThread;
   samplingThread.setFrequency( frequency() );
   samplingThread.start();
}

int main( int argc, char **argv )
{
   QApplication app( argc, argv );
   MainWindow window;
   window.resize( 700, 400 );
   window.show();
   bool ok = app.exec();
   return ok;
}

3 个答案:

答案 0 :(得分:20)

如错误消息所示:QThread: Destroyed while thread is still running。您正在SamplingThread方法中创建MainWindow::start对象,但当该方法终止时,它会超出范围(即被销毁)。我看到了两种简单的方法:

  1. 您让SamplingThread成为MainWindow的成员,因此其生命周期与MainWindow实例
  2. 相同
  3. 您使用指针,即使用

    创建SamplingThread

    SamplingThread *samplingThread = new SamplingThread;

  4. 这有帮助吗?

    编辑:为了说明这两种情况,一个非常粗略的例子来说明这两种情况

    #include <iostream>
    #include <QApplication>
    #include <QThread>
    
    class Dummy
    {
    public:
      Dummy();
      void start();
    private:
      QThread a;
    };
    
    Dummy::Dummy() :
      a()
    {
    }
    
    
    void Dummy::start()
    {
      a.start();
      QThread *b = new QThread;
      b->start();
    
      if( a.isRunning() ) {
        std::cout << "Thread a is running" << std::endl;
      }
      if( b->isRunning() ) {
        std::cout << "Thread b is running" << std::endl;
      }
    }
    
    int main(int argc, char** argv)
    {
      QApplication app(argc,argv);
      Dummy d;
      d.start();
      return app.exec();
    }
    

答案 1 :(得分:4)

这是C ++的基础知识!您正在堆栈上创建QThread的本地对象,而不是在堆上,因此当您离开方法MainWindow::start时它会立即销毁。

应该这样做:

MainWindow::MainWindow( QWidget *parent ):
QMainWindow( parent )
{
   ...

   samplingThread = SamplingThread(this);
   samplingThread->setFrequency( frequency() );

   run= new QPushButton ("Run",this);
   stop= new QPushButton("Stop",this);
   connect(run, SIGNAL(clicked()), samplingThread, SLOT(start()));
}

MainWindow::~MainWindow() {
   samplingThread->waitFor(5000);
}

答案 2 :(得分:2)

涉及两个不同的“线程”:一个是实际线程,另一个是表示它的C ++对象(并且正确,首先从另一个线程启动此代码)。

错误只是说线程仍然在代表它的C ++对象被销毁的位置运行。在您的代码中,原因是QThread实例是start()的本地实例。也许您想将QThread存储在成员中。