Connecting vtk plane widget to a ctk slider

I’ve received a lot of feedback in regards to how widgets work and am now moving forward with the suggestions. However, I am curious as to whether there is a way to connect existing widget functionalities with slider widgets? For example in my case, the vtk implicit plane widget allows rotation of slices. Is it possible to make connections of this to a ctk slider, i.e, make it such that I can move the ctk slider to update the angle of the slice that the implicit plane widget controls?

Thank you very much for the help!

Hi Asheu,

you may have a look here:

Essentially I have a value from a slider in my module GUI and i use the value to rotate the a slice in the XY plane. You don’t need to set the center of the slice (i.e. 4 colomun of the slice matrix yellowSliceToRAS, https://github.com/Punzo/SlicerAstro/blob/master/AstroModeling/qSlicerAstroModelingModuleWidget.cxx#L2848-L2855).

actually you can have also a look at the module Reformat, it does what you need.

for the reformat module, i’m finding that its functionality is in moving the angle through dragging the cursor which is comparably more difficult to find the slice angle that I want. That is why I am thinking that I could have a ctk slider being implemented in conjunction with the implicit plane widget so that it moves through slight angles at a time.

In any case, thank you very much for the sample code! I was wondering however which of the widgets were being connected? Are the nodes simply being connected to the qSlicerAstro widget?

sorry maybe we are not understanding each other:

image

in the module GUI you have 3 slider widgets (LR, PA, IS) which enable to set the angle of the slice rotation (kind of Euler angles). Is this not what you need??

in my sample code the value of the rotation is saved in a parameter node which is modified here when you interact with the ctkslider:

the slot onMRMLYellowSliceRotated is connected with the parameter node here:

1 Like

My apologies, I’ve updated this response a few times. I think what I am trying to do is to fix both the LR and IS slider in the Reformat module widget, and instead, only allow the user to change the PA slider. In that sense, I am looking for parts of the reformat widget that would allow us to eliminate the 2 other sliders

i believe this should be easily achievable through the sample widget that you have created correct?

Yes, you can take a look at the code of the reformat module regarding one slider or use my sample code (if I remember well the only difference between the two is that I store the value of the slider in a MRMLParameterNode).

1 Like

been delving through the code in the last few days and still a bit in over my head. is the ctk slider something that was packaged into the MRML parameter node or was there a particular location in the code where you called it to throw it into the GUI?

also cannot seem to find the part of the code that might control the LR, PA and IS orientations that the sliders would seem to modulate (and can’t seem to locate the source code for the reformat module either…)

Lot of questions but thank you so much for your responses, I really appreciate it

Hi Alex, no problem.

  1. the ctk widget in my code was created using the designer (./Slicer --designer). There you can find all the ctk widgets. If you don’t want use the designer or you are using python, here is some C++ code taken from my ui file:

    ctkSliderWidget *GreenSliceSliderWidget;
    GreenSliceSliderWidget = new ctkSliderWidget(OutputCollapsibleButton_2);
    GreenSliceSliderWidget->setObjectName(QStringLiteral(“GreenSliceSliderWidget”));
    GreenSliceSliderWidget->setMinimum(-200);
    GreenSliceSliderWidget->setMaximum(200);
    GreenSliceSliderWidget->setValue(0);
    gridLayout_2->addWidget(GreenSliceSliderWidget, 1, 1, 1, 1);

  2. and here are the main parts of the code related to the rotation in the reformat module:

I hope this help

NOTE: while in 3DSlicer is always very nice to use MRMLNode to store parameters regarding the data and the GUI of a module, I advice you for the moment just to follow the implementation of the Reformat module.
Later on, if you’d like to see how a proper module should be designed and implemented, you can have a look at the Crop module (https://github.com/Slicer/Slicer/tree/master/Modules/Loadable/CropVolume).

1 Like

thank you so much! this has been very helpful!

1 Like

@Davide_Punzo I hope this finds you well. I was wondering from your UI file, is the OutputCollapsibleButton something that you had defined? Or is it a parameter that the ctkSliderWidget object can take in.

Also if possible, I was wondering what the ‘d’ object in the rotational sliders are. I see that the Reformat ModuleWidget defines it as such:

Q_D(qSlicerReformatModuleWidget);
d->setupUi(this);

Is d just a default set up of the UI?

Hi Alex,

  1. the OutputCollapsibleButton is a ctk widget.
    here the code generated by the designer:

     OutputCollapsibleButton = new ctkCollapsibleButton(qSlicerAstroModelingModuleWidget);
     OutputCollapsibleButton->setObjectName(QStringLiteral("OutputCollapsibleButton"));
     OutputCollapsibleButton->setEnabled(true);
     QSizePolicy sizePolicy8(QSizePolicy::Minimum, QSizePolicy::Expanding);
     sizePolicy8.setHorizontalStretch(0);
     sizePolicy8.setVerticalStretch(0);
     sizePolicy8.setHeightForWidth(OutputCollapsibleButton->sizePolicy().hasHeightForWidth());
     OutputCollapsibleButton->setSizePolicy(sizePolicy8);
     OutputCollapsibleButton->setChecked(true);
     OutputCollapsibleButton->setCollapsed(false);
    
  2. for d pointers, here is a reference: https://wiki.qt.io/D-Pointer

The d pointers point to the Private class, i.e. to:

1 Like