Bladeren bron

ctkSimplePythonShell: CTK wrapped library automatically initialized

Script ctkSimplePythonShell defining convenient function like:
  app(), quit() or exit() is also loaded at startup
Jean-Christophe Fillion-Robin 14 jaren geleden
bovenliggende
commit
5778a254c3

+ 41 - 3
Applications/ctkSimplePythonShell/CMakeLists.txt

@@ -1,11 +1,16 @@
 PROJECT(ctkSimplePythonShell)
 
 #
+# 3rd party dependencies
+#
+INCLUDE(${VTK_USE_FILE})
+
+#
 # See CTK/CMake/ctkMacroBuildApp.cmake for details
 #
 
 SET(KIT_SRCS
-  ctkSimplePythonManager.cpp
+  ${CMAKE_CURRENT_BINARY_DIR}/ctkSimplePythonManager.cpp
   ctkSimplePythonManager.h
   ctkSimplePythonQtDecorators.h
   ctkSimplePythonShellMain.cpp
@@ -25,6 +30,12 @@ SET(KIT_UI_FORMS
 SET(KIT_resources
 )
 
+# Set VTK_LIBRARIES variable
+SET(VTK_LIBRARIES
+  vtkCommon
+  vtkFiltering
+  )
+
 # Target libraries - See CMake/ctkMacroGetTargetLibraries.cmake
 # The following macro will read the target libraries from the file 'target_libraries.cmake'
 ctkMacroGetTargetLibraries(KIT_target_libraries)
@@ -36,10 +47,35 @@ CONFIGURE_FILE(
   )
   
 IF(CTK_WRAP_PYTHONQT_LIGHT OR CTK_WRAP_PYTHONQT_FULL)
-  LIST(APPEND KIT_target_libraries CTKCorePythonQt)
-  LIST(APPEND KIT_target_libraries CTKWidgetsPythonQt)
+
+  # Update list of target libraries with the list of available PythonQt libraries
+  # and set variables holding list of pythonqt initialization method
+  SET(CTK_PYTHONQT_INITIALIZATION_METHOD_DEFINITION)
+  SET(CTK_PYTHONQT_INITIALIZATION_METHOD_CALL)
+
+  FOREACH(lib ${CTK_LIBS})
+    ctkFunctionExtractOptionNameAndValue(${lib} lib_name lib_value)
+    IF(${CTK_LIB_${lib_name}})
+      STRING(REPLACE "/" "" lib_name_no_slash ${lib_name})
+
+      LIST(APPEND KIT_target_libraries CTK${lib_name_no_slash}PythonQt)
+
+      SET(CTK_PYTHONQT_INITIALIZATION_METHOD_DEFINITION
+        "${CTK_PYTHONQT_INITIALIZATION_METHOD_DEFINITION}
+void PythonQt_init_org_commontk_CTK${lib_name_no_slash}(PyObject*);")
+
+      SET(CTK_PYTHONQT_INITIALIZATION_METHOD_CALL
+        "${CTK_PYTHONQT_INITIALIZATION_METHOD_CALL}
+PythonQt_init_org_commontk_CTK${lib_name_no_slash}(0);")
+    ENDIF()
+  ENDFOREACH()
 ENDIF()
 
+CONFIGURE_FILE(
+  ctkSimplePythonManager.cpp.in
+  ${CMAKE_CURRENT_BINARY_DIR}/ctkSimplePythonManager.cpp
+  )
+
 ctkMacroBuildApp(
   NAME ${PROJECT_NAME}
   SRCS ${KIT_SRCS}
@@ -49,6 +85,8 @@ ctkMacroBuildApp(
   RESOURCES ${KIT_resources}
   )
 
+ADD_SUBDIRECTORY(Python)
+
 # Testing
 IF(BUILD_TESTING)
 #   ADD_SUBDIRECTORY(Testing)

+ 17 - 0
Applications/ctkSimplePythonShell/Python/CMakeLists.txt

@@ -0,0 +1,17 @@
+
+
+SET(KIT_PYTHON_SCRIPTS
+  ctkSimplePythonShell
+  )
+  
+SET(KIT_PYTHON_RESOURCES
+  )
+  
+ctkMacroCompilePythonScript(
+  TARGET_NAME ${PROJECT_NAME}
+  SCRIPTS "${KIT_PYTHON_SCRIPTS}"
+  RESOURCES "${KIT_PYTHON_RESOURCES}"
+  DESTINATION_DIR ${CTK_BINARY_DIR}/bin/Python
+  INSTALL_DIR ${CTK_INSTALL_BIN_DIR}
+  )
+  

+ 9 - 0
Applications/ctkSimplePythonShell/Python/ctkSimplePythonShell.py

@@ -0,0 +1,9 @@
+
+def app():
+  return _ctkSimplePythonShellInstance
+  
+def quit():
+  exit()
+    
+def exit():
+  app().quit()

+ 0 - 55
Applications/ctkSimplePythonShell/ctkSimplePythonManager.cpp

@@ -1,55 +0,0 @@
-
-// PythonQT includes
-#include <PythonQt.h>
-
-// CTK includes
-#include "ctkSimplePythonManager.h"
-#include "ctkSimplePythonQtDecorators.h"
-
-#include "ctkScriptingPythonCoreConfigure.h" // For CTK_WRAP_PYTHONQT_{LIGHT, FULL}
-
-#if defined(CTK_WRAP_PYTHONQT_LIGHT) || defined(CTK_WRAP_PYTHONQT_FULL)
-// PythonQt wrapper initialization methods
-void PythonQt_init_org_commontk_CTKCore(PyObject*);
-void PythonQt_init_org_commontk_CTKWidgets(PyObject*);
-#endif
-
-//-----------------------------------------------------------------------------
-ctkSimplePythonManager::ctkSimplePythonManager(QObject* _parent) : Superclass(_parent)
-{
-
-}
-
-//-----------------------------------------------------------------------------
-ctkSimplePythonManager::~ctkSimplePythonManager()
-{
-}
-
-//-----------------------------------------------------------------------------
-QStringList ctkSimplePythonManager::pythonPaths()
-{  
-  QStringList paths;  
-  
-  return paths; 
-}
-
-//-----------------------------------------------------------------------------
-void ctkSimplePythonManager::preInitialization()
-{
-  Superclass::preInitialization();
-
-#if defined(CTK_WRAP_PYTHONQT_LIGHT) || defined(CTK_WRAP_PYTHONQT_FULL)
-  // Initialize wrappers
-  PythonQt_init_org_commontk_CTKCore(0);
-  PythonQt_init_org_commontk_CTKWidgets(0);
-#endif
-
-  // Register decorators
-  this->registerPythonQtDecorator(new ctkSimplePythonQtDecorators(this));  
-  
-  // Add object to python interpreter context
-  //this->addObjectToPythonMain("_qSlicerCoreApplicationInstance", app);
-
-  // Evaluate application script
-  //this->executeFile(app->slicerHome() + "/bin/Python/slicer/slicerqt.py");
-}

+ 114 - 0
Applications/ctkSimplePythonShell/ctkSimplePythonManager.cpp.in

@@ -0,0 +1,114 @@
+
+// QT includes
+#include <QFile>
+#include <QFileInfo>
+#include <QApplication>
+
+// PythonQT includes
+#include <PythonQt.h>
+
+// CTK includes
+#include "ctkSimplePythonManager.h"
+#include "ctkSimplePythonQtDecorators.h"
+
+#include "ctkSimplePythonShellConfigure.h" // For CTK_WRAP_PYTHONQT_{LIGHT, FULL}
+
+#if defined(CTK_WRAP_PYTHONQT_LIGHT) || defined(CTK_WRAP_PYTHONQT_FULL)
+// PythonQt wrapper initialization methods
+@CTK_PYTHONQT_INITIALIZATION_METHOD_DEFINITION@
+#endif
+
+#ifdef CTK_WRAP_PYTHONQT_USE_VTK
+# if defined(CMAKE_INTDIR)
+#  define VTK_PYTHON_LIBRARY_DIR VTK_PYTHON_LIBRARY_DIR_BUILD "/" CMAKE_INTDIR
+# else
+#  define VTK_PYTHON_LIBRARY_DIR VTK_PYTHON_LIBRARY_DIR_BUILD
+# endif
+#endif
+
+//-----------------------------------------------------------------------------
+ctkSimplePythonManager::ctkSimplePythonManager(QObject* _parent) : Superclass(_parent)
+{
+}
+
+//-----------------------------------------------------------------------------
+ctkSimplePythonManager::~ctkSimplePythonManager()
+{
+}
+
+//-----------------------------------------------------------------------------
+QStringList ctkSimplePythonManager::pythonPaths()
+{  
+  QStringList paths;
+  paths << Superclass::pythonPaths();
+
+  QString self_dir = QFileInfo(qApp->applicationFilePath()).absolutePath();
+
+  QString ctk_python_dir = self_dir;
+  #if defined(CMAKE_INTDIR)
+    ctk_python_dir.append("/..");
+  #endif
+  ctk_python_dir.append("/Python");
+  paths << QFileInfo(ctk_python_dir).absoluteFilePath();
+
+#ifdef CTK_WRAP_PYTHONQT_USE_VTK
+
+  // Try to put the VTK python module location in sys.path.
+  QString vtk_build_dir = "/../../CMakeExternals/Build/VTK/Wrapping/Python";
+  bool found_vtk = false;
+  QString vtk_package_dir = self_dir;
+
+#if defined(CMAKE_INTDIR)
+  vtk_package_dir.append("/..");
+#endif
+  vtk_package_dir.append(vtk_build_dir);
+  QFileInfo fi(vtk_package_dir);
+  vtk_package_dir = fi.absoluteFilePath();
+  if (fi.isDir())
+    {
+    // This executable is running from the build tree.  Prepend the
+    // library directory and package directory to the search path.
+    paths << vtk_package_dir;
+    paths << VTK_PYTHON_LIBRARY_DIR;
+    found_vtk = true;
+    }
+
+  Q_ASSERT(found_vtk);
+  if (!found_vtk)
+    {
+    // TODO Handle case when the application is started from an installed tree
+    }
+#endif
+  
+  return paths;
+}
+
+//-----------------------------------------------------------------------------
+void ctkSimplePythonManager::preInitialization()
+{
+  Superclass::preInitialization();
+
+#if defined(CTK_WRAP_PYTHONQT_LIGHT) || defined(CTK_WRAP_PYTHONQT_FULL)
+  // Initialize wrappers
+  @CTK_PYTHONQT_INITIALIZATION_METHOD_CALL@
+#endif
+
+  // Register decorators
+  this->registerPythonQtDecorator(new ctkSimplePythonQtDecorators(this));  
+  
+  // Add object to python interpreter context
+  this->addObjectToPythonMain("_ctkSimplePythonShellInstance", qApp);
+
+  QString self_dir = QFileInfo(qApp->applicationFilePath()).absolutePath();
+
+  QString initFile = self_dir;
+#if defined(CMAKE_INTDIR)
+  initFile.append("/..");
+#endif
+  initFile.append("/Python/ctkSimplePythonShell.py");
+
+  Q_ASSERT(QFile::exists(initFile));
+
+  // Evaluate application script
+  this->executeFile(initFile);
+}

+ 8 - 0
Applications/ctkSimplePythonShell/ctkSimplePythonShellConfigure.h.in

@@ -9,5 +9,13 @@
 #cmakedefine CTK_WRAP_PYTHONQT_LIGHT
 #cmakedefine CTK_WRAP_PYTHONQT_FULL
 
+//#define CTK_PYTHON_LIBRARY_DIR_BUILD "@LIBRARY_OUTPUT_DIRECTORY@"
+
+#cmakedefine CTK_WRAP_PYTHONQT_USE_VTK
+
+#ifdef CTK_WRAP_PYTHONQT_USE_VTK
+# define VTK_PYTHON_LIBRARY_DIR_BUILD "@VTK_DIR@/bin"
+#endif
+
 #endif
 

+ 40 - 0
Applications/ctkSimplePythonShell/ctkSimplePythonShellMain.cpp

@@ -1,15 +1,46 @@
 
 // Qt includes
 #include <QApplication>
+#include <QTextStream>
 
 // CTK includes
 #include <ctkPythonShell.h>
+#include <ctkCommandLineParser.h>
 
 #include "ctkSimplePythonManager.h"
 
 int main(int argc, char** argv)
 {
   QApplication app(argc, argv);
+
+  ctkCommandLineParser parser;
+  // Use Unix-style argument names
+  parser.setArgumentPrefix("--", "-");
+
+  // Add command line argument names
+  parser.addArgument("help", "h", QVariant::Bool, "Print usage information and exit.");
+  parser.addArgument("interactive", "I", QVariant::Bool, "Enable interactive mode");
+
+  // Parse the command line arguments
+  bool ok = false;
+  QHash<QString, QVariant> parsedArgs = parser.parseArguments(QCoreApplication::arguments(), &ok);
+  if (!ok)
+  {
+    QTextStream(stderr, QIODevice::WriteOnly) << "Error parsing arguments: "
+                                              << parser.errorString() << "\n";
+    return EXIT_FAILURE;
+  }
+
+  // Show a help message
+  if (parsedArgs.contains("help") || parsedArgs.contains("h"))
+  {
+    QTextStream(stdout, QIODevice::WriteOnly) << "ctkSimplePythonShell\n"
+          << "Usage\n\n"
+          << "  ctkSimplePythonShell [options] [<path-to-python-script> ...]\n\n"
+          << "Options\n"
+          << parser.helpText();
+    return EXIT_SUCCESS;
+  }
   
   ctkSimplePythonManager pythonManager;
   
@@ -17,6 +48,15 @@ int main(int argc, char** argv)
   shell.setAttribute(Qt::WA_QuitOnClose, true);
   shell.resize(600, 280);
   shell.show();
+
+  shell.setProperty("isInteractive", parsedArgs.contains("interactive"));
+
+  pythonManager.addObjectToPythonMain("_ctkPythonShellInstance", &shell);
+
+  foreach(const QString& script, parser.unparsedArguments())
+    {
+    pythonManager.executeFile(script);
+    }
   
   return app.exec();
 }