|
@@ -0,0 +1,168 @@
|
|
|
+/*=========================================================================
|
|
|
+
|
|
|
+ Library: CTK
|
|
|
+
|
|
|
+ Copyright (c) Kitware Inc.
|
|
|
+ All rights reserved.
|
|
|
+ Distributed under a BSD License. See LICENSE.txt file.
|
|
|
+
|
|
|
+ This software is distributed "AS IS" WITHOUT ANY WARRANTY; without even
|
|
|
+ the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
|
|
+ See the above copyright notice for more information.
|
|
|
+
|
|
|
+=========================================================================*/
|
|
|
+
|
|
|
+// Qt includes
|
|
|
+#include <QDir>
|
|
|
+#include <QDebug>
|
|
|
+
|
|
|
+// CTK includes
|
|
|
+#include "ctkAbstractPythonManager.h"
|
|
|
+
|
|
|
+// PythonQT includes
|
|
|
+#include <PythonQt.h>
|
|
|
+
|
|
|
+// STD includes
|
|
|
+#include <csignal>
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+ctkAbstractPythonManager::ctkAbstractPythonManager(QObject* _parent) : Superclass(_parent)
|
|
|
+{
|
|
|
+
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+ctkAbstractPythonManager::~ctkAbstractPythonManager()
|
|
|
+{
|
|
|
+ PythonQt::cleanup();
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+PythonQtObjectPtr ctkAbstractPythonManager::mainContext()
|
|
|
+{
|
|
|
+ if (!PythonQt::self())
|
|
|
+ {
|
|
|
+ this->initPythonQt();
|
|
|
+ }
|
|
|
+ if (PythonQt::self())
|
|
|
+ {
|
|
|
+ return PythonQt::self()->getMainModule();
|
|
|
+ }
|
|
|
+ return PythonQtObjectPtr();
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::initPythonQt()
|
|
|
+{
|
|
|
+ PythonQt::init(PythonQt::IgnoreSiteModule | PythonQt::RedirectStdOut);
|
|
|
+
|
|
|
+ // Python maps SIGINT (control-c) to its own handler. We will remap it
|
|
|
+ // to the default so that control-c works.
|
|
|
+ #ifdef SIGINT
|
|
|
+ signal(SIGINT, SIG_DFL);
|
|
|
+ #endif
|
|
|
+
|
|
|
+ PythonQtObjectPtr _mainContext = PythonQt::self()->getMainModule();
|
|
|
+
|
|
|
+ this->connect(PythonQt::self(), SIGNAL(pythonStdOut(const QString&)),
|
|
|
+ SLOT(printStdout(const QString&)));
|
|
|
+ this->connect(PythonQt::self(), SIGNAL(pythonStdErr(const QString&)),
|
|
|
+ SLOT(printStderr(const QString&)));
|
|
|
+
|
|
|
+ QStringList initCode;
|
|
|
+ initCode << "import sys";
|
|
|
+ foreach (QString path, this->pythonPaths())
|
|
|
+ {
|
|
|
+ initCode << QString("sys.path.append('%1')").arg(QDir::fromNativeSeparators(path));
|
|
|
+ }
|
|
|
+
|
|
|
+ _mainContext.evalScript(initCode.join("\n"));
|
|
|
+
|
|
|
+ this->preInitialization();
|
|
|
+
|
|
|
+ emit this->pythonInitialized();
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+QStringList ctkAbstractPythonManager::pythonPaths()
|
|
|
+{
|
|
|
+ return QStringList();
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::preInitialization()
|
|
|
+{
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::registerPythonQtDecorator(QObject* decorator)
|
|
|
+{
|
|
|
+ PythonQt::self()->addDecorators(decorator);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::registerClassForPythonQt(const QMetaObject* metaobject)
|
|
|
+{
|
|
|
+ PythonQt::self()->registerClass(metaobject);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::registerCPPClassForPythonQt(const char* name)
|
|
|
+{
|
|
|
+ PythonQt::self()->registerCPPClass(name);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+QVariant ctkAbstractPythonManager::executeString(const QString& code)
|
|
|
+{
|
|
|
+ QVariant ret;
|
|
|
+ PythonQtObjectPtr main = ctkAbstractPythonManager::mainContext();
|
|
|
+ if (main)
|
|
|
+ {
|
|
|
+ ret = main.evalScript(code, Py_single_input);
|
|
|
+ }
|
|
|
+ return ret;
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::executeFile(const QString& filename)
|
|
|
+{
|
|
|
+ PythonQtObjectPtr main = ctkAbstractPythonManager::mainContext();
|
|
|
+ if (main)
|
|
|
+ {
|
|
|
+ main.evalFile(filename);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::addObjectToPythonMain(const QString& name, QObject* obj)
|
|
|
+{
|
|
|
+ PythonQtObjectPtr main = ctkAbstractPythonManager::mainContext();
|
|
|
+ if (main && obj)
|
|
|
+ {
|
|
|
+ main.addObject(name, obj);
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+QVariant ctkAbstractPythonManager::getVariable(const QString& name)
|
|
|
+{
|
|
|
+ PythonQtObjectPtr main = ctkAbstractPythonManager::mainContext();
|
|
|
+ if (main)
|
|
|
+ {
|
|
|
+ return PythonQt::self()->getVariable(main, name);
|
|
|
+ }
|
|
|
+ return QVariant();
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::printStdout(const QString& text)
|
|
|
+{
|
|
|
+ std::cout << qPrintable(text);
|
|
|
+}
|
|
|
+
|
|
|
+//-----------------------------------------------------------------------------
|
|
|
+void ctkAbstractPythonManager::printStderr(const QString& text)
|
|
|
+{
|
|
|
+ std::cout << qPrintable(text);
|
|
|
+}
|