Qt对象已删除但信号未断开

时间:2016-01-27 12:13:38

标签: c++ qt

在此topic中,它告知qobject删除其活动连接时将被删除。我有一个如下情况:

Work* work = new Work();//->Work derived from QObject 
Worker* worker  = new Worker(work);//->Worker derived from QThread and has the ownership of work

connect(work, SIGNAL(percentageComplete(int)), progressDialog, SLOT(setValue(int)));
connect(worker, SIGNAL(finished()),  worker, SLOT(deleteLater()));

progressDialog->show();
worker->start();

在工人的析构函数中,我有:

Worker::~Worker(void){
    if(work != nullptr){
        work->deleteLater();
    }
}

我%100肯定会删除工作。我可以用断点看到它。我甚至可以看到QObjects析构函数调用。

但有些删除工作对象仍然接收信号“百分比完成”。并且因为它被删除,导致粉碎。

我想问为什么即使删除对象也不会断开信号?

Worker的析构函数work->deleteLater();delete work;中的第二个问题是正确的吗?

4 个答案:

答案 0 :(得分:3)

为什么不使用disconnect()断开所有连接的插槽/信号? 你可以在析构函数中调用这个函数。Here你有类似主题的解决方案

答案 1 :(得分:0)

我的猜测是工作对象被移动到工作线程,并且发出的信号将在事件循环中结束,这可以稍后传递。可能你已经杀死了progressDialog。

答案 2 :(得分:0)

除非你有一些自定义代码,否则只需直接使用QThread

Work* work = new Work(); // no parent
QThread* thread = new QThread();

work->moveToThread(worker);

connect(thread, SIGNAL(started()), work, SLOT(doSomeWork())); // add this function doSomething() in Work class which on completion should emit finished() signal
connect(work, SIGNAL(finished()), thread, SLOT(quit())); // quit the thread
connect(work, SIGNAL(finished()), work, SLOT(deleteLater())); // delete work after job done
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater())); // delete thread

// if you are using c++11, do this to see Work and Thread deletion
connect(work, &Work::destroyed, [](){ qDebug() << "Work object deleted"; });
connect(thread, &QThread::destroyed, [](){ qDebug() << "Thread deleted"; });

// start the thread now
thread->start();

See here for more info on QThread usage

答案 3 :(得分:0)

发生这种情况是因为有两个线程同时尝试使用Work,没有明显的同步,可预测的结果很糟糕。

您必须在主线程和工作线程之间编组Work的所有权和访问权限,以便两个线程无法以不安全的方式同时访问它。

Worker线程中没有执行Worker的析构函数!此外,在Worker 主题仍处于活动状态时,我没有看到任何阻止该析构函数运行的代码。请注意,QThread不是主题,而是主题句柄。这是一个欺骗性的名字。

唉,如果没有看到重现问题的完整示例,就无法回答您的问题。