Qt-使用具有不同线程的信号和插槽

时间:2017-06-05 20:16:26

标签: c++ multithreading qt signals-slots

我仍然在努力让这项工作符合我的预期。

我有一个Qt项目,我想根据不同线程的信号状态进行更新。我的主GUI线程应该在按下开始按钮时启动一个工作线程。

然后,工作线程应该执行一个函数,该函数连续轮询属于另一个类的变量,这些变量甚至被一个不同的线程更新(我使用的是portaudio库)。然后它应该触发一个信号(sendNewSig),它连接到我的GUI类中的一个插槽(DrawData)。

问题是当我按下开始按钮时程序崩溃了。我相信我错过了开始执行工作线程的一些重要步骤。通过在单击开始按钮时调用updater-> PollSignal(),我希望它能在新线程中运行,但可能不会。我已经展示了下面代码的一部分,希望这足以让我的想法得以实现。

非常感谢您的任何帮助

在GUIApp.cpp

AudioGuiApplication::AudioGuiApplication(QWidget *parent)
: QMainWindow(parent)
{
    ui.setupUi(this);

    //......  other stuff

    thread = new QThread(this);
    updater = new GUIUpdater(&audio_processor);
    updater->moveToThread(thread);

    connect(updater, SIGNAL(sendNewSig(string)), this, SLOT(DrawData(string)));

    connect(thread, SIGNAL(destroyed()), updater, SLOT(deleteLater()));

    actionText->setPlainText("Press Start to begin ");
}

void AudioGuiApplication::on_startButton_clicked()
{
    updater->PollSignal();
}

在GUIUpdater.cpp`中

void GUIUpdater::PollSignal() 
{ 
    string str;

    while (!ap->IsNewDataFound() )
    {
        emit sendNewSig(str);
        ap->SetNewSigFound(false);
    }
}`

1 个答案:

答案 0 :(得分:2)

您正在直接从main / gui线程调用PollSignal函数。

我认为在所需线程中执行它的最简单方法是使用Signal&插槽机制,单次QTimer设置为无延迟(0代表0毫秒):

void AudioGuiApplication::on_startButton_clicked()
{
    QTimer::singleShot(0, updater, &GUIUpdater::PollSignal);
}

顺便说一下:你应该考虑转移到不依赖宏的"new" connect syntax,而是允许编译时类型验证。