How to collapse a folder by code?

Hi everyone!!
Order all new nodes maked by a process is wonderfull !!!.. Every thing in a human comprensive tree of elements… But I don´t find the way to collapse by code all made folders… Is it possible?

Thanks in advance!!!

You can use SetItemExpanded method of the subject hierarchy node.

1 Like

It also works for collapsing segmentations on Data Tree. Some code to copy/paste:

shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(slicer.mrmlScene)

sceneItemID = shNode.GetSceneItemID()
folderID = shNode.GetItemChildWithName(sceneItemID,"folder_name")
shNode.SetItemExpanded(folderID , False)

SegmentationNode = slicer.mrmlScene.GetFirstNodeByName("segmentationNode_name")
segmentationNodeID = shNode.GetItemByDataNode(SegmentationNode)
shNode.SetItemExpanded(segmentationNodeID , False)

Wonderfull!

Thanks a lot!

1 Like

A bit more complex but in the same line…
Is it possible to reorder items position in the tree? I mean, to put simillar folders one over the other, not following the creation orden…

Thanks in advance!!

You can reorder items using the MoveItem method.

1 Like

I have some problem with MoveItem.
I´ve check both itemIDs and they are right but they don´t move with the function. There is no error message either… I´ve aldo tried to invert items order, but anything happends.
I don´t know what i´m doing wrong.

Thanks

C++ methods cannot log error on the console, so check out the application log for errors or warnings. If there are no messages or you cannot figure out what goes wrong then share your scene (save as .mrb file, upload some, and copy the link here) and the script that does not work as you expect.

There is no error message in slicer log either.

I´ve made a simple example scene with an empty segmentation and 2 folders:

shNode = slicer.vtkMRMLSubjectHierarchyNode.GetSubjectHierarchyNode(slicer.mrmlScene)
sceneItemID = shNode.GetSceneItemID()
folderItemID = shNode.GetItemChildWithName(sceneItemID,'NewFolder')
otherFolderItemID = shNode.GetItemChildWithName(sceneItemID,'OtherFolder')
segmentationItemID = shNode.GetItemChildWithName(sceneItemID,'Segmentation')

I tried:

shNode.MoveItem(otherFolderItemID,segmentationItemID)
shNode.MoveItem(folderItemID,segmentationItemID)

Both send me a “True” but there is no change in Subject Hierarchy order of items…

I´m sure I´m doing something wrong but I can´t find it out.

Thanks and sorry…

I was able to reproduce this update issue. A workaround is to force an update by temporarily switching to scene import state:

slicer.mrmlScene.StartState(slicer.vtkMRMLScene.ImportState)
slicer.mrmlScene.EndState(slicer.vtkMRMLScene.ImportState)

I’ve filed a bug report here:

1 Like

Any solution in the next future?

Hi!

I reached this post because I want to create a folder, put many nodes inside it, and then collapse it using a pyhton script run by prompt with --python-script.

I’m using the code below (from this discussion) to collapse it

but it doesn’t do anything. However when the script ended, if I type the same code in the python interactor it works. Could it be a problem related to the way I use the script? Otherwise, am I missing any lines?

Thanks in advance!!

Hmm maybe it will work if you connect your code to the slicer.util.mainWindow().initialWindowShown signal? I don’t know if the --python-script option already waits for this signal to execute your script. Or maybe you could connect to a qt.QTimer.singleShot with 0 or very small timeout in order to allow other events to process that might be expanding the folder at startup.

I recently ran into a situation where I wanted my script to make some changes to widgets at startup, but it had to happen after everything was sufficiently loaded that it wouldn’t revert my change. Here are the two lines that ended up working for my project: