【发布时间】:2020-05-05 08:05:09
【问题描述】:
简介
假设我有一个带有 GUI 的应用程序,它从用户那里收集一些数据,然后调用嵌入式 python 脚本。我想添加“取消按钮”以防用户想要停止进程。
示例代码
mainwindow
#include "calc_script.h"
signals:
void stopWorkSignal();
private:
calc_script *sender;
private slots:
Calculating()
on_pushButton_Cancel_clicked()
void MainWindow::Calculating()
{
QThread* newThread = new QThread();
connect(newThread, &QThread::started,
[=]() { sender->transfer(val_1, val_2, val_3); });
connect(this,
SIGNAL(stopWorkSignal()),
newThread,
SLOT(deleteLater())
newThread->start();
}
void MainWindow::on_pushButton_Cancel_clicked()
{
emit stopWorkSignal();
qDebug() << "stopwork signal emmitted";
}
calc_script.cpp
void calc_script::transfer(double val_1, double val_2, double val_3)
{
///Here the python (from boost.python) is executed
while(1) {}//this loop will generate a load to mimic this script, you cannot edit it, as the communication with .py is one-side at this lvl
}
问题
当信号被调用时,我得到了错误QThread destroyed while thread is still running(并且计算似乎仍在进行)。如果我通过SLOT(quit()),什么都不会发生。如果计算是简单的循环,我可以传递一个标志来停止循环。但是由于调用 python 脚本我无法做到这一点,所以我正在尝试销毁保存计算的线程。描述功能的正确方法是什么?
PS。我知道我没有包括对 python 的整个调用,但它很长。对于重现错误,您可以在transfer 函数中使用任何非循环长计算,它的情况基本相同。
【问题讨论】:
-
我描述了如何在没有 python 的情况下重现它。如果您需要任何额外的数据,请不要犹豫,我会尽力提供。
-
说传递函数中的非循环长计算会让人困惑,因此最好明确放置该代码,而不是您的原始代码,而是任何允许您重现问题。另外我认为可能有必要修改.py,如果你不能修改.py,那么清楚地表明它会很好。
-
我可以修改 .py,但脚本不能与 Thread 实时通信,因此可能无法传递任何标志 - 至少在我的知识中是这样。如果您想重现它,只需在
transfer(例如while(1) {})中放置任何无限循环并将其视为此脚本(您不能修改它)。如果这对您来说还不够,请通知我,我会尝试为您找到其他解决方案。我根据您的建议编辑了问题。 -
通过您的修改,python 和 boost 无关紧要,因为在您的问题中,您没有显示与
while(true){}不同的东西 -
使用
while(1) {}你不能退出线程但是可以终止它。 stackoverflow.com/questions/12207684/… 或者你需要有while(!done) {}其中done是组织线程退出的条件。更不用说如此紧密的循环只是浪费了一个 CPU 头。