232 lines
4.5 KiB
C++
232 lines
4.5 KiB
C++
|
#include <Python.h>
|
|||
|
#include "PyAgent.h"
|
|||
|
#include <QString>
|
|||
|
#include <QCoreApplication>
|
|||
|
#include <QDebug>
|
|||
|
#include <QDir>
|
|||
|
#include "MainWindow/MainWindow.h"
|
|||
|
#include "PyInterpreter.h"
|
|||
|
#include "RecordScript.h"
|
|||
|
#include "ScriptReader.h"
|
|||
|
#include <QFile>
|
|||
|
#include <QDebug>
|
|||
|
#include <QTextStream>
|
|||
|
#include <wchar.h>
|
|||
|
|
|||
|
#ifdef Q_OS_WIN32
|
|||
|
#include <atlconv.h>
|
|||
|
#endif
|
|||
|
|
|||
|
#include <locale.h>
|
|||
|
|
|||
|
namespace Py
|
|||
|
{
|
|||
|
PythonAgent *PythonAgent::_instance = nullptr;
|
|||
|
|
|||
|
PythonAgent *PythonAgent::getInstance()
|
|||
|
{
|
|||
|
if (_instance == nullptr)
|
|||
|
_instance = new PythonAgent;
|
|||
|
|
|||
|
return _instance;
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::connectSignals()
|
|||
|
{
|
|||
|
connect(this, SIGNAL(printInfo(Common::Message, QString)), _mainWindow, SIGNAL(printMessageSig(Common::Message, QString)));
|
|||
|
connect(this, SIGNAL(closeMainWindow()), _mainWindow, SIGNAL(closeMainWindow()));
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::appCodeList(QString code)
|
|||
|
{
|
|||
|
if (!_append)
|
|||
|
return;
|
|||
|
emit printInfo(Common::Message::Python, code);
|
|||
|
_interpreter->codeListAppend(code);
|
|||
|
}
|
|||
|
|
|||
|
PythonAgent::PythonAgent()
|
|||
|
{
|
|||
|
_interpreter = new PyInterpreter;
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::initialize(GUI::MainWindow *m)
|
|||
|
{
|
|||
|
_mainWindow = m;
|
|||
|
connectSignals();
|
|||
|
/*
|
|||
|
QString path = qApp->applicationDirPath() + "/../python37";
|
|||
|
path = QDir::cleanPath(path);
|
|||
|
char *ch;
|
|||
|
QByteArray ba = path.toLocal8Bit();
|
|||
|
ch = ba.data();
|
|||
|
wchar_t *wc;
|
|||
|
|
|||
|
#ifdef Q_OS_WIN32
|
|||
|
USES_CONVERSION;
|
|||
|
wc = A2W(ch);
|
|||
|
#endif
|
|||
|
|
|||
|
#ifdef Q_OS_LINUX
|
|||
|
setlocale(LC_CTYPE, "zh_CN.utf8");
|
|||
|
int w_size = mbstowcs(NULL, ba, 0) + 1;
|
|||
|
wc = new wchar_t[w_size];
|
|||
|
mbstowcs(wc, ba, strlen(ba) + 1);
|
|||
|
#endif
|
|||
|
|
|||
|
QDir d(path);
|
|||
|
if (d.exists())
|
|||
|
{
|
|||
|
#ifdef Q_OS_WIN32
|
|||
|
Py_SetPythonHome(wc);
|
|||
|
#endif
|
|||
|
}*/
|
|||
|
Py_SetProgramName(L"FastCAE");
|
|||
|
Py_Initialize();
|
|||
|
if (!_interpreter->init(this))
|
|||
|
emit printInfo(Common::Message::Error, tr("Python Initialize failed!"));
|
|||
|
else
|
|||
|
emit printInfo(Common::Message::Normal, tr("Python Initialized"));
|
|||
|
_recordScript = new RecordThread;
|
|||
|
_recordScript->start();
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::finalize()
|
|||
|
{
|
|||
|
if (_reader != nullptr)
|
|||
|
{
|
|||
|
if (_reader->isRunning())
|
|||
|
{
|
|||
|
_reader->stop();
|
|||
|
_reader->quit();
|
|||
|
_reader->wait();
|
|||
|
}
|
|||
|
while (_reader->isRunning())
|
|||
|
;
|
|||
|
delete _reader;
|
|||
|
_reader = nullptr;
|
|||
|
}
|
|||
|
|
|||
|
_recordScript->stop();
|
|||
|
_recordScript->quit();
|
|||
|
_recordScript->wait();
|
|||
|
delete _recordScript;
|
|||
|
|
|||
|
if (_interpreter != nullptr)
|
|||
|
delete _interpreter;
|
|||
|
|
|||
|
if (Py_IsInitialized())
|
|||
|
Py_Finalize();
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::submit(QString code, bool s)
|
|||
|
{
|
|||
|
// this->lock();
|
|||
|
qDebug() << "submit: " << code;
|
|||
|
emit printInfo(Common::Message::Python, code);
|
|||
|
// lock();
|
|||
|
int ok = _interpreter->execCode(code, s);
|
|||
|
if (ok == -1)
|
|||
|
{
|
|||
|
if (_reader != nullptr)
|
|||
|
_reader->restart();
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::submit(QStringList codes, bool save /*= true*/)
|
|||
|
{
|
|||
|
const int n = codes.size();
|
|||
|
for (int i = 0; i < n; ++i)
|
|||
|
{
|
|||
|
this->submit(codes.at(i), save);
|
|||
|
}
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::saveScript(QString fileName)
|
|||
|
{
|
|||
|
QFile file(fileName);
|
|||
|
if (!file.open(QIODevice::Text | QIODevice::WriteOnly))
|
|||
|
{
|
|||
|
emit printInfo(Common::Message::Error, tr("Script open failed"));
|
|||
|
return;
|
|||
|
}
|
|||
|
QTextStream stream(&file);
|
|||
|
const int n = _interpreter->getCodeCount();
|
|||
|
for (int i = 0; i < n; ++i)
|
|||
|
{
|
|||
|
QString s = _interpreter->getCodeAt(i);
|
|||
|
stream << s << endl;
|
|||
|
}
|
|||
|
file.close();
|
|||
|
emit printInfo(Common::Message::Normal, tr("Script Saved %1").arg(fileName));
|
|||
|
}
|
|||
|
|
|||
|
bool PythonAgent::execScript(QString fileName)
|
|||
|
{
|
|||
|
if (_reader != nullptr)
|
|||
|
return false;
|
|||
|
_reader = new ScriptReader(fileName, this);
|
|||
|
_recordScript->pause();
|
|||
|
connect(_reader, SIGNAL(finished()), this, SLOT(readerFinished()));
|
|||
|
_reader->start();
|
|||
|
return true;
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::readerFinished()
|
|||
|
{
|
|||
|
if (_reader != nullptr)
|
|||
|
delete _reader;
|
|||
|
_reader = nullptr;
|
|||
|
_recordScript->reStart();
|
|||
|
if (_noGUI)
|
|||
|
emit closeMainWindow();
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::lock()
|
|||
|
{
|
|||
|
if (_reader != nullptr)
|
|||
|
_reader->pause();
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::unLock()
|
|||
|
{
|
|||
|
if (_reader != nullptr)
|
|||
|
_reader->restart();
|
|||
|
}
|
|||
|
|
|||
|
bool PythonAgent::isLocked()
|
|||
|
{
|
|||
|
return _islock;
|
|||
|
}
|
|||
|
|
|||
|
QStringList PythonAgent::getcodelist()
|
|||
|
{
|
|||
|
if (_interpreter != nullptr)
|
|||
|
return _interpreter->getCode();
|
|||
|
return QStringList();
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::setNoGUI(bool nogui)
|
|||
|
{
|
|||
|
_noGUI = nogui;
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::appendOn()
|
|||
|
{
|
|||
|
_append = true;
|
|||
|
}
|
|||
|
void PythonAgent::appendOff()
|
|||
|
{
|
|||
|
_append = false;
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::execMessWinCode(QString code)
|
|||
|
{
|
|||
|
_interpreter->execCode(code);
|
|||
|
}
|
|||
|
|
|||
|
void PythonAgent::backstageExec(QString code)
|
|||
|
{
|
|||
|
_interpreter->execCode(code, false);
|
|||
|
}
|
|||
|
}
|