停止对 Qt 脚本的评估
Stop the evaluation of a Qt Script
我最近在模拟器上添加了一个脚本函数。我在 GUI 上添加了一个"启动脚本"按钮,该按钮能够启动脚本的评估。
我的主要创建了一个QThread(scriptThread)来评估我的脚本。我的QMainWindows向我的主服务器发送信号,后者调用scriptThread插槽。
我希望能够启动脚本,并在需要时从 GUI 停止脚本。我首先调用了 scriptThread 的 terminate() 插槽。但是它破坏了我的 Qthread,取消脚本后我无法重新编写脚本(因为我在 main 的开头创建了我的脚本线程)。
这是我的主要内容的一部分:
MyGUI w();
ScriptThread scriptThread();
QObject::connect(&w, SIGNAL(setScriptPath(QString)),
&scriptThread, SLOT(setPath(QString)));
QObject::connect(&w, SIGNAL(launchScriptSignal()),
&scriptThread, SLOT(start()));
QObject::connect(&w, SIGNAL(stopScript()),
&scriptThread, SLOT(terminate()));
QObject::connect(&scriptThread, SIGNAL(finished()),
&w, SLOT(scriptFinished()));
这是我的脚本线程中的 run() 函数:
QScriptEngine m_scriptEngine;
QScriptValue m_result;
QScriptValue m_scriptValue = m_scriptEngine.newQObject(m_MyQOBJECT);
m_scriptEngine.globalObject().setProperty("sc", m_scriptValue);
QFile file(m_path);
bool result = file.open(QIODevice::ReadOnly);
if(!result)
{
printf("Script path not found.n");
emit finished();
return;
}
m_result = m_scriptEngine.evaluate(file.readAll());
if(m_result.toString() != "undefined")
std::cout << m_result.toString().toStdString() << std::endl;
file.close();
if(m_scriptEngine.hasUncaughtException())
{
int lineNo = m_scriptEngine.uncaughtExceptionLineNumber();
printf("lineNo : %in", lineNo);
}
printf("ScriptThread finishedn");
emit finished();
GUI有趣的功能:
void myGUI::launchScript(QString path)
{
if(!m_isScriptRunning)
{
path = ui->editScriptPath->text();
disableAll();
ui->Script->setText("stop script");
m_isScriptRunning = true ;
emit setScriptPath(path);
emit launchScriptSignal();
}
else
{
emit stopScript();
scriptFinished();
}
}
void MyGUI::scriptFinished()
{
enableAll();
ui->Script->setText("launch script");
m_isScriptRunning = false ;
}
所以我的问题是,如何在不破坏线程的情况下取消脚本的评估?我已经尝试了 quit() 插槽,但它仅用于事件循环。是否有现有的插槽或技巧可以做到这一点?
谢谢。
abortEvaluation()
不适用于QScriptValue::call()
,也不适用于从C++代码到javascript的调用。要中断这些,您可以引发异常。这对我有用,我把它放在这里,所以没有其他人需要花时间寻找它:
if(engine->isEvaluating())
{
engine->abortEvaluation();
}
else
{
QScriptContext *ctx = engine->currentContext();
if(ctx)
ctx->throwError("Code has been executing for too long!");
}
当然,脚本可以捕获此异常并继续,但很有可能它不会,即使它这样做,它也很可能会脱离无限循环。
我已经成功尝试了卡米尔解决方案。
在Qt 4.4及更早版本中,有一个QScriptEngine::abortEvaluation()函数工作得很好。
我刚刚将我的函数本地引擎切换到我的类中。
脚本线程的工作部分代码.cpp
:void ScriptThread::cancelScriptEvaluation()
{
m_scriptEngine.abortEvaluation();
emit finished();
}
当然在 ScriptThread.h 中:
private:
QScriptEngine m_scriptEngine;
在我的主要:
QObject::connect(&w, SIGNAL(stopScript()),
&scriptThread, SLOT(cancelScriptEvaluation()));
相关文章:
- std::condition_variable::wait()如何评估给定的谓词
- 如何通过cpp程序运行shell脚本
- 在程序中编写脚本来编写和编译代码
- c++11评估顺序(未定义的行为)
- 如何在c++中使用system()来运行包含空格的python脚本
- 在cygwin中运行c++脚本时发生错误
- 如何将真正的字符串从python c-api转换为python脚本
- 用于将C++代码转换为 Web 程序集的脚本未终止
- 如何使用C++初始化向量;脚本化值不是数组、指针或矢量错误
- 在原子中使用犰狳与脚本
- 如何使用"equal to"以外的评估编写开关语句
- 嵌套 if 中没有返回评估
- 我适合在我的构建系统中使用 shell 脚本而不是AX_CHECK_COMPILE_FLAG吗?
- 懒惰的参数评估try_emplace?
- CANoe - 无法在 CAPL 脚本中打开.dll
- 在从Qt调用的Python脚本中导入OpenCV崩溃
- 在实践中,在运行时为零的乘法中是否有任何"lazy"评估
- 停止对 Qt 脚本的评估
- 使用C++或Bash/Shell脚本评估后台linux命令的输出
- 正在从C++评估脚本表达式