来自线程的Qt槽不止一次

时间:2016-09-07 13:10:31

标签: c++ multithreading qt signals-slots

我创建了一个类CalculationManager,它有一个公共插槽进程()发出一个信号finished()。

void CalculationManager::process()
{
    cout << "calc FFT: process()" << endl;
    ...
    emit finished();
}

这与gui的QThread一起使用(calculateManager是QScopedPointer)

void MainWindow::on_pushButtonStartFFT_clicked()
{
    cout << "on_pushButtonStartFFT_clicked()" << endl;

    ...
    calculationManager->moveToThread(thread);

    connect(thread, SIGNAL (started()), calculationManager.data(), SLOT (process()));
    connect(calculationManager.data(), SIGNAL (finished()), thread, SLOT (quit()));
    connect(calculationManager.data(), SIGNAL (finished()), this, SLOT (getResultsAndPlot()));

    cout << "FFT thread started." << endl;
    thread->start();
}

带有图块的插槽

void MainWindow::getResultsAndPlot()
{
    fftAction doShift = static_cast<fftAction>(calculationManager->shiftBeforeFFT());

    updatePlotData(ui->qplot1, calculationManager->data(doShift) );
    cout << "update plots" << endl;
}

在启动gui时调用该函数。输出符合预期:

on_pushButtonStartFFT_clicked()
FFT thread started.
calc FFT: process()
update plots

然而,每次进一步点击按钮都会多次调用,并且更频繁地使用getResultsAndPlot()。我不知道为什么会这样。我该如何调试或解决这个问题?

on_pushButtonStartFFT_clicked()
FFT thread started.
calc FFT: process()
calc FFT: process()
update plots
update plots
update plots
update plots
on_pushButtonStartFFT_clicked()
FFT thread started.
calc FFT: process()
calc FFT: process()
calc FFT: process()
update plots
update plots
update plots
update plots
update plots
update plots
update plots
update plots
update plots

3 个答案:

答案 0 :(得分:4)

每次单击该按钮,都会创建此连接

connect(thread, SIGNAL (started()), calculationManager.data(), SLOT (process()));
connect(calculationManager.data(), SIGNAL (finished()), thread, SLOT (quit()));
connect(calculationManager.data(), SIGNAL (finished()), this, SLOT (getResultsAndPlot()));

因此,在第一次单击后,有一个连接和插槽process()被调用一次。第二次单击后,有两个连接,此插槽调用两次。等等。只需在插槽on_pushButtonStartFFT_clicked()之外建立此连接。

答案 1 :(得分:1)

在pushbotton插槽中进行所有连接是原因。因此连接多次完成。

void MainWindow::on_pushButtonStartFFT_clicked()
{
    ...
    connect(thread, SIGNAL (started()), calculationManager.data(), SLOT (process()));
}

一旦将它移动到gui构造函数,一切正常

答案 2 :(得分:0)

同意@Matthias Pospiech。如果你想在连接按钮上使用连接,你有一个选项就是在连接之前使用断开连接,按照http://doc.qt.io/qt-4.8/qobject.html#disconnect ...这样你就可以确保信号只连接一次......例如,

void MainWindow::on_pushButtonStartFFT_clicked()
{
... 

 disconnect(thread, SIGNAL (started()), calculationManager.data(), SLOT(process()));
 connect(thread, SIGNAL (started()), calculationManager.data(), SLOT(process())); 

...
}