# Calling Python from C++

**URL:** https://discourse.slicer.org/t/calling-python-from-c/7841
**Category:** Development
**Created:** [August 1, 2019, 6:18pm UTC](https://discourse.slicer.org/t/calling-python-from-c/7841 "2019-08-01T18:18:37Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![rprueckl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rprueckl/32/4240_2.png) [@rprueckl](https://discourse.slicer.org/u/rprueckl)
#### Post date: [August 1, 2019, 6:18pm UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/1 "2019-08-01T18:18:37Z")

</div>

Hi, as the title suggests, the question is whether there is a possibility to call a scripted python module from C++, and if yes, how to do that.

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [August 1, 2019, 6:33pm UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/2 "2019-08-01T18:33:07Z")

</div>

In general, infrastructure is implemented in C++ (it is a bit more work but code is usually more robust, easier to maintain, and has better performance), which is easily accessible from both Python and C++.

If you want to call Python from C++ then it means that infrastructure-like code is implemented in Python, which is not desirable.

If you are sure that you must call Python from C++ then you can use a Python scripted CLI module with a C++ interface (the same way as you would [run any other CLI module from C++](https://github.com/Slicer/Slicer/blob/dc72547a0252053ec751924fdb75ef36e0c1718d/Modules/Loadable/CropVolume/Logic/vtkSlicerCropVolumeLogic.cxx#L577-L581)) or you can run arbitrary Python code using [`evalScript`](https://github.com/Slicer/Slicer/blob/dc72547a0252053ec751924fdb75ef36e0c1718d/Modules/Loadable/Segmentations/qSlicerSegmentationsModule.cxx#L198-L200).

---

<div class="post-metadata">

### Author: ![rprueckl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rprueckl/32/4240_2.png) [@rprueckl](https://discourse.slicer.org/u/rprueckl)
#### Post date: [August 1, 2019, 7:18pm UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/3 "2019-08-01T19:18:13Z")

</div>

Yes, that’s clear. The question was regarding a Python scripted CLI (e.g. Surface Toolkit) that I want to use in my workflow. I tried it with pattern I used for calling CLI modules, but somehow I got null pointers… I will try again…

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [August 1, 2019, 9:12pm UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/4 "2019-08-01T21:12:32Z")

</div>

Currently, surface toolkit is a Python scripted module, not a CLI. We left it like this, because it exposes very simple features (few lines of code each). The module is currently being reworked. What Surface toolbox feature would you like to use in your module?

---

<div class="post-metadata">

### Author: ![rprueckl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rprueckl/32/4240_2.png) [@rprueckl](https://discourse.slicer.org/u/rprueckl)
#### Post date: [August 2, 2019, 7:27am UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/5 "2019-08-02T07:27:36Z")

</div>

Sure, wrong terminology on my side.  
I find the ‘Connectivity’ tool very handy. I saw in the source code that there was a suggestion to consider a certain minimum size for the individual parts, which I also would find very useful.

---

<div class="post-metadata">

### Author: ![rprueckl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rprueckl/32/4240_2.png) [@rprueckl](https://discourse.slicer.org/u/rprueckl)
#### Post date: [August 2, 2019, 1:33pm UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/6 "2019-08-02T13:33:05Z")

</div>

Sorry, I’m stuck with this one. Is there a difference between a Python scripted CLI module and a Python scripted module?

For calling the SurfaceToolbox this is what I have:

```auto
qSlicerScriptedLoadableModule* scrModule = static_cast<qSlicerScriptedLoadableModule*>(qSlicerCoreApplication::application()->moduleManager()->module("SurfaceToolbox"));
qSlicerScriptedLoadableModuleWidget *scrWidget = static_cast<qSlicerScriptedLoadableModuleWidget*>(scrModule->widgetRepresentation());
vtkSlicerScriptedLoadableModuleLogic* moduleLogic = vtkSlicerScriptedLoadableModuleLogic::SafeDownCast(scrModule->logic());

// create scripted module node
d->scrNode = vtkMRMLScriptedModuleNode::SafeDownCast(scene->CreateNodeByClass("vtkMRMLScriptedModuleNode"));
d->scrNode->Register(d);

// Add node to the scene
scene->AddNode(d->scrNode);

// set node to widget
scrWidget->setEditedNode(d->scrNode);

// set parameters
d->scrNode->SetParameter("connectivity", "true");

```

I do not know how to execute the logic, as there is no `Apply` method. Moreover, I don’t know how to specify the input and output models.

---

<div class="post-metadata">

### Author: ![rprueckl](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/rprueckl/32/4240_2.png) [@rprueckl](https://discourse.slicer.org/u/rprueckl)
#### Post date: [August 6, 2019, 11:34am UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/7 "2019-08-06T11:34:58Z")

</div>

Considering the comments from [here](https://discourse.slicer.org/t/updated-sample-code-for-calling-cli-via-c/7840/4), I reduced the code as follows, but still the question remains: can I execute the scripted module based on the following code? How would I do that?

```auto
// get module and its widget
qSlicerScriptedLoadableModule* scrModule = static_cast<qSlicerScriptedLoadableModule*>(qSlicerCoreApplication::application()->moduleManager()->module("SurfaceToolbox"));
vtkSlicerScriptedLoadableModuleLogic* moduleLogic = vtkSlicerScriptedLoadableModuleLogic::SafeDownCast(scrModule->logic());

// create scripted module node
vtkMRMLScriptedModuleNode* scrNode = vtkMRMLScriptedModuleNode::SafeDownCast(scene->CreateNodeByClass("vtkMRMLScriptedModuleNode"));
scene->AddNode(scrNode);

// set parameters
scrNode->SetParameter("connectivity", "true");

// TBD: set input/output nodes
// TBD: start execution

```

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [August 7, 2019, 4:45am UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/8 "2019-08-07T04:45:37Z")

</div>

You can use Python scripted modules using `evalScript`. For example:

```
PythonQt::init();
PythonQtObjectPtr context = PythonQt::self()->getMainModule();
context.evalScript(QString("import SampleData; SampleData.SampleDataLogic().downloadMRHead()"));
```

---

<div class="post-metadata">

### Author: ![Zhiy](https://avatars.discourse-cdn.com/v4/letter/z/0ea827/32.png) [@Zhiy](https://discourse.slicer.org/u/Zhiy)
#### Post date: [June 26, 2020, 2:29pm UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/9 "2020-06-26T14:29:49Z")

</div>

Hi, I am trying to call a Python script (python3.7) that runs scipy functions in Slicer C++ module. Can I do this?

---

<div class="post-metadata">

### Author: ![lassoan](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/lassoan/32/13_2.png) [@lassoan](https://discourse.slicer.org/u/lassoan)
#### Post date: [June 26, 2020, 3:14pm UTC](https://discourse.slicer.org/t/calling-python-from-c/7841/10 "2020-06-26T15:14:44Z")

</div>

There are several options for calling Python from C++ (one of them is shown in my comment above, using `evalScript`) and it is done at many places in Slicer. However, C++ modules provide low-level infrastructure, so it would not make sense for a C++ module to depend on Python.

If you want to implement some performance-critical processing in C++ but other features are in Python then I would recommend to:

- create a hidden C++ loadable module that just implements performance-critical processing in its logic classes: these classes are all Python-wrapped and so can be used from either C++ of Python modules
- create Python-scripted module that uses your C++ module’s logic and any Python packages (scipy, etc.)

Also note that VTK, ITK, and other libraries bundled with Slicer already provide many features of scipy, so you may remove the need to call Python from C++ by using those libraries instead.
