Macro XML to python

Hi, I’m recording some macros and I want to know if there’s any way that I can convert the XLM code to python code for Slicer.
Thanks

There are currently no way of recording macro as python script. As described below, there is a way to record python code but this would be very similar to the generated XML and challenging to maintain.

Question: What are you trying to achieve ? By understanding this, we may be able to better answer your question.

For now, I instead suggest to write self test by hand.

There are a lot of python snippets available here, and the extension wizard will create a skeleton of module including the relevant infrastructure to run the test.

Enabling macro recording

Answers in this post assumes you are talking about using QtTesting functionality that can be enabled through the settings:

image

QtTesting and python

All of that said, we could look into generating python code similar to what is done in Paraview (see here). The code would be similar to the one posted below:

import QtTesting
import QtTestingImage
object1 = 'MainWindow/menubar/menuFile'
QtTesting.playCommand(object1, 'activate', 'actionFileLoadServerState')
object2 = 'MainWindow/ServerStartupBrowser/connect'
QtTesting.playCommand(object2, 'activate', )
object3 = 'MainWindow/FileLoadServerStateDialog'
QtTesting.playCommand(object3, 'filesSelected', '$PARAVIEW_DATA_ROOT/Data/LoadStateMultiView.pvsm')
snapshotWidget = 'MainWindow/1pqRenderWindowManager0/SplitterFrame/MultiViewSplitter/0/Viewport'
QtTestingImage.compareImage(snapshotWidget, 'LoadStateMultiView.png', 200, 200);

Recording GUI events (button clicks, etc.) has very limited use (only for testing, and even there it is quite fragile). Meaningful workflow automation Python scripts should operate at lower level, by changing properties of MRML nodes and calling module logic functions.

I’ve recently implemented a simple Python script that observes all MRML node changes and generate a list of node property modifications (by comparing MRML node PrintSelf results before and after the node modification). This can be used to generate a runnable, user-editable Python script. This is similar to what Paraview can do. However, this turned out not to be very useful, because it is too low level (for a single user action you get a bunch of node property modification events, but you don’t know why the node ended up being modified like that).

What we would really need is an intermediate level, where a user action is translated to a few high-level method calls. I’m not sure what is the easiest way to achieve this. Maybe we could add a specially formatted log message whenever a logic method is called (and macro recording is enabled), and these could be easily converted to runnable Python code.

2 Likes

Having a log of what logic methods are called would be really great. Module logic is not always intuitive and having the system to give some clue on where to look for the methods that replicate the actions that the user has just done via the UI would really speed up the creation of simple automations.

hi i want to do this image
open 2 files at the same time and select a freeSurferLabels
just this by python code

larssoan could you please show me this script
-implemented a simple Python script that observes all MRML node changes and generate a list of node property modifications (by comparing MRML node PrintSelf results before and after the node modification)

when i code this:

import QtTesting
import QtTestingImage

a get this message :

Traceback (most recent call last):
  File "<string>", line 1, in <module>
  File "C:/Users/aldot/AppData/Roaming/NA-MIC/Extensions-28257/Sandbox/lib/Slicer-4.10/qt-scripted-modules/UserStatistics.py", line 805, in <module>
    class IdleDetectionEventFilter(qt.QObject):
AttributeError: 'module' object has no attribute 'QObject'

Assuming the SlicerFreeSurfer extension is installer, the follow will allow you to load files using python:

slicer.util.loadVolume('/path/to/volume.nrrd', {'colorNodeID': 'vtkMRMLColorTableNodeFile'})
slicer.util.loadLabelVolume('/path/to/label.nrrd')

For list of properties that can be passed to loadVolume and loadLabelVolume, see Developer Guide / Modules API / Volumes / Reading from file

This was an example of code used in Paraview, it is not supported in Slicer.

thanks, it works, not as I like to
but I going to play a little to get the colors I want.
i leave the code :

slicer.util.loadVolume('C:/Users/aldot/Desktop/Seg30/Aldo 3/Done/IXI-aseg.mgz', {'colorNodeID': 'vtkMRMLColorTableNodeFileGenericColors.txt'})

i couldn’t use this one returns a falls state:

slicer.util.loadLabelVolume('/path/to/label.nrrd')
slicer.util.loadLabelVolume('C:/Program Files/Slicer 4.10.2/share/FreeSurfer')
False
slicer.util.loadLabelVolume('C:/Program Files/Slicer 4.10.2/share/Slicer-4.10/ColorFiles/Inferno.txt')
False
slicer.util.loadVolume('C:/Users/aldot/Desktop/Seg30/Aldo 3/Done/IXI134-aseg.mgz', {'colorNodeID': 'vtkMRMLColorTableNodeFile'})

this one for free surfer but because there are 3 diferent files i dont know what to do

now it works perfect thanks for the information.

slicer.util.loadVolume('C:/Users/aldot/Desktop/Seg30/Aldo 3/Done/IXI-nu.mgz')
slicer.util.loadLabelVolume('C:/Users/aldot/Desktop/Seg30/Aldo 3/Done/IXI-aseg.mgz', {'colorNodeID': 'vtkMRMLColorTableNodeFile'})
1 Like