【问题标题】:Qt slot from thread called more than once [duplicate]来自线程的Qt插槽多​​次调用[重复]
【发布时间】:2016-09-07 13:10:31
【问题描述】:

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

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

这与 gui 中的 QThread 一起使用(calculationManager 是一个 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

【问题讨论】:

  • 如果你真的想从插槽范围内连接信号和插槽,你需要将Qt::UniqueConnection 传递给connect,例如:connect(thread, SIGNAL (started()), calculationManager.data(), SLOT (process()), Qt::UniqueConnection);

标签: c++ multithreading qt signals-slots


【解决方案1】:

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

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() 之外建立此连接即可。

【讨论】:

    【解决方案2】:

    在按钮槽内进行所有连接是原因。因此,连接会进行多次。

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

    一旦将其移至 gui 构造函数,一切正常

    【讨论】:

    • 是的,这就是@Evgeny 之前描述的......
    【解决方案3】:

    同意@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())); 
    
    ...
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-05-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-04-07
      相关资源
      最近更新 更多