# \[ctk.ctkDoubleRangeSlider()\] Unable to use setRange() on this class

**URL:** <https://discourse.slicer.org/t/ctk-ctkdoublerangeslider-unable-to-use-setrange-on-this-class/20055>\
**Category:** Development\
**Tags:** python\
**Created:** [October 7, 2021, 5:59pm UTC](https://discourse.slicer.org/t/ctk-ctkdoublerangeslider-unable-to-use-setrange-on-this-class/20055 "2021-10-07T17:59:43Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![strider\_hunter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/strider_hunter/32/8253_2.png) [@strider\_hunter](https://discourse.slicer.org/u/strider_hunter)\
**Post date:** [October 7, 2021, 5:59pm UTC](https://discourse.slicer.org/t/ctk-ctkdoublerangeslider-unable-to-use-setrange-on-this-class/20055/1 "2021-10-07T17:59:43Z")

</div>

Hi,  
Im using Slicer 4.11.0-2020-09-05 and am building a python scriptable module.

**Issue**  
I wish to replicate the behavior of `slicer.qMRMLWindowLevelWidget()` as done on this [line](https://github.com/Slicer/Slicer/blob/v4.11/Libs/MRML/Widgets/qMRMLWindowLevelWidget.cxx#L103), but on my own using `ctk.ctkDoubleRangeSlider()`. I did not use the default `slicer.qMRMLRangeWidget()` since it does not seem to be using a spin box that allows floating values. But i am unable to use `setRange()` on `ctk.ctkDoubleRangeSlider()` and hence it uses the default range of `[0,100]`

**My Code**  
The erroneous line has been commented here

```auto
self.uncMinSpinBox = qt.QDoubleSpinBox()
self.uncMinSpinBox.setRange(0.0, 10.0)
self.uncMinSpinBox.setValue(0.0)
self.uncMinSpinBox.setDecimals(1)
self.uncMinSpinBox.setSingleStep(0.1)
self.uncMinSpinBox.valueChanged.connect(self._uncMinSpinBoxChanged)

self.uncMaxSpinBox = qt.QDoubleSpinBox()
self.uncMaxSpinBox.setRange(0, 10.0)
self.uncMaxSpinBox.setValue(10.0)
self.uncMaxSpinBox.setDecimals(1)
self.uncMaxSpinBox.setSingleStep(0.1)
self.uncMaxSpinBox.valueChanged.connect(self._uncMaxSpinBoxChanged)

self.uncSlider = ctk.ctkDoubleRangeSlider()
# self.uncSlider.setRange(0.0, 10.0) # << -------------- ERRONEOUS LINE
self.uncSlider.orientation=qt.Qt.Horizontal
self.uncSlider.singleStep=0.1
self.uncSlider.setMinimumValue(0.0)
self.uncSlider.setMaximumValue(1.0)
self.uncSlider.positionsChanged.connect(self._onUncSliderChanged)

```

What am I missing here.

---

<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:** [October 7, 2021, 6:15pm UTC](https://discourse.slicer.org/t/ctk-ctkdoublerangeslider-unable-to-use-setrange-on-this-class/20055/2 "2021-10-07T18:15:41Z")

</div>

> [@strider\_hunter](#):
>
> slicer.qMRMLRangeWidget()

The problem is just that `setRange` method is not a property setter and it was not declared as Q\_INVOKABLE either:

> <https://github.com/commontk/CTK/blob/master/Libs/Widgets/ctkDoubleSlider.h#L93>

It is a very easy fix (just add `Q_INVOKABLE` before `void`).

However, you don’t need this, as slicer.qMRMLRangeWidget() uses a double spinbox and sliders. If you set a quantity then the unit and number of decimals will be determined by the unit settings in the application. If you don’t set a quantity then it will be determined automatically (and you can probably add more decimals by typing and/or by hitting Ctrl + +).

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/a/7/a72d187fabbeab4dd4c2d99a6acfe06fe17125ab.png)

---

<div class="post-metadata">

**Author:** ![pieper](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/pieper/32/8_2.png) [@pieper](https://discourse.slicer.org/u/pieper)\
**Post date:** [October 7, 2021, 9:31pm UTC](https://discourse.slicer.org/t/ctk-ctkdoublerangeslider-unable-to-use-setrange-on-this-class/20055/3 "2021-10-07T21:31:10Z")

</div>

+1 for making range a property

---

<div class="post-metadata">

**Author:** ![jamesobutler](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/jamesobutler/32/7511_2.png) [@jamesobutler](https://discourse.slicer.org/u/jamesobutler)\
**Post date:** [October 7, 2021, 9:58pm UTC](https://discourse.slicer.org/t/ctk-ctkdoublerangeslider-unable-to-use-setrange-on-this-class/20055/4 "2021-10-07T21:58:26Z")

</div>

> [@strider\_hunter](#):
>
> Im using Slicer 4.11.0-2020-09-05

If you are looking to create a widget similar to `slicer.qMRMLWindowLevelWidget` where you are also using it to manage Window Level, I would suggest that your try out the latest Slicer Preview as this widget has changed since the version that you are using which is over a year old.

In the latest Slicer Preview you can do the following to set the range of the Window level bounds. Note the difference between setting the bounds versus setting the upper and lower values of the active range.

```python
# Load sample volume
import SampleData
sampleDataLogic = SampleData.SampleDataLogic()
mrHead = sampleDataLogic.downloadMRHead()

widget = slicer.qMRMLWindowLevelWidget()
widget.setMRMLVolumeNode(mrHead)
widget.setMinMaxBounds(-200, 200)
widget.setMinMaxRangeValue(-100,100)
widget.show()

```

 ![image](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/e/c/ec7b8b14e8166c31c695c75ad060783816a2f0b5.png)

---

<div class="post-metadata">

**Author:** ![strider\_hunter](https://sea2.discourse-cdn.com/flex002/user_avatar/discourse.slicer.org/strider_hunter/32/8253_2.png) [@strider\_hunter](https://discourse.slicer.org/u/strider_hunter)\
**Post date:** [October 8, 2021, 10:53am UTC](https://discourse.slicer.org/t/ctk-ctkdoublerangeslider-unable-to-use-setrange-on-this-class/20055/5 "2021-10-08T10:53:20Z")

</div>

> [@lassoan](#):
>
> qMRMLRangeWidget

Thanks @lassoan !  
I followed your suggestion and did the following.

```auto
self.uncSlider2 = slicer.qMRMLRangeWidget()
self.uncSlider2.setRange(0.0, 1.0)
self.uncSlider2.singleStep=0.1 # <----- this did the trick
self.uncSlider2.valuesChanged.connect(self._onUncSliderChanged2)
viewParametersFormLayout.addRow(self.uncSlider2)

```

It now looks like this  
 ![qMRMLRangeWidget](https://us1.discourse-cdn.com/flex002/uploads/slicer/original/3X/7/d/7d5fc657e5f0c6f075dc5207def0378c56d7e225.png)

But, I was unable to find ([here](https://apidocs.slicer.org/v4.11/classqMRMLRangeWidget.html) or [here](https://github.com/Slicer/Slicer/blob/v4.11/Libs/MRML/Widgets/qMRMLRangeWidget.cxx)) a function to avoid showing the circled item.  
I may sound too pedantic, but given that I am designing this interface for clinicians, I would prefer keeping the interface as minimal as possible. I do not want the users playing with the min and max values of the range.

---

<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:** [October 8, 2021, 2:33pm UTC](https://discourse.slicer.org/t/ctk-ctkdoublerangeslider-unable-to-use-setrange-on-this-class/20055/6 "2021-10-08T14:33:56Z")

</div>

We don’t always expose specific API to manipulate such small details, but you can always have full access to all Qt widgets that you can use (at your won risk). Hiding the button has no risk, and probably it is not a very common need (so there would be no need to create a specific API for it), so you can just get that button and hide it:

```python
tripleDotButton = slicer.util.findChildren(self.uncSlider2, className='QToolButton')[0]
tripleDotButton.hide()

```

If you need a list of child widgets (so that you know the type and name of the object), you can use `slicer.util.findChildren` method, specifying just the parent widget.
