View Issue Details

IDProjectCategoryView StatusLast Update
0004051Slicer4Core: Scripting (Wrapping, Python)public2015-09-21 09:21
Reporterlassoan Assigned Tojcfr  
PrioritynormalSeverityminorReproducibilityalways
Status assignedResolutionopen 
Product Version 
Target VersionFixed in Version 
Summary0004051: No logic object is instantiated for scripted modules
Description

Scripted modules currently cannot do anything until the widget class is instantiated, because Slicer does not instantiate the module logic class. This is a problem because it is not possible to create "background" modules in Slicer, which performs operations without requiring the user to open the module's user interface.

Slicer correctly instantiated module logic class for loadable modules. Instantiation is performed in an order computed based on specified module dependencies.

Workarounds, such as creating logic class manually would not be consistent with other types of modules and would not work because dependencies between modules are ignored:

  • logic cannot be created in the module class, because logic may depend on other module's logic, which are not available at that time
  • logic cannot be created with a hack such as setting up a single-shot timer to create it after Slicer has "started", because multiple modules that use the same technique would be served in random order, therefore module logic could be attempted to be created earlier than all the required modules' logic are created
TagsNo tags attached.

Activities

pieper

pieper

2015-09-21 06:55

administrator   ~0013286

Agreed - scripted modules should have all the same features and behave consistently with any other module (as much as possible).

jcfr

jcfr

2015-09-21 08:28

administrator   ~0013287

Couldn't agree more. Few years ago, in an attempt to address this, we created:

vtkSlicerScriptedLoadableModuleLogic [1]

Similarly to loadable module, this would allow the logic of scripted module to be instantiated before the associated representation.

This raises the following questions / remarks:

(1) Being able to leverage QtCore classes in python logic has been great.

(2) Currently, loadable logic only depends on VTK/ITK. The base class derives from vtkObject and there are no dependency on Qt. We could either:

  • introduce a base class named QtCore/qSlicerModuleLogic (similar to vtkSlicerModuleLogic)
  • or allow existing vtkSlicer[Name]ModuleLogic to depends on QtCore

[1] https://github.com/Slicer/Slicer/blob/master/Base/Logic/vtkSlicerScriptedLoadableModuleLogic.h

pieper

pieper

2015-09-21 08:34

administrator   ~0013288

Yes, it's aways been possible for scripted logics to use qt and being explicit that QtCore is exptected makes sense. This would give a hook for implementing the things Andras mentions.

lassoan

lassoan

2015-09-21 08:51

developer   ~0013289

Making module logic depend on Qt would be a huge change. For me it would only make sense if we made all MRML classes to be based on Qt instead of MRML but then we would depend on Qt forever, for everything. Using Qt instead of VTK would have serious performance consequences, as VTK observers are typically about 10x faster than Qt signals/slots.

Developers can still leverage qt features in their scripted module logic if Qt dependency is not an issue (it's typically not, as scripted modules are mostly high-level application modules anyway).

lassoan

lassoan

2015-09-21 09:14

developer   ~0013290

Something like that is done for the module widget would work well:

  • create Python object
  • forward C++ interface method calls to Python
  • have a slicer.modules.somescriptedmodule.logic().self() method for accessing the complete python logic object

I see that Python object creation code is there but it is commented out:
//-----------------------------------------------------------------------------
vtkMRMLAbstractLogic* qSlicerScriptedLoadableModule::createLogic()
{
// Q_D(qSlicerScriptedLoadableModule);

vtkSlicerScriptedLoadableModuleLogic* logic = vtkSlicerScriptedLoadableModuleLogic::New();

// bool ret = logic->SetPythonSource(d->PythonSource.toStdString());
// if (!ret)
// {
// logic->Delete();
// return 0;
// }

return logic;
}

jcfr

jcfr

2015-09-21 09:21

administrator   ~0013291

I see that Python object creation code is there but it is commented out:

Indeed, at that time we didn't have a use case. The idea of having a dedicated Python class to implement the logic wasn't formalised.

Now we have more use case, it would be great to have the scripted logic instantiated by the module manager.

That said, some more work would be needed to implement the "reload" function directly within the module manager. Otherwise, the existing "Reload and Test" wouldn't be as useful.

Issue History

Date Modified Username Field Change
2015-09-21 06:51 lassoan New Issue
2015-09-21 06:51 lassoan Status new => assigned
2015-09-21 06:51 lassoan Assigned To => jcfr
2015-09-21 06:55 pieper Note Added: 0013286
2015-09-21 08:28 jcfr Note Added: 0013287
2015-09-21 08:34 pieper Note Added: 0013288
2015-09-21 08:51 lassoan Note Added: 0013289
2015-09-21 09:14 lassoan Note Added: 0013290
2015-09-21 09:21 jcfr Note Added: 0013291