# Accessing a custom loadable module's logic from python

**URL:** https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318
**Category:** Development
**Created:** [March 3, 2021, 2:07am UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318 "2021-03-03T02:07:15Z")
**Posts on this page:** 10
**Page:** 1

<div class="post-metadata">

### Author: ![hphalen](https://avatars.discourse-cdn.com/v4/letter/h/c6cbf5/32.png) [@hphalen](https://discourse.slicer.org/u/hphalen)
#### Post date: [March 3, 2021, 2:07am UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/1 "2021-03-03T02:07:16Z")

</div>

Hello, I am working with an existing custom loadable module (written in C++) and was hoping to be able to access functions from the module’s logic in the python interface and/or within a scripted python module.

For the existing modules that come with Slicer, I typically do this as recommended here [How to call a function from the logic - #2 by pieper](https://discourse.slicer.org/t/how-to-call-a-function-from-the-logic/6433/2)

e.g.

```auto
slicer.modules.screencapture.widgetRepresentation().self().logic

```

However, for the loadable module that was developed in my group, the widgetRepresentation does not have a ‘self’. I was wondering if it is even possible to access the logic of C++ loadable modules in this way?

---

<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: [March 3, 2021, 2:11am UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/2 "2021-03-03T02:11:43Z")

</div>

For Python scripted modules, you need to call `self()` to get the Python implementation of the generic C++ widget representation, an call `logic` because in scripted modules it makes dynamic reloading of the module much easier if the widget owns the logic. In C++ you don’t need any of these, so you can simply call `logic()` method of the module class, for example: `slicer.modules.volumerendering.logic()`.

This and many other useful concepts are described in the PerkLab developer tutorial: [Documentation/Nightly/Training - Slicer Wiki](https://www.slicer.org/wiki/Documentation/Nightly/Training#PerkLab.27s_Slicer_bootcamp_training_materials)

---

<div class="post-metadata">

### Author: ![pll\_llq](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pll_llq/32/9408_2.png) [@pll\_llq](https://discourse.slicer.org/u/pll_llq)
#### Post date: [March 3, 2021, 11:13am UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/3 "2021-03-03T11:13:45Z")

</div>

> [@lassoan](#):
>
> it makes dynamic reloading of the module much easier if the widget owns the logic

This is the answer to a question I had after I went through the tutorials after the call on Tuesday=)  
Thanks for the advice to revisit the PerkLab presentations. It really is an iterative process.

---

<div class="post-metadata">

### Author: ![hphalen](https://avatars.discourse-cdn.com/v4/letter/h/c6cbf5/32.png) [@hphalen](https://discourse.slicer.org/u/hphalen)
#### Post date: [March 3, 2021, 6:16pm UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/4 "2021-03-03T18:16:47Z")

</div>

Thank you for your response! The distinction is clear - I had not seen this PerkLab tutorial before so thank you for the link.

I tried the `slicer.modules.modulename.logic()` route previously, but did not get access to any of the logic methods from the module, just standard ones (e.g. `AddObserver()`, `BreakOnError()`, etc.) so I thought it was the wrong approach. Instead, it seems there must be an implementation issue with the loadable module I am using such that it isn’t exposing these methods correctly.

I wanted to make sure that my assumption/understanding is correct as I try to hunt down the issue. If things are done correctly, should I be able to call all of the public methods of `vtkSlicer[ModuleName]Logic` from Python using the method we discussed of

```auto
logic = slicer.modules.modulename.logic()
logic.method() 

```

?

To be (hopefully) more clear, the setup is as follows:  
There is a module which in the top-level directory has `qSlicerUniversalRobotModule.cxx(/h)` and `qSlicerUniversalRobotModuleWidget.cxx(/h)`. The module has a `createLogic()` method which creates a new instance of `vtkSlicerUniversalRobotLogic`, which is derived from `vtkSlicerModuleLogic`. Basically, my questions i, if everything was set up correctly, should I be able to access the public methods of this `vtkSlicerUniversalRobotLogic`?

Thanks 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: [March 3, 2021, 6:37pm UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/5 "2021-03-03T18:37:07Z")

</div>

> [@hphalen](#):
>
> should I be able to call all of the public methods of ‘vtkSlicer[ModuleName]Logic’ from Python using the method we discussed of  
> logic = slicer.modules.modulename.logic()  
> logic.method() ?

Yes.

> [@hphalen](#):
>
> if everything was set up correctly, should I be able to access the public methods of this vtkSlicerUniversalRobotLogic?

Yes.  
The first thing to check is the class name that is displayed when you call `slicer.modules.modulename.logic()`. If that’s correct then you can call `help(slicer.modules.modulename.logic())` to see what methods are visible from Python.

---

<div class="post-metadata">

### Author: ![hphalen](https://avatars.discourse-cdn.com/v4/letter/h/c6cbf5/32.png) [@hphalen](https://discourse.slicer.org/u/hphalen)
#### Post date: [March 3, 2021, 6:41pm UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/6 "2021-03-03T18:41:57Z")

</div>

Thanks - for me it says the following when I call `slicer.modules.modulename.logic()`:  
vtkCommonCorePython.vtkSlicerModuleLogic.

I imagine if this was working correctly it would say vtkSlicerUniversalRobotModuleLogic? If so, I at least know my problem now 🙂

---

<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: [March 3, 2021, 7:36pm UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/7 "2021-03-03T19:36:56Z")

</div>

There is either something unusual in the logic class header file (e.g., you have included some headers from a third-party library - those should be all just included in the implementation cxx file), or maybe there is something wrong with the export declaration (between `class` keyword and class name in the header file). You can make a verbatim copy of a loadable module from an extension and see if you see the logic methods. If yes, then you can start modifying it step by step and see what change causes failure of the Python wrapping.

---

<div class="post-metadata">

### Author: ![hphalen](https://avatars.discourse-cdn.com/v4/letter/h/c6cbf5/32.png) [@hphalen](https://discourse.slicer.org/u/hphalen)
#### Post date: [March 3, 2021, 8:13pm UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/8 "2021-03-03T20:13:54Z")

</div>

> There is either something unusual in the logic class header file (e.g., you have included some headers from a third-party library

This is exactly the problem, and it is done quite liberally. Many of the variables are of types defined by headers outside of Slicer (from internal code developed in our group). Basically, I think previous developers have baked in a lot of extraneous things into this logic code that should be elsewhere if done correctly. I don’t see a straightforward way of moving that over to the implementation, so unfortunately I will either have to do a large refactoring of this or find some other approach…

Thank you for you help - figuring out the issue here has been very helpful.

---

<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: [March 3, 2021, 8:55pm UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/9 "2021-03-03T20:55:09Z")

</div>

No redesign should be needed. You can use the private implementation (PIMPL) pattern, it is used many places (search for `vtkInternal`).

In general, logic should encapsulate libraries: classes from third-party libraries should not leak out to public interface of a logic class.

---

<div class="post-metadata">

### Author: ![hphalen](https://avatars.discourse-cdn.com/v4/letter/h/c6cbf5/32.png) [@hphalen](https://discourse.slicer.org/u/hphalen)
#### Post date: [March 4, 2021, 9:23pm UTC](https://discourse.slicer.org/t/accessing-a-custom-loadable-modules-logic-from-python/16318/10 "2021-03-04T21:23:55Z")

</div>

Thanks you Andras. This was very helpful. I was able to implement this and it seems to be working!

I just wanted to leave a note here in case someone runs into the same problem in the future. While I needed to do what was described above, I also found that there was the following line ‘DISABLE\_WRAP\_PYTHON’ in the CMakeLists in the Logic folder of the Loadable Module (see below). Unsurprisingly(!), if this is here, no matter how clean your logic headers are, the python wrapping will be skipped.

```auto
  NAME ${KIT}
  EXPORT_DIRECTIVE ${${KIT}_EXPORT_DIRECTIVE}
  INCLUDE_DIRECTORIES ${${KIT}_INCLUDE_DIRECTORIES}
  SRCS ${${KIT}_SRCS}
  TARGET_LIBRARIES ${${KIT}_TARGET_LIBRARIES}
  DISABLE_WRAP_PYTHON
  )

```

Thanks again!
