3

最近、シミュレーターにスクリプト関数を追加しました。スクリプトの評価を起動できる「スクリプトの起動」ボタンを GUI に追加しました。

私のメインは、スクリプトを評価する QThread (scriptThread) を作成します。QMainWindows は、scriptThread スロットを呼び出すメインにシグナルを送信します。

GUIから必要なときにスクリプトを開始および停止できるようにしたい。最初に、scriptThread の terminate() スロットを呼び出しました。しかし、それは私の Qthread を破壊し、キャンセルした後にスクリプトを再起動することはできません (メインの開始時に scriptThread を作成したため)。

これは私のメインの一部です:

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()));

これは私の scriptThread の私の 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 : %i\n", lineNo);
}

printf("ScriptThread finished\n");
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() スロットを試しましたが、これはイベント ループ専用です。既存のスロットまたはそれを行うためのちょっとしたトリックはありますか?

ありがとう。

4

2 に答える 2

0

私はKamilソリューションをうまく試しました。

Qt 4.4 以降では、うまく機能している QScriptEngine::abortEvaluation() 関数があります。

自分の関数に対してローカルだったエンジンを自分のクラスに切り替えました。

ScriptThread.cpp の作業部分コード:

void ScriptThread::cancelScriptEvaluation()
{
  m_scriptEngine.abortEvaluation();
  emit finished();
}

もちろん、 ScriptThread.h で:

private:
  QScriptEngine m_scriptEngine;

そして私のメインで:

QObject::connect(&w, SIGNAL(stopScript()),
               &scriptThread, SLOT(cancelScriptEvaluation()));
于 2014-01-08T14:42:06.200 に答える