From cfb913d8a865912f521fe3556b96bda7ef565720 Mon Sep 17 00:00:00 2001 From: "Gregory R. Lee" Date: Tue, 9 Sep 2014 16:16:32 -0400 Subject: [PATCH 1/6] add CheckBox widget to viewer. fix ComboBox widget docstring --- skimage/viewer/tests/test_widgets.py | 17 +++++++- skimage/viewer/widgets/core.py | 65 +++++++++++++++++++++++++--- 2 files changed, 75 insertions(+), 7 deletions(-) diff --git a/skimage/viewer/tests/test_widgets.py b/skimage/viewer/tests/test_widgets.py index ee4c91fb..d83f54ac 100644 --- a/skimage/viewer/tests/test_widgets.py +++ b/skimage/viewer/tests/test_widgets.py @@ -3,7 +3,7 @@ import os from skimage import data, img_as_float, io from skimage.viewer import ImageViewer, viewer_available from skimage.viewer.widgets import ( - Slider, OKCancelButtons, SaveButtons, ComboBox, Text) + Slider, OKCancelButtons, SaveButtons, ComboBox, CheckBox, Text) from skimage.viewer.plugins.base import Plugin from skimage.viewer.qt import QtGui, QtCore from numpy.testing import assert_almost_equal, assert_equal @@ -16,6 +16,20 @@ def get_image_viewer(): viewer += Plugin() return viewer +@skipif(not viewer_available) +def test_check_box(): + viewer = get_image_viewer() + cb = CheckBox('hello', value=True, alignment='left') + viewer.plugins[0] += cb + + assert_equal(cb.val, True) + cb.val = False + assert_equal(cb.val, False) + cb.val = 1 + assert_equal(cb.val, True) + cb.val = 0 + assert_equal(cb.val, False) + @skipif(not viewer_available) def test_combo_box(): @@ -29,7 +43,6 @@ def test_combo_box(): assert_equal(str(cb.val), 'c'), assert_equal(cb.index, 2) - @skipif(not viewer_available) def test_text_widget(): viewer = get_image_viewer() diff --git a/skimage/viewer/widgets/core.py b/skimage/viewer/widgets/core.py index 74fe9de4..85302aaa 100644 --- a/skimage/viewer/widgets/core.py +++ b/skimage/viewer/widgets/core.py @@ -22,7 +22,7 @@ from ..qt.QtCore import Qt from ..utils import RequiredAttr -__all__ = ['BaseWidget', 'Slider', 'ComboBox', 'Text'] +__all__ = ['BaseWidget', 'Slider', 'ComboBox', 'CheckBox', 'Text'] class BaseWidget(QtGui.QWidget): @@ -211,16 +211,16 @@ class ComboBox(BaseWidget): Parameters ---------- name : str - Name of slider parameter. If this parameter is passed as a keyword + Name of ComboBox parameter. If this parameter is passed as a keyword argument, it must match the name of that keyword argument (spaces are replaced with underscores). In addition, this name is displayed as the - name of the slider. - items: list + name of the ComboBox. + items: list of str Allowed parameter values. ptype : {'arg' | 'kwarg' | 'plugin'} Parameter type. callback : function - Callback function called in response to slider changes. This function + Callback function called in response to ComboBox changes. This function is typically set when the widget is added to a plugin. """ @@ -253,3 +253,58 @@ class ComboBox(BaseWidget): @index.setter def index(self, i): self._combo_box.setCurrentIndex(i) + +class CheckBox(BaseWidget): + """CheckBox widget + + Parameters + ---------- + name : str + Name of CheckBox parameter. If this parameter is passed as a keyword + argument, it must match the name of that keyword argument (spaces are + replaced with underscores). In addition, this name is displayed as the + name of the CheckBox. + value: {False, True} + Initial state of the CheckBox. + alignment: {'center','left','right'} + Checkbox alignment + ptype : {'arg' | 'kwarg' | 'plugin'} + Parameter type. + callback : function + Callback function called in response to CheckBox changes. This function + is typically set when the widget is added to a plugin. + """ + + def __init__(self, name, value=False, alignment='center', ptype='kwarg', callback=None): + super(CheckBox, self).__init__(name, ptype, callback) + + self._check_box = QtGui.QCheckBox() + self._check_box.setChecked(value) + self._check_box.setText(self.name) + + self.layout = QtGui.QHBoxLayout(self) + if alignment == 'center': + self.layout.setAlignment(QtCore.Qt.AlignCenter) + elif alignment == 'left': + self.layout.setAlignment(QtCore.Qt.AlignLeft) + elif alignment == 'right': + self.layout.setAlignment(QtCore.Qt.AlignRight) + else: + raise ValueError("Unexpected value %s for 'alignment'" % alignment) + + self.layout.addWidget(self._check_box) + + self._check_box.stateChanged.connect(self._value_changed) + + @property + def val(self): + #return self._check_box.checkState() + return self._check_box.isChecked() + + + @val.setter + def val(self, i): + #self._check_box.setCheckState(i) # setCheckState has 3 states: + # 0=unchecked, 1=partial, 2=checked + self._check_box.setChecked(i) # setChecked has only two states: + # 0 = unchecked, 2 = checked \ No newline at end of file From cb735dca55418200a71bd64bdc1249079474e2dd Mon Sep 17 00:00:00 2001 From: "Gregory R. Lee" Date: Tue, 9 Sep 2014 19:07:45 -0400 Subject: [PATCH 2/6] added tv_denoise.py viewer example using the CheckBox --- viewer_examples/plugins/tv_denoise.py | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) create mode 100644 viewer_examples/plugins/tv_denoise.py diff --git a/viewer_examples/plugins/tv_denoise.py b/viewer_examples/plugins/tv_denoise.py new file mode 100644 index 00000000..05b57205 --- /dev/null +++ b/viewer_examples/plugins/tv_denoise.py @@ -0,0 +1,25 @@ +from skimage import data +from skimage.restoration import denoise_tv_chambolle +from numpy import random, clip, uint8 + +from skimage.viewer import ImageViewer +from skimage.viewer.widgets import Slider, CheckBox, OKCancelButtons, SaveButtons +from skimage.viewer.plugins.base import Plugin + + +image = data.chelsea() +sigma = 30 + +image = image + random.normal(loc=0, scale=sigma, size=image.shape) +image = clip(image,0,255).astype(uint8) +viewer = ImageViewer(image) + +plugin = Plugin(image_filter=denoise_tv_chambolle) +plugin += Slider('weight', 0, 5, value=0.3, value_type='float') +plugin += Slider('n_iter_max', 1, 1000, value=100, value_type='int') +plugin += CheckBox('multichannel',value=True) +plugin += SaveButtons() +plugin += OKCancelButtons() + +viewer += plugin +viewer.show() From 026fc8eef1cfc5b9bf1a07a2b63691410eb8b662 Mon Sep 17 00:00:00 2001 From: "Gregory R. Lee" Date: Wed, 10 Sep 2014 14:09:11 -0400 Subject: [PATCH 3/6] fix image scaling in tv_denoise.py example --- viewer_examples/plugins/tv_denoise.py | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/viewer_examples/plugins/tv_denoise.py b/viewer_examples/plugins/tv_denoise.py index 05b57205..370efea3 100644 --- a/viewer_examples/plugins/tv_denoise.py +++ b/viewer_examples/plugins/tv_denoise.py @@ -1,22 +1,23 @@ from skimage import data from skimage.restoration import denoise_tv_chambolle -from numpy import random, clip, uint8 +from skimage.util import img_as_float +from numpy import random, clip from skimage.viewer import ImageViewer from skimage.viewer.widgets import Slider, CheckBox, OKCancelButtons, SaveButtons from skimage.viewer.plugins.base import Plugin -image = data.chelsea() -sigma = 30 +image = img_as_float(data.chelsea()) +sigma = 30/255. image = image + random.normal(loc=0, scale=sigma, size=image.shape) -image = clip(image,0,255).astype(uint8) +image = clip(image,0,1) viewer = ImageViewer(image) plugin = Plugin(image_filter=denoise_tv_chambolle) -plugin += Slider('weight', 0, 5, value=0.3, value_type='float') -plugin += Slider('n_iter_max', 1, 1000, value=100, value_type='int') +plugin += Slider('weight', 0.01, 5, value=0.3, value_type='float') +plugin += Slider('n_iter_max', 1, 100, value=20, value_type='int') plugin += CheckBox('multichannel',value=True) plugin += SaveButtons() plugin += OKCancelButtons() From 3f1b8a44685e118cadc5aa60ba01b137d81cb735 Mon Sep 17 00:00:00 2001 From: Gregory Lee Date: Fri, 12 Sep 2014 19:37:09 -0700 Subject: [PATCH 4/6] code formatting fixes --- skimage/viewer/widgets/core.py | 17 ++++++++--------- viewer_examples/plugins/tv_denoise.py | 7 ++++--- 2 files changed, 12 insertions(+), 12 deletions(-) diff --git a/skimage/viewer/widgets/core.py b/skimage/viewer/widgets/core.py index 85302aaa..9a99d7e8 100644 --- a/skimage/viewer/widgets/core.py +++ b/skimage/viewer/widgets/core.py @@ -254,6 +254,7 @@ class ComboBox(BaseWidget): def index(self, i): self._combo_box.setCurrentIndex(i) + class CheckBox(BaseWidget): """CheckBox widget @@ -265,17 +266,18 @@ class CheckBox(BaseWidget): replaced with underscores). In addition, this name is displayed as the name of the CheckBox. value: {False, True} - Initial state of the CheckBox. + Initial state of the CheckBox. alignment: {'center','left','right'} - Checkbox alignment + Checkbox alignment ptype : {'arg' | 'kwarg' | 'plugin'} - Parameter type. + Parameter type callback : function Callback function called in response to CheckBox changes. This function is typically set when the widget is added to a plugin. """ - def __init__(self, name, value=False, alignment='center', ptype='kwarg', callback=None): + def __init__(self, name, value=False, alignment='center', ptype='kwarg', + callback=None): super(CheckBox, self).__init__(name, ptype, callback) self._check_box = QtGui.QCheckBox() @@ -298,13 +300,10 @@ class CheckBox(BaseWidget): @property def val(self): - #return self._check_box.checkState() return self._check_box.isChecked() - @val.setter def val(self, i): - #self._check_box.setCheckState(i) # setCheckState has 3 states: - # 0=unchecked, 1=partial, 2=checked self._check_box.setChecked(i) # setChecked has only two states: - # 0 = unchecked, 2 = checked \ No newline at end of file + # 0 = unchecked, 2 = checked + \ No newline at end of file diff --git a/viewer_examples/plugins/tv_denoise.py b/viewer_examples/plugins/tv_denoise.py index 370efea3..e4d06fb2 100644 --- a/viewer_examples/plugins/tv_denoise.py +++ b/viewer_examples/plugins/tv_denoise.py @@ -4,7 +4,8 @@ from skimage.util import img_as_float from numpy import random, clip from skimage.viewer import ImageViewer -from skimage.viewer.widgets import Slider, CheckBox, OKCancelButtons, SaveButtons +from skimage.viewer.widgets import (Slider, CheckBox, OKCancelButtons, + SaveButtons) from skimage.viewer.plugins.base import Plugin @@ -12,13 +13,13 @@ image = img_as_float(data.chelsea()) sigma = 30/255. image = image + random.normal(loc=0, scale=sigma, size=image.shape) -image = clip(image,0,1) +image = clip(image, 0, 1) viewer = ImageViewer(image) plugin = Plugin(image_filter=denoise_tv_chambolle) plugin += Slider('weight', 0.01, 5, value=0.3, value_type='float') plugin += Slider('n_iter_max', 1, 100, value=20, value_type='int') -plugin += CheckBox('multichannel',value=True) +plugin += CheckBox('multichannel', value=True) plugin += SaveButtons() plugin += OKCancelButtons() From bdd9fb08322a9b96aaed37c996e8973ae734aebc Mon Sep 17 00:00:00 2001 From: "Gregory R. Lee" Date: Tue, 16 Sep 2014 12:49:40 -0400 Subject: [PATCH 5/6] PEP8 formatting --- skimage/viewer/tests/test_widgets.py | 2 ++ skimage/viewer/widgets/core.py | 5 +++-- viewer_examples/plugins/tv_denoise.py | 4 ++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/skimage/viewer/tests/test_widgets.py b/skimage/viewer/tests/test_widgets.py index d83f54ac..a9f84fbd 100644 --- a/skimage/viewer/tests/test_widgets.py +++ b/skimage/viewer/tests/test_widgets.py @@ -16,6 +16,7 @@ def get_image_viewer(): viewer += Plugin() return viewer + @skipif(not viewer_available) def test_check_box(): viewer = get_image_viewer() @@ -43,6 +44,7 @@ def test_combo_box(): assert_equal(str(cb.val), 'c'), assert_equal(cb.index, 2) + @skipif(not viewer_available) def test_text_widget(): viewer = get_image_viewer() diff --git a/skimage/viewer/widgets/core.py b/skimage/viewer/widgets/core.py index 9a99d7e8..0eebbe8c 100644 --- a/skimage/viewer/widgets/core.py +++ b/skimage/viewer/widgets/core.py @@ -304,6 +304,7 @@ class CheckBox(BaseWidget): @val.setter def val(self, i): - self._check_box.setChecked(i) # setChecked has only two states: - # 0 = unchecked, 2 = checked + # setChecked has only two states: 0 = unchecked, 2 = checked + self._check_box.setChecked(i) + \ No newline at end of file diff --git a/viewer_examples/plugins/tv_denoise.py b/viewer_examples/plugins/tv_denoise.py index e4d06fb2..5ad527ec 100644 --- a/viewer_examples/plugins/tv_denoise.py +++ b/viewer_examples/plugins/tv_denoise.py @@ -4,8 +4,8 @@ from skimage.util import img_as_float from numpy import random, clip from skimage.viewer import ImageViewer -from skimage.viewer.widgets import (Slider, CheckBox, OKCancelButtons, - SaveButtons) +from skimage.viewer.widgets import (Slider, CheckBox, OKCancelButtons, + SaveButtons) from skimage.viewer.plugins.base import Plugin From eb7cdb5a16efd1e2c0b9f93547a7c08d8beebd70 Mon Sep 17 00:00:00 2001 From: "Gregory R. Lee" Date: Wed, 17 Sep 2014 12:29:48 -0400 Subject: [PATCH 6/6] remove outdated comment line --- skimage/viewer/widgets/core.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/skimage/viewer/widgets/core.py b/skimage/viewer/widgets/core.py index 0eebbe8c..91265633 100644 --- a/skimage/viewer/widgets/core.py +++ b/skimage/viewer/widgets/core.py @@ -304,7 +304,4 @@ class CheckBox(BaseWidget): @val.setter def val(self, i): - # setChecked has only two states: 0 = unchecked, 2 = checked - self._check_box.setChecked(i) - - \ No newline at end of file + self._check_box.setChecked(i)