summaryrefslogtreecommitdiff
path: root/src/silx/gui/dialog
diff options
context:
space:
mode:
Diffstat (limited to 'src/silx/gui/dialog')
-rw-r--r--src/silx/gui/dialog/AbstractDataFileDialog.py165
-rw-r--r--src/silx/gui/dialog/ColormapDialog.py358
-rw-r--r--src/silx/gui/dialog/DataFileDialog.py4
-rw-r--r--src/silx/gui/dialog/DatasetDialog.py27
-rw-r--r--src/silx/gui/dialog/FileTypeComboBox.py24
-rw-r--r--src/silx/gui/dialog/GroupDialog.py33
-rw-r--r--src/silx/gui/dialog/ImageFileDialog.py10
-rw-r--r--src/silx/gui/dialog/SafeFileIconProvider.py1
-rw-r--r--src/silx/gui/dialog/SafeFileSystemModel.py25
-rw-r--r--src/silx/gui/dialog/test/test_colormapdialog.py704
-rw-r--r--src/silx/gui/dialog/test/test_datafiledialog.py203
-rw-r--r--src/silx/gui/dialog/test/test_imagefiledialog.py172
-rw-r--r--src/silx/gui/dialog/utils.py2
13 files changed, 977 insertions, 751 deletions
diff --git a/src/silx/gui/dialog/AbstractDataFileDialog.py b/src/silx/gui/dialog/AbstractDataFileDialog.py
index f656bb2..00db275 100644
--- a/src/silx/gui/dialog/AbstractDataFileDialog.py
+++ b/src/silx/gui/dialog/AbstractDataFileDialog.py
@@ -56,7 +56,6 @@ some version of PyQt."""
class _IconProvider(object):
-
FileDialogToParentDir = qt.QStyle.SP_CustomBase + 1
FileDialogToParentFile = qt.QStyle.SP_CustomBase + 2
@@ -92,7 +91,9 @@ class _IconProvider(object):
pixmap.fill(qt.Qt.transparent)
painter = qt.QPainter(pixmap)
painter.drawPixmap(0, 0, backgroundIcon.pixmap(baseSize, mode=mode))
- painter.drawPixmap(0, size.height() // 3, baseIcon.pixmap(baseSize, mode=mode))
+ painter.drawPixmap(
+ 0, size.height() // 3, baseIcon.pixmap(baseSize, mode=mode)
+ )
painter.end()
icon.addPixmap(pixmap, mode=mode)
@@ -100,12 +101,16 @@ class _IconProvider(object):
def getFileDialogToParentDir(self):
if self.__iconFileDialogToParentDir is None:
- self.__iconFileDialogToParentDir = self._createIconToParent(qt.QStyle.SP_DirIcon)
+ self.__iconFileDialogToParentDir = self._createIconToParent(
+ qt.QStyle.SP_DirIcon
+ )
return self.__iconFileDialogToParentDir
def getFileDialogToParentFile(self):
if self.__iconFileDialogToParentFile is None:
- self.__iconFileDialogToParentFile = self._createIconToParent(qt.QStyle.SP_FileIcon)
+ self.__iconFileDialogToParentFile = self._createIconToParent(
+ qt.QStyle.SP_FileIcon
+ )
return self.__iconFileDialogToParentFile
def icon(self, kind):
@@ -147,13 +152,17 @@ class _SideBar(qt.QListView):
:rtype: List[str]
"""
urls = []
- version = tuple(map(int, qt.qVersion().split('.')[:3]))
+ version = tuple(map(int, qt.qVersion().split(".")[:3]))
feed_sidebar = True
if not DEFAULT_SIDEBAR_URL:
_logger.debug("Skip default sidebar URLs (from setted variable)")
feed_sidebar = False
- elif version < (5, 11, 2) and qt.BINDING == "PyQt5" and sys.platform in ["linux", "linux2"]:
+ elif (
+ version < (5, 11, 2)
+ and qt.BINDING == "PyQt5"
+ and sys.platform in ["linux", "linux2"]
+ ):
# Avoid segfault on PyQt5 + gtk
_logger.debug("Skip default sidebar URLs (avoid PyQt5 segfault)")
feed_sidebar = False
@@ -186,7 +195,9 @@ class _SideBar(qt.QListView):
selectionModel = self.selectionModel()
if selected is not None:
- selectionModel.setCurrentIndex(selected, qt.QItemSelectionModel.ClearAndSelect)
+ selectionModel.setCurrentIndex(
+ selected, qt.QItemSelectionModel.ClearAndSelect
+ )
else:
selectionModel.clear()
@@ -232,11 +243,12 @@ class _SideBar(qt.QListView):
def sizeHint(self):
index = self.model().index(0, 0)
- return self.sizeHintForIndex(index) + qt.QSize(2 * self.frameWidth(), 2 * self.frameWidth())
+ return self.sizeHintForIndex(index) + qt.QSize(
+ 2 * self.frameWidth(), 2 * self.frameWidth()
+ )
class _Browser(qt.QStackedWidget):
-
activated = qt.Signal(qt.QModelIndex)
selected = qt.Signal(qt.QModelIndex)
rootIndexChanged = qt.Signal(qt.QModelIndex)
@@ -302,7 +314,7 @@ class _Browser(qt.QStackedWidget):
elif self.currentIndex() == 1:
return qt.QFileDialog.Detail
else:
- assert(False)
+ assert False
def setViewMode(self, mode):
"""Set the current view mode.
@@ -314,7 +326,7 @@ class _Browser(qt.QStackedWidget):
elif mode == qt.QFileDialog.List:
self.showList()
else:
- assert(False)
+ assert False
def showList(self):
self.__listView.show()
@@ -342,11 +354,10 @@ class _Browser(qt.QStackedWidget):
self.__detailView.setModel(None)
def setRootIndex(self, index, model=None):
- """Sets the root item to the item at the given index.
- """
+ """Sets the root item to the item at the given index."""
rootIndex = self.__listView.rootIndex()
newModel = model or index.model()
- assert(newModel is not None)
+ assert newModel is not None
if rootIndex is None or rootIndex.model() is not newModel:
# update the model
@@ -415,12 +426,16 @@ class _Browser(qt.QStackedWidget):
nameId = stream.readQString()
if nameId != "Browser":
- _logger.warning("Stored state contains an invalid name id. Browser restoration cancelled.")
+ _logger.warning(
+ "Stored state contains an invalid name id. Browser restoration cancelled."
+ )
return False
version = stream.readInt32()
if version != self.__serialVersion:
- _logger.warning("Stored state contains an invalid version. Browser restoration cancelled.")
+ _logger.warning(
+ "Stored state contains an invalid version. Browser restoration cancelled."
+ )
return False
headerData = stream.readQVariant()
@@ -438,12 +453,12 @@ class _Browser(qt.QStackedWidget):
data = qt.QByteArray()
stream = qt.QDataStream(data, qt.QIODevice.WriteOnly)
- nameId = u"Browser"
+ nameId = "Browser"
stream.writeQString(nameId)
stream.writeInt32(self.__serialVersion)
stream.writeQVariant(self.__detailView.header().saveState())
viewMode = self.viewMode()
- if qt.BINDING == 'PyQt6': # No auto conversion to int
+ if qt.BINDING in ("PyQt6", "PySide6"): # No auto conversion to int
viewMode = viewMode.value
stream.writeInt32(viewMode)
@@ -451,7 +466,6 @@ class _Browser(qt.QStackedWidget):
class _FabioData(object):
-
def __init__(self, fabioFile):
self.__fabioFile = fabioFile
@@ -492,7 +506,6 @@ class _PathEdit(qt.QLineEdit):
class _CatchResizeEvent(qt.QObject):
-
resized = qt.Signal(qt.QResizeEvent)
def __init__(self, parent, target):
@@ -565,6 +578,7 @@ class AbstractDataFileDialog(qt.QDialog):
_logger.debug("Uses default QFileSystemModel with a SafeFileIconProvider")
self.__fileModel = qt.QFileSystemModel(self)
from .SafeFileIconProvider import SafeFileIconProvider
+
iconProvider = SafeFileIconProvider()
self.__fileModel.setIconProvider(iconProvider)
@@ -677,8 +691,12 @@ class AbstractDataFileDialog(qt.QDialog):
self.__fileTypeCombo = FileTypeComboBox(self)
self.__fileTypeCombo.setObjectName("fileTypeCombo")
self.__fileTypeCombo.setDuplicatesEnabled(False)
- self.__fileTypeCombo.setSizeAdjustPolicy(qt.QComboBox.AdjustToMinimumContentsLengthWithIcon)
- self.__fileTypeCombo.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Fixed)
+ self.__fileTypeCombo.setSizeAdjustPolicy(
+ qt.QComboBox.AdjustToMinimumContentsLengthWithIcon
+ )
+ self.__fileTypeCombo.setSizePolicy(
+ qt.QSizePolicy.Expanding, qt.QSizePolicy.Fixed
+ )
self.__fileTypeCombo.activated[int].connect(self.__filterSelected)
self.__fileTypeCombo.setFabioUrlSupproted(self._isFabioFilesSupported())
@@ -708,7 +726,9 @@ class AbstractDataFileDialog(qt.QDialog):
if self.__selectorWidget is not None:
self.__selectorWidget.selectionChanged.connect(self.__selectorWidgetChanged)
- self.__previewToolBar = self._createPreviewToolbar(self, self.__previewWidget, self.__selectorWidget)
+ self.__previewToolBar = self._createPreviewToolbar(
+ self, self.__previewWidget, self.__selectorWidget
+ )
self.__dataIcon = qt.QLabel(self)
self.__dataIcon.setSizePolicy(qt.QSizePolicy.Fixed, qt.QSizePolicy.Fixed)
@@ -767,7 +787,9 @@ class AbstractDataFileDialog(qt.QDialog):
parentFileDirectory = qt.QAction(toolbar)
parentFileDirectory.setText("Parent directory of the file")
parentFileDirectory.setObjectName("toDirectoryAction")
- parentFileDirectory.setIcon(iconProvider.icon(iconProvider.FileDialogToParentDir))
+ parentFileDirectory.setIcon(
+ iconProvider.icon(iconProvider.FileDialogToParentDir)
+ )
parentFileDirectory.triggered.connect(self.__navigateToParentDir)
self.__parentFileDirectoryAction = parentFileDirectory
@@ -818,11 +840,15 @@ class AbstractDataFileDialog(qt.QDialog):
dummyCombo.setFixedHeight(self.__fileTypeCombo.height())
self.__resizeCombo = _CatchResizeEvent(self, self.__fileTypeCombo)
- self.__resizeCombo.resized.connect(lambda e: dummyCombo.setFixedHeight(e.size().height()))
+ self.__resizeCombo.resized.connect(
+ lambda e: dummyCombo.setFixedHeight(e.size().height())
+ )
dummyToolBar.setFixedHeight(self.__browseToolBar.height())
self.__resizeToolbar = _CatchResizeEvent(self, self.__browseToolBar)
- self.__resizeToolbar.resized.connect(lambda e: dummyToolBar.setFixedHeight(e.size().height()))
+ self.__resizeToolbar.resized.connect(
+ lambda e: dummyToolBar.setFixedHeight(e.size().height())
+ )
datasetSelection = qt.QWidget(self)
layoutLeft = qt.QVBoxLayout()
@@ -831,7 +857,9 @@ class AbstractDataFileDialog(qt.QDialog):
layoutLeft.addWidget(self.__browser)
layoutLeft.addWidget(self.__fileTypeCombo)
datasetSelection.setLayout(layoutLeft)
- datasetSelection.setSizePolicy(qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Expanding)
+ datasetSelection.setSizePolicy(
+ qt.QSizePolicy.MinimumExpanding, qt.QSizePolicy.Expanding
+ )
infoLayout = qt.QHBoxLayout()
infoLayout.setContentsMargins(0, 0, 0, 0)
@@ -858,7 +886,9 @@ class AbstractDataFileDialog(qt.QDialog):
dummyToolbar2.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Fixed)
dummyToolbar2.setFixedHeight(self.__browseToolBar.height())
self.__resizeToolbar = _CatchResizeEvent(self, self.__browseToolBar)
- self.__resizeToolbar.resized.connect(lambda e: dummyToolbar2.setFixedHeight(e.size().height()))
+ self.__resizeToolbar.resized.connect(
+ lambda e: dummyToolbar2.setFixedHeight(e.size().height())
+ )
dataLayout.addWidget(dummyToolbar2)
dataLayout.addWidget(dataFrame)
@@ -870,7 +900,9 @@ class AbstractDataFileDialog(qt.QDialog):
dummyCombo2.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Fixed)
dummyCombo2.setFixedHeight(self.__fileTypeCombo.height())
self.__resizeToolbar = _CatchResizeEvent(self, self.__fileTypeCombo)
- self.__resizeToolbar.resized.connect(lambda e: dummyCombo2.setFixedHeight(e.size().height()))
+ self.__resizeToolbar.resized.connect(
+ lambda e: dummyCombo2.setFixedHeight(e.size().height())
+ )
dataLayout.addWidget(dummyCombo2)
dataSelection.setLayout(dataLayout)
@@ -904,7 +936,10 @@ class AbstractDataFileDialog(qt.QDialog):
def __navigateForward(self):
"""Navigate through the history one step forward."""
- if len(self.__currentHistory) > 0 and self.__currentHistoryLocation < len(self.__currentHistory) - 1:
+ if (
+ len(self.__currentHistory) > 0
+ and self.__currentHistoryLocation < len(self.__currentHistory) - 1
+ ):
self.__currentHistoryLocation += 1
url = self.__currentHistory[self.__currentHistoryLocation]
self.selectUrl(url)
@@ -971,7 +1006,7 @@ class AbstractDataFileDialog(qt.QDialog):
self.__listViewAction.setChecked(True)
self.__detailViewAction.setChecked(False)
else:
- assert(False)
+ assert False
def __showAsListView(self):
self.setViewMode(qt.QFileDialog.List)
@@ -1005,7 +1040,7 @@ class AbstractDataFileDialog(qt.QDialog):
if silx.io.is_group(obj):
self.__browser.setRootIndex(index)
else:
- assert(False)
+ assert False
def __browsedItemSelected(self, index):
self.__dataSelected(index)
@@ -1020,7 +1055,7 @@ class AbstractDataFileDialog(qt.QDialog):
:param str path: Path to load
"""
- assert(path is not None)
+ assert path is not None
if path != "" and not os.path.exists(path):
return
if self.hasPendingEvents():
@@ -1102,8 +1137,7 @@ class AbstractDataFileDialog(qt.QDialog):
return True
def __isSilxHavePriority(self, filename):
- """Silx have priority when there is a specific decoder
- """
+ """Silx have priority when there is a specific decoder"""
_, ext = os.path.splitext(filename)
ext = "*%s" % ext
formats = silx.io.supported_extensions(flat_formats=False)
@@ -1166,14 +1200,17 @@ class AbstractDataFileDialog(qt.QDialog):
if os.path.isfile(path):
codec = self.__fileTypeCombo.currentCodec()
is_fabio_decoder = codec.is_fabio_codec()
- is_fabio_have_priority = not codec.is_silx_codec() and not self.__isSilxHavePriority(path)
+ is_fabio_have_priority = (
+ not codec.is_silx_codec()
+ and not self.__isSilxHavePriority(path)
+ )
if is_fabio_decoder or is_fabio_have_priority:
# Then it's flat frame container
self.__openFabioFile(path)
if self.__fabio is not None:
selectedData = _FabioData(self.__fabio)
else:
- assert(False)
+ assert False
self.__setData(selectedData)
@@ -1193,7 +1230,9 @@ class AbstractDataFileDialog(qt.QDialog):
self.__setSelectedData(data)
self.__selectorWidget.hide()
else:
- self.__selectorWidget.setVisible(self.__selectorWidget.hasVisibleSelectors())
+ self.__selectorWidget.setVisible(
+ self.__selectorWidget.hasVisibleSelectors()
+ )
# Needed to fake the fact we have to reset the zoom in preview
self.__selectedData = None
self.__selectorWidget.selectionChanged.emit()
@@ -1266,7 +1305,10 @@ class AbstractDataFileDialog(qt.QDialog):
def __updateDataInfo(self):
if self.__errorWhileLoadingFile is not None:
filename, message = self.__errorWhileLoadingFile
- message = "<b>Error while loading file '%s'</b><hr/>%s" % (filename, message)
+ message = "<b>Error while loading file '%s'</b><hr/>%s" % (
+ filename,
+ message,
+ )
size = self.__dataInfo.height()
icon = self.style().standardIcon(qt.QStyle.SP_MessageBoxCritical)
pixmap = icon.pixmap(size, size)
@@ -1317,7 +1359,11 @@ class AbstractDataFileDialog(qt.QDialog):
filename = ""
dataPath = None
- if useSelectorWidget and self.__selectorWidget is not None and self.__selectorWidget.isUsed():
+ if (
+ useSelectorWidget
+ and self.__selectorWidget is not None
+ and self.__selectorWidget.isUsed()
+ ):
slicing = self.__selectorWidget.slicing()
if slicing == tuple():
slicing = None
@@ -1340,7 +1386,9 @@ class AbstractDataFileDialog(qt.QDialog):
else:
scheme = None
- url = silx.io.url.DataUrl(file_path=filename, data_path=dataPath, data_slice=slicing, scheme=scheme)
+ url = silx.io.url.DataUrl(
+ file_path=filename, data_path=dataPath, data_slice=slicing, scheme=scheme
+ )
return url
def __updatePath(self):
@@ -1362,7 +1410,9 @@ class AbstractDataFileDialog(qt.QDialog):
if currentUrl is None or currentUrl != url.path():
# clean up the forward history
- self.__currentHistory = self.__currentHistory[0:self.__currentHistoryLocation + 1]
+ self.__currentHistory = self.__currentHistory[
+ 0 : self.__currentHistoryLocation + 1
+ ]
self.__currentHistory.append(url.path())
self.__currentHistoryLocation += 1
@@ -1400,15 +1450,16 @@ class AbstractDataFileDialog(qt.QDialog):
selectionModel.selectionChanged.connect(self.__shortcutSelected)
def __updateActionHistory(self):
- self.__forwardAction.setEnabled(len(self.__currentHistory) - 1 > self.__currentHistoryLocation)
+ self.__forwardAction.setEnabled(
+ len(self.__currentHistory) - 1 > self.__currentHistoryLocation
+ )
self.__backwardAction.setEnabled(self.__currentHistoryLocation > 0)
def __textChanged(self, text):
self.__pathChanged()
def _isFabioFilesSupported(self):
- """Returns true fabio files can be loaded.
- """
+ """Returns true fabio files can be loaded."""
return True
def _isLoadableUrl(self, url):
@@ -1479,7 +1530,7 @@ class AbstractDataFileDialog(qt.QDialog):
# data = _FabioData(self.__fabio)
# self.__setData(data)
else:
- assert(False)
+ assert False
else:
self.__browser.setRootIndex(index, model=self.__fileModel)
self.__clearData()
@@ -1615,7 +1666,7 @@ class AbstractDataFileDialog(qt.QDialog):
"""
if len(self.__currentHistory) <= 1:
return []
- history = self.__currentHistory[0:self.__currentHistoryLocation]
+ history = self.__currentHistory[0 : self.__currentHistoryLocation]
return list(history)
def setHistory(self, history):
@@ -1670,12 +1721,18 @@ class AbstractDataFileDialog(qt.QDialog):
qualifiedName = stream.readQString()
if qualifiedName != self.qualifiedName():
- _logger.warning("Stored state contains an invalid qualified name. %s restoration cancelled.", self.__class__.__name__)
+ _logger.warning(
+ "Stored state contains an invalid qualified name. %s restoration cancelled.",
+ self.__class__.__name__,
+ )
return False
version = stream.readInt32()
if version != self.__serialVersion:
- _logger.warning("Stored state contains an invalid version. %s restoration cancelled.", self.__class__.__name__)
+ _logger.warning(
+ "Stored state contains an invalid version. %s restoration cancelled.",
+ self.__class__.__name__,
+ )
return False
result = True
@@ -1713,17 +1770,17 @@ class AbstractDataFileDialog(qt.QDialog):
stream = qt.QDataStream(data, qt.QIODevice.WriteOnly)
s = self.qualifiedName()
- stream.writeQString(u"%s" % s)
+ stream.writeQString("%s" % s)
stream.writeInt32(self.__serialVersion)
stream.writeQVariant(self.__splitter.saveState())
- strings = [u"%s" % s.toString() for s in self.sidebarUrls()]
+ strings = ["%s" % s.toString() for s in self.sidebarUrls()]
stream.writeQStringList(strings)
- strings = [u"%s" % s for s in self.history()]
+ strings = ["%s" % s for s in self.history()]
stream.writeQStringList(strings)
- stream.writeQString(u"%s" % self.directory())
+ stream.writeQString("%s" % self.directory())
stream.writeQVariant(self.__browser.saveState())
viewMode = self.viewMode()
- if qt.BINDING == 'PyQt6': # No auto conversion to int
+ if qt.BINDING in ("PyQt6", "PySide6"): # No auto conversion to int
viewMode = viewMode.value
stream.writeInt32(viewMode)
colormap = self.colormap()
diff --git a/src/silx/gui/dialog/ColormapDialog.py b/src/silx/gui/dialog/ColormapDialog.py
index f3f38b5..75ab39e 100644
--- a/src/silx/gui/dialog/ColormapDialog.py
+++ b/src/silx/gui/dialog/ColormapDialog.py
@@ -1,6 +1,6 @@
# /*##########################################################################
#
-# Copyright (c) 2004-2022 European Synchrotron Radiation Facility
+# Copyright (c) 2004-2023 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -58,6 +58,8 @@ The updates of the colormap description are also available through the signal:
:attr:`ColormapDialog.sigColormapChanged`.
""" # noqa
+from __future__ import annotations
+
__authors__ = ["V.A. Sole", "T. Vincent", "H. Payno"]
__license__ = "MIT"
__date__ = "08/12/2020"
@@ -82,9 +84,9 @@ from silx.gui.qt import inspect as qtinspect
from silx.gui.widgets.ColormapNameComboBox import ColormapNameComboBox
from silx.gui.widgets.FormGridLayout import FormGridLayout
from silx.math.histogram import Histogramnd
-from silx.utils import deprecation
from silx.gui.plot.items.roi import RectangleROI
from silx.gui.plot.tools.roi import RegionOfInterestManager
+from silx.utils.enum import Enum as _Enum
_logger = logging.getLogger(__name__)
@@ -128,8 +130,8 @@ class _BoundaryWidget(qt.QWidget):
self.layout().setContentsMargins(0, 0, 0, 0)
self._numVal = FloatEdit(parent=self, value=value)
- self._iconAuto = icons.getQIcon('scale-auto')
- self._iconFixed = icons.getQIcon('scale-fixed')
+ self._iconAuto = icons.getQIcon("scale-auto")
+ self._iconFixed = icons.getQIcon("scale-fixed")
self._autoToggleAction = qt.QAction(self)
self._autoToggleAction.setText("Auto scale")
@@ -142,7 +144,7 @@ class _BoundaryWidget(qt.QWidget):
self._numVal.addAction(self._autoToggleAction, qt.QLineEdit.LeadingPosition)
self.layout().addWidget(self._numVal)
- self._autoCB = qt.QCheckBox('auto', parent=self)
+ self._autoCB = qt.QCheckBox("auto", parent=self)
self.layout().addWidget(self._autoCB)
self._autoCB.setChecked(False)
self._autoCB.setVisible(False)
@@ -220,7 +222,7 @@ class _BoundaryWidget(qt.QWidget):
color = palette.color(qt.QPalette.Disabled, qt.QPalette.Base)
icon = self._iconAuto
else:
- color = palette.color(qt.QPalette.Normal, qt.QPalette.Base)
+ color = palette.color(qt.QPalette.Active, qt.QPalette.Base)
icon = self._iconFixed
palette.setColor(qt.QPalette.Base, color)
self._numVal.setPalette(palette)
@@ -228,7 +230,6 @@ class _BoundaryWidget(qt.QWidget):
class _AutoscaleModeComboBox(qt.QComboBox):
-
DATA = {
Colormap.MINMAX: ("Min/max", "Use the data min/max"),
Colormap.STDDEV3: ("Mean±3std", "Use the data mean ± 3 × standard deviation"),
@@ -275,7 +276,6 @@ class _AutoscaleModeComboBox(qt.QComboBox):
class _AutoScaleButton(qt.QPushButton):
-
autoRangeChanged = qt.Signal(object)
def __init__(self, parent=None):
@@ -300,11 +300,13 @@ class _AutoScaleButton(qt.QPushButton):
with utils.blockSignals(self):
self.setChecked(autoRange[0] if autoRange[0] == autoRange[1] else False)
+
@enum.unique
-class _DataInPlotMode(enum.Enum):
+class DisplayMode(_Enum):
"""Enum for each mode of display of the data in the plot."""
- RANGE = 'range'
- HISTOGRAM = 'histogram'
+
+ RANGE = "range"
+ HISTOGRAM = "histogram"
class _ColormapHistogram(qt.QWidget):
@@ -333,7 +335,7 @@ class _ColormapHistogram(qt.QWidget):
def __init__(self, parent):
qt.QWidget.__init__(self, parent=parent)
- self._dataInPlotMode = _DataInPlotMode.RANGE
+ self._displayMode = DisplayMode.RANGE
self._finiteRange = None, None
self._initPlot()
@@ -350,7 +352,7 @@ class _ColormapHistogram(qt.QWidget):
def paintEvent(self, event):
if self._invalidated:
- self._updateDataInPlot()
+ self._updateDisplayMode()
self._invalidated = False
self._updateMarkerPosition()
return super(_ColormapHistogram, self).paintEvent(event)
@@ -419,7 +421,9 @@ class _ColormapHistogram(qt.QWidget):
dataRange = self._getNormalizedDataRange()
if dataRange[0] is None or dataRange[1] is None:
return None, None
- counts, edges = self.parent().computeHistogram(data, scale=norm, dataRange=dataRange)
+ counts, edges = self.parent().computeHistogram(
+ data, scale=norm, dataRange=dataRange
+ )
return counts, edges
def _getNormalizedDataRange(self):
@@ -511,22 +515,22 @@ class _ColormapHistogram(qt.QWidget):
self._plot.setDataMargins(0.125, 0.125, 0.01, 0.01)
self._plot.getXAxis().setLabel("Data Values")
self._plot.getYAxis().setLabel("")
- self._plot.setInteractiveMode('select', zoomOnWheel=False)
+ self._plot.setInteractiveMode("select", zoomOnWheel=False)
self._plot.setActiveCurveHandling(False)
self._plot.setMinimumSize(qt.QSize(250, 200))
self._plot.sigPlotSignal.connect(self._plotEventReceived)
palette = self.palette()
- color = palette.color(qt.QPalette.Normal, qt.QPalette.Window)
+ color = palette.color(qt.QPalette.Active, qt.QPalette.Window)
self._plot.setBackgroundColor(color)
self._plot.setDataBackgroundColor("white")
lut = numpy.arange(256)
lut.shape = 1, -1
- self._plot.addImage(lut, legend='lut')
+ self._plot.addImage(lut, legend="lut")
self._lutItem = self._plot._getItem("image", "lut")
self._lutItem.setVisible(False)
- self._plot.addScatter(x=[], y=[], value=[], legend='lut2')
+ self._plot.addScatter(x=[], y=[], value=[], legend="lut2")
self._lutItem2 = self._plot._getItem("scatter", "lut2")
self._lutItem2.setVisible(False)
self.__lutY = numpy.array([-0.05] * 256)
@@ -546,24 +550,32 @@ class _ColormapHistogram(qt.QWidget):
group = qt.QActionGroup(self._plotToolbar)
group.setExclusive(True)
-
+ # data range mode
action = qt.QAction("Data range", self)
- action.setToolTip("Display the data range within the colormap range. A fast data processing have to be done.")
- action.setIcon(icons.getQIcon('colormap-range'))
+ action.setToolTip(
+ "Display the data range within the colormap range. A fast data processing have to be done."
+ )
+ action.setIcon(icons.getQIcon("colormap-range"))
action.setCheckable(True)
- action.setData(_DataInPlotMode.RANGE)
- action.setChecked(action.data() == self._dataInPlotMode)
+ action.setData(DisplayMode.RANGE)
+ action.setChecked(action.data() == self._displayMode)
self._plotToolbar.addAction(action)
group.addAction(action)
+ self._dataRangeAction = action
+ # histogram mode
action = qt.QAction("Histogram", self)
- action.setToolTip("Display the data histogram within the colormap range. A slow data processing have to be done. ")
- action.setIcon(icons.getQIcon('colormap-histogram'))
+ action.setToolTip(
+ "Display the data histogram within the colormap range. A slow data processing have to be done. "
+ )
+ action.setIcon(icons.getQIcon("colormap-histogram"))
action.setCheckable(True)
- action.setData(_DataInPlotMode.HISTOGRAM)
- action.setChecked(action.data() == self._dataInPlotMode)
+ action.setData(DisplayMode.HISTOGRAM)
+ action.setChecked(action.data() == self._displayMode)
self._plotToolbar.addAction(action)
group.addAction(action)
- group.triggered.connect(self._displayDataInPlotModeChanged)
+ self._dataHistogramAction = action
+ group.setExclusive(True)
+ group.triggered.connect(self._displayModeChanged)
plotBoxLayout = qt.QHBoxLayout()
plotBoxLayout.setContentsMargins(0, 0, 0, 0)
@@ -575,28 +587,28 @@ class _ColormapHistogram(qt.QWidget):
def _plotEventReceived(self, event):
"""Handle events from the plot"""
- kind = event['event']
+ kind = event["event"]
- if kind == 'markerMoving':
- value = event['xdata']
- if event['label'] == 'Min':
+ if kind == "markerMoving":
+ value = event["xdata"]
+ if event["label"] == "Min":
self._dragging = True, False, False
self._finiteRange = value, self._finiteRange[1]
self._last = value, None, None
self._updateGammaPosition()
self.sigRangeMoving.emit(*self._last)
- elif event['label'] == 'Max':
+ elif event["label"] == "Max":
self._dragging = False, True, False
self._finiteRange = self._finiteRange[0], value
self._last = None, value, None
self._updateGammaPosition()
self.sigRangeMoving.emit(*self._last)
- elif event['label'] == 'Gamma':
+ elif event["label"] == "Gamma":
self._dragging = False, False, True
self._last = None, None, value
self.sigRangeMoving.emit(*self._last)
self._updateLutItem(self._finiteRange)
- elif kind == 'markerMoved':
+ elif kind == "markerMoved":
self.sigRangeMoved.emit(*self._last)
self._plot.resetZoom()
self._dragging = False, False, False
@@ -616,20 +628,22 @@ class _ColormapHistogram(qt.QWidget):
if posMin is not None and not self._dragging[0]:
self._plot.addXMarker(
posMin,
- legend='Min',
- text='Min',
+ legend="Min",
+ text="Min",
draggable=isDraggable,
color="blue",
- constraint=self._plotMinMarkerConstraint)
+ constraint=self._plotMinMarkerConstraint,
+ )
self._updateGammaPosition()
if posMax is not None and not self._dragging[1]:
self._plot.addXMarker(
posMax,
- legend='Max',
- text='\n\nMax',
+ legend="Max",
+ text="\n\nMax",
draggable=isDraggable,
color="blue",
- constraint=self._plotMaxMarkerConstraint)
+ constraint=self._plotMaxMarkerConstraint,
+ )
self._updateLutItem((posMin, posMax))
self._plot.resetZoom()
@@ -650,14 +664,14 @@ class _ColormapHistogram(qt.QWidget):
if not self._dragging[2]:
posRange = posMax - posMin
if posRange > 0:
- gammaPos = posMin + posRange * 0.5**(1/gamma)
+ gammaPos = posMin + posRange * 0.5 ** (1 / gamma)
else:
gammaPos = posMin
marker = self._plot._getMarker(
self._plot.addXMarker(
gammaPos,
- legend='Gamma',
- text='\nGamma',
+ legend="Gamma",
+ text="\nGamma",
draggable=True,
color="blue",
constraint=self._plotGammaMarkerConstraint,
@@ -666,7 +680,7 @@ class _ColormapHistogram(qt.QWidget):
marker.setZValue(2)
else:
try:
- self._plot.removeMarker('Gamma')
+ self._plot.removeMarker("Gamma")
except Exception:
pass
@@ -703,10 +717,9 @@ class _ColormapHistogram(qt.QWidget):
self._lutItem2.setVisible(False)
self._lutItem2.setColormap(normColormap)
xx = numpy.geomspace(posMin, posMax, 256)
- self._lutItem2.setData(x=xx,
- y=self.__lutY,
- value=self.__lutV,
- copy=False)
+ self._lutItem2.setData(
+ x=xx, y=self.__lutY, value=self.__lutV, copy=False
+ )
self._lutItem2.setSymbol("|")
self._lutItem2.setVisible(True)
self._lutItem.setVisible(False)
@@ -717,10 +730,8 @@ class _ColormapHistogram(qt.QWidget):
self._lutItem2.setColormap(normColormap)
xx = numpy.linspace(posMin, posMax, 256, endpoint=True)
self._lutItem2.setData(
- x=xx,
- y=self.__lutY,
- value=self.__lutV,
- copy=False)
+ x=xx, y=self.__lutY, value=self.__lutV, copy=False
+ )
self._lutItem2.setSymbol("|")
self._lutItem2.setVisible(True)
self._lutItem.setVisible(False)
@@ -750,15 +761,29 @@ class _ColormapHistogram(qt.QWidget):
x = min(x, vmax)
return x, y
- def _setDataInPlotMode(self, mode):
- if self._dataInPlotMode == mode:
+ def setDisplayMode(self, mode: str | DisplayMode):
+ mode = DisplayMode.from_value(mode)
+ if mode is DisplayMode.HISTOGRAM:
+ action = self._dataHistogramAction
+ elif mode is DisplayMode.RANGE:
+ action = self._dataRangeAction
+ else:
+ raise ValueError("Mode not supported")
+ action.setChecked(True)
+ self._displayModeChanged(action)
+
+ def _setDisplayMode(self, mode):
+ if self._displayMode == mode:
return
- self._dataInPlotMode = mode
- self._updateDataInPlot()
+ self._displayMode = mode
+ self._updateDisplayMode()
- def _displayDataInPlotModeChanged(self, action):
+ def getDsiplayMode(self) -> DisplayMode:
+ return self._displayMode
+
+ def _displayModeChanged(self, action):
mode = action.data()
- self._setDataInPlotMode(mode)
+ self._setDisplayMode(mode)
def invalidateData(self):
self._histogramData = {}
@@ -766,8 +791,8 @@ class _ColormapHistogram(qt.QWidget):
self._invalidated = True
self.update()
- def _updateDataInPlot(self):
- mode = self._dataInPlotMode
+ def _updateDisplayMode(self):
+ mode = self._displayMode
norm = self._getNorm()
if norm == Colormap.LINEAR:
@@ -780,38 +805,42 @@ class _ColormapHistogram(qt.QWidget):
axis = self._plot.getXAxis()
axis.setScale(scale)
- if mode == _DataInPlotMode.RANGE:
+ if mode == DisplayMode.RANGE:
dataRange = self._getNormalizedDataRange()
xmin, xmax = dataRange
if xmax is None or xmin is None:
- self._plot.remove(legend='Data', kind='histogram')
+ self._plot.remove(legend="Data", kind="histogram")
else:
histogram = numpy.array([1])
bin_edges = numpy.array([xmin, xmax])
- self._plot.addHistogram(histogram,
- bin_edges,
- legend="Data",
- color='gray',
- align='center',
- fill=True,
- z=1)
-
- elif mode == _DataInPlotMode.HISTOGRAM:
+ self._plot.addHistogram(
+ histogram,
+ bin_edges,
+ legend="Data",
+ color="gray",
+ align="center",
+ fill=True,
+ z=1,
+ )
+
+ elif mode == DisplayMode.HISTOGRAM:
histogram, bin_edges = self._getNormalizedHistogram()
if histogram is None or bin_edges is None:
- self._plot.remove(legend='Data', kind='histogram')
+ self._plot.remove(legend="Data", kind="histogram")
else:
histogram = numpy.array(histogram, copy=True)
bin_edges = numpy.array(bin_edges, copy=True)
- with numpy.errstate(invalid='ignore'):
+ with numpy.errstate(invalid="ignore"):
norm_histogram = histogram / numpy.nanmax(histogram)
- self._plot.addHistogram(norm_histogram,
- bin_edges,
- legend="Data",
- color='gray',
- align='center',
- fill=True,
- z=1)
+ self._plot.addHistogram(
+ norm_histogram,
+ bin_edges,
+ legend="Data",
+ color="gray",
+ align="center",
+ fill=True,
+ z=1,
+ )
else:
_logger.error("Mode unsupported")
@@ -830,7 +859,7 @@ class _ColormapHistogram(qt.QWidget):
return norm
def updateNormalization(self):
- self._updateDataInPlot()
+ self._updateDisplayMode()
self.update()
@@ -887,16 +916,19 @@ class ColormapDialog(qt.QDialog):
# Colormap row
self._comboBoxColormap = ColormapNameComboBox(parent=self)
- self._comboBoxColormap.currentIndexChanged[int].connect(self._comboBoxColormapUpdated)
+ self._comboBoxColormap.currentIndexChanged[int].connect(
+ self._comboBoxColormapUpdated
+ )
# Normalization row
self._comboBoxNormalization = qt.QComboBox(parent=self)
normalizations = [
- ('Linear', Colormap.LINEAR),
- ('Gamma correction', Colormap.GAMMA),
- ('Arcsinh', Colormap.ARCSINH),
- ('Logarithmic', Colormap.LOGARITHM),
- ('Square root', Colormap.SQRT)]
+ ("Linear", Colormap.LINEAR),
+ ("Gamma correction", Colormap.GAMMA),
+ ("Arcsinh", Colormap.ARCSINH),
+ ("Logarithmic", Colormap.LOGARITHM),
+ ("Square root", Colormap.SQRT),
+ ]
for name, userData in normalizations:
try:
icon = icons.getQIcon("colormap-norm-%s" % userData)
@@ -904,11 +936,12 @@ class ColormapDialog(qt.QDialog):
icon = qt.QIcon()
self._comboBoxNormalization.addItem(icon, name, userData)
self._comboBoxNormalization.currentIndexChanged[int].connect(
- self._normalizationUpdated)
+ self._normalizationUpdated
+ )
self._gammaSpinBox = qt.QDoubleSpinBox(parent=self)
self._gammaSpinBox.setEnabled(False)
- self._gammaSpinBox.setRange(0.01, 100.)
+ self._gammaSpinBox.setRange(0.01, 100.0)
self._gammaSpinBox.setDecimals(4)
if hasattr(qt.QDoubleSpinBox, "setStepType"):
# Introduced in Qt 5.12
@@ -916,7 +949,7 @@ class ColormapDialog(qt.QDialog):
else:
self._gammaSpinBox.setSingleStep(0.1)
self._gammaSpinBox.valueChanged.connect(self._gammaUpdated)
- self._gammaSpinBox.setValue(2.)
+ self._gammaSpinBox.setValue(2.0)
autoScaleCombo = _AutoscaleModeComboBox(self)
autoScaleCombo.currentIndexChanged.connect(self._autoscaleModeUpdated)
@@ -959,15 +992,17 @@ class ColormapDialog(qt.QDialog):
self._histoWidget = _ColormapHistogram(self)
self._histoWidget.sigRangeMoving.connect(self._histogramRangeMoving)
self._histoWidget.sigRangeMoved.connect(self._histogramRangeMoved)
- self._histoWidget.setSizePolicy(qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding)
+ self._histoWidget.setSizePolicy(
+ qt.QSizePolicy.Expanding, qt.QSizePolicy.Expanding
+ )
# Scale to buttons
self._visibleAreaButton = qt.QPushButton(self)
self._visibleAreaButton.setEnabled(False)
self._visibleAreaButton.setText("Visible Area")
self._visibleAreaButton.clicked.connect(
- self._handleScaleToVisibleAreaClicked,
- type=qt.Qt.QueuedConnection)
+ self._handleScaleToVisibleAreaClicked, type=qt.Qt.QueuedConnection
+ )
# Place-holder for selected area ROI manager
self._roiForColormapManager = None
@@ -979,8 +1014,8 @@ class ColormapDialog(qt.QDialog):
self._selectedAreaButton.setIcon(icons.getQIcon("add-shape-rectangle"))
self._selectedAreaButton.setCheckable(True)
self._selectedAreaButton.toggled.connect(
- self._handleScaleToSelectionToggled,
- type=qt.Qt.QueuedConnection)
+ self._handleScaleToSelectionToggled, type=qt.Qt.QueuedConnection
+ )
# define modal buttons
types = qt.QDialogButtonBox.Ok | qt.QDialogButtonBox.Cancel
@@ -1003,8 +1038,9 @@ class ColormapDialog(qt.QDialog):
self._buttonsNonModal.setFocus(qt.Qt.OtherFocusReason)
# Set the colormap to default values
- self.setColormap(Colormap(name='gray', normalization='linear',
- vmin=None, vmax=None))
+ self.setColormap(
+ Colormap(name="gray", normalization="linear", vmin=None, vmax=None)
+ )
self.setModal(self.isModal())
@@ -1023,19 +1059,23 @@ class ColormapDialog(qt.QDialog):
layoutScale.addWidget(self._autoScaleCombo)
layoutScale.addStretch()
-
formLayout = FormGridLayout(self)
formLayout.setContentsMargins(10, 10, 10, 10)
- formLayout.addRow('Colormap:', self._comboBoxColormap)
- formLayout.addRow('Normalization:', self._comboBoxNormalization)
- formLayout.addRow('Gamma:', self._gammaSpinBox)
+ formLayout.addRow("Colormap:", self._comboBoxColormap)
+ formLayout.addRow("Normalization:", self._comboBoxNormalization)
+ formLayout.addRow("Gamma:", self._gammaSpinBox)
- formLayout.addItem(qt.QSpacerItem(1, 1, qt.QSizePolicy.Fixed, qt.QSizePolicy.Fixed))
+ formLayout.addItem(
+ qt.QSpacerItem(1, 1, qt.QSizePolicy.Fixed, qt.QSizePolicy.Fixed)
+ )
formLayout.addRow(self._histoWidget)
+ formLayout.setRowStretch(formLayout.rowCount() - 1, 1)
formLayout.addRow(rangeLayout)
- formLayout.addItem(qt.QSpacerItem(1, 1, qt.QSizePolicy.Fixed, qt.QSizePolicy.Fixed))
- formLayout.addRow('Scale:', layoutScale)
+ formLayout.addItem(
+ qt.QSpacerItem(1, 1, qt.QSizePolicy.Fixed, qt.QSizePolicy.Fixed)
+ )
+ formLayout.addRow("Scale:", layoutScale)
formLayout.addRow("Fixed scale on:", self._scaleToAreaGroup)
formLayout.addRow(self._buttonsModal)
formLayout.addRow(self._buttonsNonModal)
@@ -1054,6 +1094,9 @@ class ColormapDialog(qt.QDialog):
self._applyColormap()
+ def getHistogramWidget(self):
+ return self._histoWidget
+
def _invalidateColormap(self):
if self.isVisible():
self._applyColormap()
@@ -1156,9 +1199,9 @@ class ColormapDialog(qt.QDialog):
if dataRange is None or len(dataRange) != 3:
qt.QMessageBox.warning(
- None, "No Data",
- "Image data does not contain any real value")
- dataRange = 1., 1., 10.
+ None, "No Data", "Image data does not contain any real value"
+ )
+ dataRange = 1.0, 1.0, 10.0
return dataRange
@@ -1182,11 +1225,11 @@ class ColormapDialog(qt.QDialog):
return None, None
if data.ndim == 3: # RGB(A) images
- _logger.info('Converting current image from RGB(A) to grayscale\
- in order to compute the intensity distribution')
- data = (data[:,:, 0] * 0.299 +
- data[:,:, 1] * 0.587 +
- data[:,:, 2] * 0.114)
+ _logger.info(
+ "Converting current image from RGB(A) to grayscale\
+ in order to compute the intensity distribution"
+ )
+ data = data[:, :, 0] * 0.299 + data[:, :, 1] * 0.587 + data[:, :, 2] * 0.114
# bad hack: get 256 continuous bins in the case we have a B&W
normalizeData = True
@@ -1200,7 +1243,7 @@ class ColormapDialog(qt.QDialog):
if normalizeData:
if scale == Colormap.LOGARITHM:
- with numpy.errstate(divide='ignore', invalid='ignore'):
+ with numpy.errstate(divide="ignore", invalid="ignore"):
data = numpy.log10(data)
if dataRange is not None:
@@ -1231,7 +1274,7 @@ class ColormapDialog(qt.QDialog):
bins = histogram.edges[0]
if normalizeData:
if scale == Colormap.LOGARITHM:
- bins = 10 ** bins
+ bins = 10**bins
return histogram.histo, bins
def _getItem(self):
@@ -1263,8 +1306,7 @@ class ColormapDialog(qt.QDialog):
if oldArray is array:
return
- self._data = None
- self._itemHolder = None
+ self.__resetItem()
try:
if item is None:
self._item = None
@@ -1272,6 +1314,7 @@ class ColormapDialog(qt.QDialog):
if not isinstance(item, items.ColormapMixIn):
self._item = None
raise ValueError("Item %s is not supported" % item)
+ item.sigItemChanged.connect(self.__itemChanged)
self._item = weakref.ref(item, self._itemAboutToFinalize)
finally:
self._syncScaleToButtonsEnabled()
@@ -1279,6 +1322,20 @@ class ColormapDialog(qt.QDialog):
self._histogramData = None
self._invalidateData()
+ def __resetItem(self):
+ """Reset item and data used by the dialog"""
+ self._data = None
+ self._itemHolder = None
+ if self._item is not None:
+ item = self._item()
+ self._item = None
+ if item is not None:
+ item.sigItemChanged.disconnect(self.__itemChanged)
+
+ def __itemChanged(self, event):
+ if event == items.ItemChangedType.DATA:
+ self._invalidateData()
+
def _getData(self):
if self._data is None:
return None
@@ -1295,12 +1352,9 @@ class ColormapDialog(qt.QDialog):
if oldData is data:
return
- self._item = None
+ self.__resetItem()
self._syncScaleToButtonsEnabled()
- if data is None:
- self._data = None
- self._itemHolder = None
- else:
+ if data is not None:
self._data = weakref.ref(data, self._dataAboutToFinalize)
self._itemHolder = _DataRefHolder(self._data)
@@ -1338,14 +1392,6 @@ class ColormapDialog(qt.QDialog):
if self._item is weakref and qtinspect.isValid(self):
self.setItem(None)
- @deprecation.deprecated(reason="It is private data", since_version="0.13")
- def getHistogram(self):
- histo = self._getHistogram()
- if histo is None:
- return None
- counts, bin_edges = histo
- return numpy.array(counts, copy=True), numpy.array(bin_edges, copy=True)
-
def _getHistogram(self):
"""Returns the histogram defined by the dialog as metadata
to describe the data in order to speed up the dialog.
@@ -1429,7 +1475,7 @@ class ColormapDialog(qt.QDialog):
(xmin, xmax, ymin, ymax) Rectangular region in data space
"""
if bounds is None:
- return None # no-op
+ return # no-op
colormap = self.getColormap()
if colormap is None:
@@ -1437,13 +1483,15 @@ class ColormapDialog(qt.QDialog):
item = self._getItem()
if not isinstance(item, items.ColormapMixIn):
- return None # no-op
+ return # no-op
data = item.getColormappedData(copy=False)
-
xmin, xmax, ymin, ymax = bounds
if isinstance(item, items.ImageBase):
+ if data.ndim != 2:
+ return # no-op
+
ox, oy = item.getOrigin()
sx, sy = item.getScale()
@@ -1460,7 +1508,9 @@ class ColormapDialog(qt.QDialog):
subset = data[
numpy.logical_and(
numpy.logical_and(xmin <= x, x <= xmax),
- numpy.logical_and(ymin <= y, y <= ymax))]
+ numpy.logical_and(ymin <= y, y <= ymax),
+ )
+ ]
if subset.size == 0:
return # no-op
@@ -1563,19 +1613,21 @@ class ColormapDialog(qt.QDialog):
self._comboBoxColormap.setEnabled(colormap.isEditable())
with utils.blockSignals(self._comboBoxNormalization):
index = self._comboBoxNormalization.findData(
- colormap.getNormalization())
+ colormap.getNormalization()
+ )
if index < 0:
- _logger.error('Unsupported normalization: %s' %
- colormap.getNormalization())
+ _logger.error(
+ "Unsupported normalization: %s" % colormap.getNormalization()
+ )
else:
self._comboBoxNormalization.setCurrentIndex(index)
self._comboBoxNormalization.setEnabled(colormap.isEditable())
with utils.blockSignals(self._gammaSpinBox):
- self._gammaSpinBox.setValue(
- colormap.getGammaNormalizationParameter())
+ self._gammaSpinBox.setValue(colormap.getGammaNormalizationParameter())
self._gammaSpinBox.setEnabled(
- colormap.getNormalization() == Colormap.GAMMA and
- colormap.isEditable())
+ colormap.getNormalization() == Colormap.GAMMA
+ and colormap.isEditable()
+ )
with utils.blockSignals(self._autoScaleCombo):
self._autoScaleCombo.setCurrentMode(colormap.getAutoscaleMode())
self._autoScaleCombo.setEnabled(colormap.isEditable())
@@ -1624,8 +1676,8 @@ class ColormapDialog(qt.QDialog):
dataRange = self._getFiniteColormapRange()
# Final colormap range
- vmin = (dataRange[0] if not autoRange[0] else None)
- vmax = (dataRange[1] if not autoRange[1] else None)
+ vmin = dataRange[0] if not autoRange[0] else None
+ vmax = dataRange[1] if not autoRange[1] else None
with self._colormapChange:
colormap = self.getColormap()
@@ -1645,7 +1697,7 @@ class ColormapDialog(qt.QDialog):
colormap = self.getColormap()
if colormap is not None:
normalization = self._comboBoxNormalization.itemData(index)
- self._gammaSpinBox.setEnabled(normalization == 'gamma')
+ self._gammaSpinBox.setEnabled(normalization == "gamma")
with self._colormapChange:
colormap.setNormalization(normalization)
@@ -1745,7 +1797,7 @@ class ColormapDialog(qt.QDialog):
gamma = self._gammaSpinBox.minimum()
else:
gamma = numpy.clip(
- numpy.log(0.5)/numpy.log((gammaPos - vmin) / (vmax - vmin)),
+ numpy.log(0.5) / numpy.log((gammaPos - vmin) / (vmax - vmin)),
self._gammaSpinBox.minimum(),
self._gammaSpinBox.maximum(),
)
@@ -1771,7 +1823,9 @@ class ColormapDialog(qt.QDialog):
def _syncScaleToButtonsEnabled(self):
"""Set the state of scale to buttons according to current item and colormap"""
colormap = self.getColormap()
- enabled = self._item is not None and colormap is not None and colormap.isEditable()
+ enabled = (
+ self._item is not None and colormap is not None and colormap.isEditable()
+ )
self._scaleToAreaGroup.setVisible(enabled)
self._visibleAreaButton.setEnabled(enabled)
if not enabled:
@@ -1817,10 +1871,14 @@ class ColormapDialog(qt.QDialog):
self._roiForColormapManager = RegionOfInterestManager(parent=plotWidget)
cmap = self.getColormap()
self._roiForColormapManager.setColor(
- 'black' if cmap is None else cursorColorForColormap(cmap.getName()))
+ "black" if cmap is None else cursorColorForColormap(cmap.getName())
+ )
self._roiForColormapManager.sigInteractiveModeFinished.connect(
- self.__roiInteractiveModeFinished)
- self._roiForColormapManager.sigInteractiveRoiFinalized.connect(self.__roiFinalized)
+ self.__roiInteractiveModeFinished
+ )
+ self._roiForColormapManager.sigInteractiveRoiFinalized.connect(
+ self.__roiFinalized
+ )
self._roiForColormapManager.start(RectangleROI)
def __roiInteractiveModeFinished(self):
@@ -1830,7 +1888,7 @@ class ColormapDialog(qt.QDialog):
if roi is not None:
ox, oy = roi.getOrigin()
width, height = roi.getSize()
- self.setColormapRangeFromDataBounds((ox, ox+width, oy, oy+height))
+ self.setColormapRangeFromDataBounds((ox, ox + width, oy, oy + height))
# clear ROI
self._roiForColormapManager.removeRoi(roi)
diff --git a/src/silx/gui/dialog/DataFileDialog.py b/src/silx/gui/dialog/DataFileDialog.py
index 75b1721..4c6891e 100644
--- a/src/silx/gui/dialog/DataFileDialog.py
+++ b/src/silx/gui/dialog/DataFileDialog.py
@@ -36,8 +36,6 @@ from silx.gui.hdf5.Hdf5Formatter import Hdf5Formatter
import silx.io
from .AbstractDataFileDialog import AbstractDataFileDialog
-import fabio
-
_logger = logging.getLogger(__name__)
@@ -336,4 +334,4 @@ class DataFileDialog(AbstractDataFileDialog):
selection widget (basically the data from the browsing widget)
:rtype: bool
"""
- return u""
+ return ""
diff --git a/src/silx/gui/dialog/DatasetDialog.py b/src/silx/gui/dialog/DatasetDialog.py
index 5d8af0d..1bc2722 100644
--- a/src/silx/gui/dialog/DatasetDialog.py
+++ b/src/silx/gui/dialog/DatasetDialog.py
@@ -60,17 +60,22 @@ class DatasetDialog(_Hdf5ItemSelectionDialog):
print("Operation cancelled :(")
"""
+
def __init__(self, parent=None):
_Hdf5ItemSelectionDialog.__init__(self, parent)
# customization for groups
self.setWindowTitle("HDF5 dataset selection")
- self._header.setSections([self._model.NAME_COLUMN,
- self._model.NODE_COLUMN,
- self._model.LINK_COLUMN,
- self._model.TYPE_COLUMN,
- self._model.SHAPE_COLUMN])
+ self._header.setSections(
+ [
+ self._model.NAME_COLUMN,
+ self._model.NODE_COLUMN,
+ self._model.LINK_COLUMN,
+ self._model.TYPE_COLUMN,
+ self._model.SHAPE_COLUMN,
+ ]
+ )
self._selectDatasetStatusText = "Select a dataset or type a new dataset name"
def setMode(self, mode):
@@ -80,7 +85,9 @@ class DatasetDialog(_Hdf5ItemSelectionDialog):
"""
_Hdf5ItemSelectionDialog.setMode(self, mode)
if mode == DatasetDialog.SaveMode:
- self._selectDatasetStatusText = "Select a dataset or type a new dataset name"
+ self._selectDatasetStatusText = (
+ "Select a dataset or type a new dataset name"
+ )
elif mode == DatasetDialog.LoadMode:
self._selectDatasetStatusText = "Select a dataset"
@@ -110,11 +117,11 @@ class DatasetDialog(_Hdf5ItemSelectionDialog):
isDatasetSelected = True
if isDatasetSelected:
- self._selectedUrl = DataUrl(file_path=node.local_filename,
- data_path=data_path)
+ self._selectedUrl = DataUrl(
+ file_path=node.local_filename, data_path=data_path
+ )
self._okButton.setEnabled(True)
- self._labelSelection.setText(
- self._selectedUrl.path())
+ self._labelSelection.setText(self._selectedUrl.path())
else:
self._selectedUrl = None
self._okButton.setEnabled(False)
diff --git a/src/silx/gui/dialog/FileTypeComboBox.py b/src/silx/gui/dialog/FileTypeComboBox.py
index 0ffc3a5..85ad3b1 100644
--- a/src/silx/gui/dialog/FileTypeComboBox.py
+++ b/src/silx/gui/dialog/FileTypeComboBox.py
@@ -1,6 +1,6 @@
# /*##########################################################################
#
-# Copyright (c) 2016 European Synchrotron Radiation Facility
+# Copyright (c) 2016-2023 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -30,12 +30,13 @@ __license__ = "MIT"
__date__ = "17/01/2019"
import fabio
+from fabio import fabioutils
+
import silx.io
from silx.gui import qt
class Codec(object):
-
def __init__(self, any_fabio=False, any_silx=False, fabio_codec=None, auto=False):
self.__any_fabio = any_fabio
self.__any_silx = any_silx
@@ -63,7 +64,7 @@ class FileTypeComboBox(qt.QComboBox):
CODEC_ROLE = qt.Qt.UserRole + 2
- INDENTATION = u"\u2022 "
+ INDENTATION = "\u2022 "
def __init__(self, parent=None):
qt.QComboBox.__init__(self, parent)
@@ -134,20 +135,13 @@ class FileTypeComboBox(qt.QComboBox):
def __insertFabioFormats(self):
formats = fabio.fabioformats.get_classes(reader=True)
- from fabio import fabioutils
- if hasattr(fabioutils, "COMPRESSED_EXTENSIONS"):
- compressedExtensions = fabioutils.COMPRESSED_EXTENSIONS
- else:
- # Support for fabio < 0.9
- compressedExtensions = set(["gz", "bz2"])
-
extensions = []
allExtensions = set([])
def extensionsIterator(reader):
for extension in reader.DEFAULT_EXTENSIONS:
yield "*.%s" % extension
- for compressedExtension in compressedExtensions:
+ for compressedExtension in fabioutils.COMPRESSED_EXTENSIONS:
for extension in reader.DEFAULT_EXTENSIONS:
yield "*.%s.%s" % (extension, compressedExtension)
@@ -163,7 +157,9 @@ class FileTypeComboBox(qt.QComboBox):
allExtensions.update(ext)
if ext == []:
ext = ["*"]
- extensions.append((reader.DESCRIPTION, displayext, ext, reader.codec_name()))
+ extensions.append(
+ (reader.DESCRIPTION, displayext, ext, reader.codec_name())
+ )
extensions = list(sorted(extensions))
allExtensions = list(sorted(list(allExtensions)))
@@ -176,7 +172,9 @@ class FileTypeComboBox(qt.QComboBox):
description, displayExt, allExt, _codecName = e
index = self.count()
if len(e[1]) < 10:
- self.addItem("%s%s (%s)" % (self.INDENTATION, description, " ".join(displayExt)))
+ self.addItem(
+ "%s%s (%s)" % (self.INDENTATION, description, " ".join(displayExt))
+ )
else:
self.addItem("%s%s" % (self.INDENTATION, description))
codec = Codec(fabio_codec=_codecName)
diff --git a/src/silx/gui/dialog/GroupDialog.py b/src/silx/gui/dialog/GroupDialog.py
index fb85d83..ca669f2 100644
--- a/src/silx/gui/dialog/GroupDialog.py
+++ b/src/silx/gui/dialog/GroupDialog.py
@@ -54,8 +54,7 @@ class _Hdf5ItemSelectionDialog(qt.QDialog):
self._tree = Hdf5TreeView(self)
self._tree.setSelectionMode(qt.QAbstractItemView.SingleSelection)
self._tree.activated.connect(self._onActivation)
- self._tree.selectionModel().selectionChanged.connect(
- self._onSelectionChange)
+ self._tree.selectionModel().selectionChanged.connect(self._onSelectionChange)
self._model = self._tree.findHdf5TreeModel()
@@ -67,10 +66,9 @@ class _Hdf5ItemSelectionDialog(qt.QDialog):
self._labelNewItem.setText("Create new item in selected group (optional):")
self._lineEditNewItem = qt.QLineEdit(self._newItemWidget)
self._lineEditNewItem.setToolTip(
- "Specify the name of a new item "
- "to be created in the selected group.")
- self._lineEditNewItem.textChanged.connect(
- self._onNewItemNameChange)
+ "Specify the name of a new item " "to be created in the selected group."
+ )
+ self._lineEditNewItem.textChanged.connect(self._onNewItemNameChange)
newItemLayout.addWidget(self._labelNewItem)
newItemLayout.addWidget(self._lineEditNewItem)
@@ -151,11 +149,11 @@ class _Hdf5ItemSelectionDialog(qt.QDialog):
if not data_path.endswith("/"):
data_path += "/"
data_path += subgroupName.lstrip("/")
- self._selectedUrl = DataUrl(file_path=node.local_filename,
- data_path=data_path)
+ self._selectedUrl = DataUrl(
+ file_path=node.local_filename, data_path=data_path
+ )
self._okButton.setEnabled(True)
- self._labelSelection.setText(
- self._selectedUrl.path())
+ self._labelSelection.setText(self._selectedUrl.path())
def getSelectedDataUrl(self):
"""Return a :class:`DataUrl` with a file path and a data path.
@@ -189,15 +187,16 @@ class GroupDialog(_Hdf5ItemSelectionDialog):
print("Operation cancelled :(")
"""
+
def __init__(self, parent=None):
_Hdf5ItemSelectionDialog.__init__(self, parent)
# customization for groups
self.setWindowTitle("HDF5 group selection")
- self._header.setSections([self._model.NAME_COLUMN,
- self._model.NODE_COLUMN,
- self._model.LINK_COLUMN])
+ self._header.setSections(
+ [self._model.NAME_COLUMN, self._model.NODE_COLUMN, self._model.LINK_COLUMN]
+ )
def _onActivation(self, idx):
# double-click or enter press: filter for groups
@@ -218,11 +217,11 @@ class GroupDialog(_Hdf5ItemSelectionDialog):
if not data_path.endswith("/"):
data_path += "/"
data_path += subgroupName.lstrip("/")
- self._selectedUrl = DataUrl(file_path=node.local_filename,
- data_path=data_path)
+ self._selectedUrl = DataUrl(
+ file_path=node.local_filename, data_path=data_path
+ )
self._okButton.setEnabled(True)
- self._labelSelection.setText(
- self._selectedUrl.path())
+ self._labelSelection.setText(self._selectedUrl.path())
else:
self._selectedUrl = None
self._okButton.setEnabled(False)
diff --git a/src/silx/gui/dialog/ImageFileDialog.py b/src/silx/gui/dialog/ImageFileDialog.py
index ed455f3..e7ce38f 100644
--- a/src/silx/gui/dialog/ImageFileDialog.py
+++ b/src/silx/gui/dialog/ImageFileDialog.py
@@ -198,7 +198,9 @@ class _ImagePreview(qt.QWidget):
axis = self.__plot.getXAxis()
axis.setLimitsConstraints(midWidth - widthContraint, midWidth + widthContraint)
axis = self.__plot.getYAxis()
- axis.setLimitsConstraints(midHeight - heightContraint, midHeight + heightContraint)
+ axis.setLimitsConstraints(
+ midHeight - heightContraint, midHeight + heightContraint
+ )
def __imageItem(self):
image = self.__plot.getImage("data")
@@ -340,14 +342,14 @@ class ImageFileDialog(AbstractDataFileDialog):
"""
destination = self.__formatShape(dataAfterSelection.shape)
source = self.__formatShape(dataBeforeSelection.shape)
- return u"%s \u2192 %s" % (source, destination)
+ return "%s \u2192 %s" % (source, destination)
def __formatShape(self, shape):
result = []
for s in shape:
if isinstance(s, slice):
- v = u"\u2026"
+ v = "\u2026"
else:
v = str(s)
result.append(v)
- return u" \u00D7 ".join(result)
+ return " \u00D7 ".join(result)
diff --git a/src/silx/gui/dialog/SafeFileIconProvider.py b/src/silx/gui/dialog/SafeFileIconProvider.py
index 141bedf..7022876 100644
--- a/src/silx/gui/dialog/SafeFileIconProvider.py
+++ b/src/silx/gui/dialog/SafeFileIconProvider.py
@@ -91,6 +91,7 @@ class SafeFileIconProvider(qt.QFileIconProvider):
def __windowsDriveTypeId(self, info):
try:
import ctypes
+
path = info.filePath()
dtype = ctypes.cdll.kernel32.GetDriveTypeW(path)
except Exception:
diff --git a/src/silx/gui/dialog/SafeFileSystemModel.py b/src/silx/gui/dialog/SafeFileSystemModel.py
index b9f3913..7cacc1e 100644
--- a/src/silx/gui/dialog/SafeFileSystemModel.py
+++ b/src/silx/gui/dialog/SafeFileSystemModel.py
@@ -41,7 +41,6 @@ _logger = logging.getLogger(__name__)
class _Item(object):
-
def __init__(self, fileInfo):
self.__fileInfo = fileInfo
self.__parent = None
@@ -101,7 +100,9 @@ class _Item(object):
elif self.isDrive():
path = self.__fileInfo.filePath()
else:
- path = os.path.join(self.parent().absoluteFilePath(), self.__fileInfo.fileName())
+ path = os.path.join(
+ self.parent().absoluteFilePath(), self.__fileInfo.fileName()
+ )
if path == "":
return "/"
self.__absolutePath = path
@@ -236,7 +237,9 @@ class _RawFileSystemModel(qt.QAbstractItemModel):
self.__header = "Name", "Size", "Type", "Last modification"
self.__currentPath = ""
self.__iconProvider = SafeFileIconProvider()
- self.__directoryLoadedSync.connect(self.__emitDirectoryLoaded, qt.Qt.QueuedConnection)
+ self.__directoryLoadedSync.connect(
+ self.__emitDirectoryLoaded, qt.Qt.QueuedConnection
+ )
def headerData(self, section, orientation, role=qt.Qt.DisplayRole):
if orientation == qt.Qt.Horizontal:
@@ -496,7 +499,7 @@ class _RawFileSystemModel(qt.QAbstractItemModel):
return
def setReadOnly(self, enable):
- assert(enable is True)
+ assert enable is True
def isReadOnly(self):
return False
@@ -612,20 +615,20 @@ class SafeFileSystemModel(qt.QSortFilterProxyModel):
filterPermissions = (filters & qt.QDir.PermissionMask) != 0
if filterPermissions and (filters & (qt.QDir.Dirs | qt.QDir.Files)):
- if (filters & qt.QDir.Readable):
+ if filters & qt.QDir.Readable:
# Hide unreadable
if not fileInfo.isReadable():
return False
- if (filters & qt.QDir.Writable):
+ if filters & qt.QDir.Writable:
# Hide unwritable
if not fileInfo.isWritable():
return False
- if (filters & qt.QDir.Executable):
+ if filters & qt.QDir.Executable:
# Hide unexecutable
if not fileInfo.isExecutable():
return False
- if (filters & qt.QDir.NoSymLinks):
+ if filters & qt.QDir.NoSymLinks:
# Hide sym links
if fileInfo.isSymLink():
return False
@@ -711,7 +714,9 @@ class SafeFileSystemModel(qt.QSortFilterProxyModel):
def setNameFilters(self, filters):
self.__nameFilters = []
isCaseSensitive = self.__filters & qt.QDir.CaseSensitive
- caseSensitive = qt.Qt.CaseSensitive if isCaseSensitive else qt.Qt.CaseInsensitive
+ caseSensitive = (
+ qt.Qt.CaseSensitive if isCaseSensitive else qt.Qt.CaseInsensitive
+ )
for f in filters:
reg = qt.QRegExp(f, caseSensitive, qt.QRegExp.Wildcard)
self.__nameFilters.append(reg)
@@ -730,7 +735,7 @@ class SafeFileSystemModel(qt.QSortFilterProxyModel):
self.invalidate()
def setReadOnly(self, enable):
- assert(enable is True)
+ assert enable is True
def isReadOnly(self):
return False
diff --git a/src/silx/gui/dialog/test/test_colormapdialog.py b/src/silx/gui/dialog/test/test_colormapdialog.py
index 1bfd584..1afafc0 100644
--- a/src/silx/gui/dialog/test/test_colormapdialog.py
+++ b/src/silx/gui/dialog/test/test_colormapdialog.py
@@ -1,6 +1,6 @@
# /*##########################################################################
#
-# Copyright (c) 2016-2022 European Synchrotron Radiation Facility
+# Copyright (c) 2016-2024 European Synchrotron Radiation Facility
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@@ -29,371 +29,369 @@ __date__ = "09/11/2018"
import pytest
-import weakref
from silx.gui import qt
from silx.gui.dialog import ColormapDialog
-from silx.gui.utils.testutils import TestCaseQt
from silx.gui.colors import Colormap, preferredColormaps
-from silx.utils.testutils import ParametricTestCase
from silx.gui.plot.items.image import ImageData
import numpy
-@pytest.fixture
-def colormap():
- colormap = Colormap(name='gray',
- vmin=10.0, vmax=20.0,
- normalization='linear')
- yield colormap
+def testGUIEdition(qWidgetFactory):
+ """Make sure the colormap is correctly edited and also that the
+ modification are correctly updated if an other colormapdialog is
+ editing the same colormap"""
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ dialog.setColormap(colormap)
+ dialog2 = qWidgetFactory(ColormapDialog.ColormapDialog)
+ dialog2.setColormap(colormap)
+
+ dialog._comboBoxColormap._setCurrentName("red")
+ dialog._comboBoxNormalization.setCurrentIndex(
+ dialog._comboBoxNormalization.findData(Colormap.LOGARITHM)
+ )
+ assert colormap.getName() == "red"
+ assert dialog.getColormap().getName() == "red"
+ assert colormap.getNormalization() == "log"
+ assert colormap.getVMin() == 10
+ assert colormap.getVMax() == 20
+ # checked second colormap dialog
+ assert dialog2._comboBoxColormap.getCurrentName() == "red"
+ assert dialog2._comboBoxNormalization.currentData() == Colormap.LOGARITHM
+ assert int(dialog2._minValue.getValue()) == 10
+ assert int(dialog2._maxValue.getValue()) == 20
+
+
+def testGUIModalOk(qapp, qapp_utils, qWidgetFactory):
+ """Make sure the colormap is modified if gone through accept"""
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ assert colormap.isAutoscale() is False
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ dialog.setModal(True)
+ qapp.processEvents()
+
+ dialog.setColormap(colormap)
+ assert colormap.getVMin() is not None
+ dialog._minValue.sigAutoScaleChanged.emit(True)
+ assert colormap.getVMin() is None
+ dialog._maxValue.sigAutoScaleChanged.emit(True)
+ qapp_utils.mouseClick(
+ widget=dialog._buttonsModal.button(qt.QDialogButtonBox.Ok),
+ button=qt.Qt.LeftButton,
+ )
+ assert colormap.getVMin() is None
+ assert colormap.getVMax() is None
+ assert colormap.isAutoscale() is True
+
+
+def testGUIModalCancel(qapp, qapp_utils, qWidgetFactory):
+ """Make sure the colormap is not modified if gone through reject"""
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ assert colormap.isAutoscale() is False
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ dialog.setModal(True)
+ qapp.processEvents()
+
+ dialog.setColormap(colormap)
+ assert colormap.getVMin() is not None
+ dialog._minValue.sigAutoScaleChanged.emit(True)
+ assert colormap.getVMin() is None
+ qapp_utils.mouseClick(
+ widget=dialog._buttonsModal.button(qt.QDialogButtonBox.Cancel),
+ button=qt.Qt.LeftButton,
+ )
+ assert colormap.getVMin() is not None
+
+
+def testGUIModalClose(qapp, qapp_utils, qWidgetFactory):
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ assert colormap.isAutoscale() is False
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ dialog.setModal(False)
+ qapp.processEvents()
+ dialog.setColormap(colormap)
+ assert colormap.getVMin() is not None
+ dialog._minValue.sigAutoScaleChanged.emit(True)
+ assert colormap.getVMin() is None
+ qapp_utils.mouseClick(
+ widget=dialog._buttonsNonModal.button(qt.QDialogButtonBox.Close),
+ button=qt.Qt.LeftButton,
+ )
+ assert colormap.getVMin() is None
+
+
+def testGUIModalReset(qapp, qapp_utils, qWidgetFactory):
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ assert colormap.isAutoscale() is False
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ dialog.setModal(False)
+ dialog.show()
+ qapp.processEvents()
+ dialog.setColormap(colormap)
+ assert colormap.getVMin() is not None
+ dialog._minValue.sigAutoScaleChanged.emit(True)
+ assert colormap.getVMin() is None
+ qapp_utils.mouseClick(
+ widget=dialog._buttonsNonModal.button(qt.QDialogButtonBox.Reset),
+ button=qt.Qt.LeftButton,
+ )
+ assert colormap.getVMin() is not None
+ dialog.close()
+
+
+def testGUIClose(qapp, qWidgetFactory):
+ """Make sure the colormap is modify if go through reject"""
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ assert colormap.isAutoscale() is False
+ qapp.processEvents()
+
+ dialog.setColormap(colormap)
+ assert colormap.getVMin() is not None
+ dialog._minValue.sigAutoScaleChanged.emit(True)
+ assert colormap.getVMin() is None
+ dialog.close()
+ qapp.processEvents()
+ assert colormap.getVMin() is None
+
+
+@pytest.mark.parametrize("norm", Colormap.NORMALIZATIONS)
+@pytest.mark.parametrize("autoscale", (True, False))
+def testSetColormapIsCorrect(norm, autoscale, qapp, qWidgetFactory):
+ """Make sure the interface fir the colormap when set a new colormap"""
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ colormap.setName("red")
+ if autoscale is True:
+ colormap.setVRange(None, None)
+ else:
+ colormap.setVRange(11, 101)
+ colormap.setNormalization(norm)
+ dialog.setColormap(colormap)
+ qapp.processEvents()
-@pytest.fixture
-def colormapDialog(qapp):
- dialog = ColormapDialog.ColormapDialog()
- dialog.setAttribute(qt.Qt.WA_DeleteOnClose)
- yield weakref.proxy(dialog)
+ assert dialog._comboBoxNormalization.currentData() == norm
+ assert dialog._comboBoxColormap.getCurrentName() == "red"
+ assert dialog._minValue.isAutoChecked() == autoscale
+ assert dialog._maxValue.isAutoChecked() == autoscale
+ if autoscale is False:
+ assert dialog._minValue.getValue() == 11
+ assert dialog._maxValue.getValue() == 101
+ assert dialog._minValue.isEnabled()
+ assert dialog._maxValue.isEnabled()
+ else:
+ assert dialog._minValue._numVal.isReadOnly()
+ assert dialog._maxValue._numVal.isReadOnly()
+
+
+def testColormapDel(qapp, qWidgetFactory):
+ """Check behavior if the colormap has been deleted outside. For now
+ we make sure the colormap is still running and nothing more"""
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ colormap = Colormap(name="gray")
+ dialog.setColormap(colormap)
qapp.processEvents()
- from silx.gui.qt import inspect
- if inspect.isValid(dialog):
- dialog.close()
- del dialog
- qapp.processEvents()
+ colormap = None
+ assert dialog.getColormap() is None
+ dialog._comboBoxColormap._setCurrentName("blue")
-@pytest.fixture
-def colormap_class_attr(request, qapp_utils, colormap, colormapDialog):
- """Provides few fixtures to a class as class attribute
- Used as transition from TestCase to pytest
+def testColormapEditedOutside(qapp, qWidgetFactory):
+ """Make sure the GUI is still up to date if the colormap is modified
+ outside"""
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ dialog.setColormap(colormap)
+ qapp.processEvents()
+
+ colormap.setName("red")
+ assert dialog._comboBoxColormap.getCurrentName() == "red"
+ colormap.setNormalization(Colormap.LOGARITHM)
+ assert dialog._comboBoxNormalization.currentData() == Colormap.LOGARITHM
+ colormap.setVRange(11, 201)
+ assert dialog._minValue.getValue() == 11
+ assert dialog._maxValue.getValue() == 201
+ assert not (dialog._minValue._numVal.isReadOnly())
+ assert not (dialog._maxValue._numVal.isReadOnly())
+ assert not (dialog._minValue.isAutoChecked())
+ assert not (dialog._maxValue.isAutoChecked())
+ colormap.setVRange(None, None)
+ qapp.processEvents()
+
+ assert dialog._minValue._numVal.isReadOnly()
+ assert dialog._maxValue._numVal.isReadOnly()
+ assert dialog._minValue.isAutoChecked()
+ assert dialog._maxValue.isAutoChecked()
+
+
+def testSetColormapScenario(qWidgetFactory):
+ """Test of a simple scenario of a colormap dialog editing several
+ colormap"""
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ colormap = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ colormap1 = Colormap(name="gray", vmin=10.0, vmax=20.0, normalization="linear")
+ colormap2 = Colormap(name="red", vmin=10.0, vmax=20.0, normalization="log")
+ colormap3 = Colormap(name="blue", vmin=None, vmax=None, normalization="linear")
+
+ dialog.setColormap(colormap)
+ dialog.setColormap(colormap1)
+ del colormap1
+ dialog.setColormap(colormap2)
+ del colormap2
+ dialog.setColormap(colormap3)
+ del colormap3
+
+
+def testNotPreferredColormap(qapp, qWidgetFactory):
+ """Test that the colormapEditor is able to edit a colormap which is not
+ part of the 'prefered colormap'
"""
- request.cls.qapp_utils = qapp_utils
- request.cls.colormap = colormap
- request.cls.colormapDiag = colormapDialog
- yield
- request.cls.qapp_utils = None
- request.cls.colormap = None
- request.cls.colormapDiag = None
-
-
-@pytest.mark.usefixtures("colormap_class_attr")
-class TestColormapDialog(TestCaseQt, ParametricTestCase):
-
- def testGUIEdition(self):
- """Make sure the colormap is correctly edited and also that the
- modification are correctly updated if an other colormapdialog is
- editing the same colormap"""
- colormapDiag2 = ColormapDialog.ColormapDialog()
- colormapDiag2.setAttribute(qt.Qt.WA_DeleteOnClose)
- colormapDiag2.setColormap(self.colormap)
- colormapDiag2.show()
- self.colormapDiag.setColormap(self.colormap)
- self.colormapDiag.show()
- self.qapp.processEvents()
-
- self.colormapDiag._comboBoxColormap._setCurrentName('red')
- self.colormapDiag._comboBoxNormalization.setCurrentIndex(
- self.colormapDiag._comboBoxNormalization.findData(Colormap.LOGARITHM))
- self.assertTrue(self.colormap.getName() == 'red')
- self.assertTrue(self.colormapDiag.getColormap().getName() == 'red')
- self.assertTrue(self.colormap.getNormalization() == 'log')
- self.assertTrue(self.colormap.getVMin() == 10)
- self.assertTrue(self.colormap.getVMax() == 20)
- # checked second colormap dialog
- self.assertTrue(colormapDiag2._comboBoxColormap.getCurrentName() == 'red')
- self.assertEqual(colormapDiag2._comboBoxNormalization.currentData(),
- Colormap.LOGARITHM)
- self.assertTrue(int(colormapDiag2._minValue.getValue()) == 10)
- self.assertTrue(int(colormapDiag2._maxValue.getValue()) == 20)
- colormapDiag2.close()
- del colormapDiag2
- self.qapp.processEvents()
-
- def testGUIModalOk(self):
- """Make sure the colormap is modified if gone through accept"""
- assert self.colormap.isAutoscale() is False
- self.colormapDiag.setModal(True)
- self.colormapDiag.show()
- self.qapp.processEvents()
- self.colormapDiag.setColormap(self.colormap)
- self.assertTrue(self.colormap.getVMin() is not None)
- self.colormapDiag._minValue.sigAutoScaleChanged.emit(True)
- self.assertTrue(self.colormap.getVMin() is None)
- self.colormapDiag._maxValue.sigAutoScaleChanged.emit(True)
- self.mouseClick(
- widget=self.colormapDiag._buttonsModal.button(qt.QDialogButtonBox.Ok),
- button=qt.Qt.LeftButton
- )
- self.assertTrue(self.colormap.getVMin() is None)
- self.assertTrue(self.colormap.getVMax() is None)
- self.assertTrue(self.colormap.isAutoscale() is True)
-
- def testGUIModalCancel(self):
- """Make sure the colormap is not modified if gone through reject"""
- assert self.colormap.isAutoscale() is False
- self.colormapDiag.setModal(True)
- self.colormapDiag.show()
- self.qapp.processEvents()
- self.colormapDiag.setColormap(self.colormap)
- self.assertTrue(self.colormap.getVMin() is not None)
- self.colormapDiag._minValue.sigAutoScaleChanged.emit(True)
- self.assertTrue(self.colormap.getVMin() is None)
- self.mouseClick(
- widget=self.colormapDiag._buttonsModal.button(qt.QDialogButtonBox.Cancel),
- button=qt.Qt.LeftButton
- )
- self.assertTrue(self.colormap.getVMin() is not None)
-
- def testGUIModalClose(self):
- assert self.colormap.isAutoscale() is False
- self.colormapDiag.setModal(False)
- self.colormapDiag.show()
- self.qapp.processEvents()
- self.colormapDiag.setColormap(self.colormap)
- self.assertTrue(self.colormap.getVMin() is not None)
- self.colormapDiag._minValue.sigAutoScaleChanged.emit(True)
- self.assertTrue(self.colormap.getVMin() is None)
- self.mouseClick(
- widget=self.colormapDiag._buttonsNonModal.button(qt.QDialogButtonBox.Close),
- button=qt.Qt.LeftButton
- )
- self.assertTrue(self.colormap.getVMin() is None)
-
- def testGUIModalReset(self):
- assert self.colormap.isAutoscale() is False
- self.colormapDiag.setModal(False)
- self.colormapDiag.show()
- self.qapp.processEvents()
- self.colormapDiag.setColormap(self.colormap)
- self.assertTrue(self.colormap.getVMin() is not None)
- self.colormapDiag._minValue.sigAutoScaleChanged.emit(True)
- self.assertTrue(self.colormap.getVMin() is None)
- self.mouseClick(
- widget=self.colormapDiag._buttonsNonModal.button(qt.QDialogButtonBox.Reset),
- button=qt.Qt.LeftButton
- )
- self.assertTrue(self.colormap.getVMin() is not None)
- self.colormapDiag.close()
-
- def testGUIClose(self):
- """Make sure the colormap is modify if go through reject"""
- assert self.colormap.isAutoscale() is False
- self.colormapDiag.show()
- self.qapp.processEvents()
- self.colormapDiag.setColormap(self.colormap)
- self.assertTrue(self.colormap.getVMin() is not None)
- self.colormapDiag._minValue.sigAutoScaleChanged.emit(True)
- self.assertTrue(self.colormap.getVMin() is None)
- self.colormapDiag.close()
- self.qapp.processEvents()
- self.assertTrue(self.colormap.getVMin() is None)
-
- def testSetColormapIsCorrect(self):
- """Make sure the interface fir the colormap when set a new colormap"""
- self.colormap.setName('red')
- self.colormapDiag.show()
- self.qapp.processEvents()
- for norm in (Colormap.NORMALIZATIONS):
- for autoscale in (True, False):
- if autoscale is True:
- self.colormap.setVRange(None, None)
- else:
- self.colormap.setVRange(11, 101)
- self.colormap.setNormalization(norm)
- with self.subTest(colormap=self.colormap):
- self.colormapDiag.setColormap(self.colormap)
- self.assertEqual(
- self.colormapDiag._comboBoxNormalization.currentData(), norm)
- self.assertTrue(
- self.colormapDiag._comboBoxColormap.getCurrentName() == 'red')
- self.assertTrue(
- self.colormapDiag._minValue.isAutoChecked() == autoscale)
- self.assertTrue(
- self.colormapDiag._maxValue.isAutoChecked() == autoscale)
- if autoscale is False:
- self.assertTrue(self.colormapDiag._minValue.getValue() == 11)
- self.assertTrue(self.colormapDiag._maxValue.getValue() == 101)
- self.assertTrue(self.colormapDiag._minValue.isEnabled())
- self.assertTrue(self.colormapDiag._maxValue.isEnabled())
- else:
- self.assertTrue(self.colormapDiag._minValue._numVal.isReadOnly())
- self.assertTrue(self.colormapDiag._maxValue._numVal.isReadOnly())
-
- def testColormapDel(self):
- """Check behavior if the colormap has been deleted outside. For now
- we make sure the colormap is still running and nothing more"""
- colormap = Colormap(name='gray')
- self.colormapDiag.setColormap(colormap)
- self.colormapDiag.show()
- self.qapp.processEvents()
- colormap = None
- self.assertTrue(self.colormapDiag.getColormap() is None)
- self.colormapDiag._comboBoxColormap._setCurrentName('blue')
-
- def testColormapEditedOutside(self):
- """Make sure the GUI is still up to date if the colormap is modified
- outside"""
- self.colormapDiag.setColormap(self.colormap)
- self.colormapDiag.show()
- self.qapp.processEvents()
-
- self.colormap.setName('red')
- self.assertTrue(
- self.colormapDiag._comboBoxColormap.getCurrentName() == 'red')
- self.colormap.setNormalization(Colormap.LOGARITHM)
- self.assertEqual(self.colormapDiag._comboBoxNormalization.currentData(),
- Colormap.LOGARITHM)
- self.colormap.setVRange(11, 201)
- self.assertTrue(self.colormapDiag._minValue.getValue() == 11)
- self.assertTrue(self.colormapDiag._maxValue.getValue() == 201)
- self.assertFalse(self.colormapDiag._minValue._numVal.isReadOnly())
- self.assertFalse(self.colormapDiag._maxValue._numVal.isReadOnly())
- self.assertFalse(self.colormapDiag._minValue.isAutoChecked())
- self.assertFalse(self.colormapDiag._maxValue.isAutoChecked())
- self.colormap.setVRange(None, None)
- self.qapp.processEvents()
- self.assertTrue(self.colormapDiag._minValue._numVal.isReadOnly())
- self.assertTrue(self.colormapDiag._maxValue._numVal.isReadOnly())
- self.assertTrue(self.colormapDiag._minValue.isAutoChecked())
- self.assertTrue(self.colormapDiag._maxValue.isAutoChecked())
-
- def testSetColormapScenario(self):
- """Test of a simple scenario of a colormap dialog editing several
- colormap"""
- colormap1 = Colormap(name='gray', vmin=10.0, vmax=20.0,
- normalization='linear')
- colormap2 = Colormap(name='red', vmin=10.0, vmax=20.0,
- normalization='log')
- colormap3 = Colormap(name='blue', vmin=None, vmax=None,
- normalization='linear')
- self.colormapDiag.setColormap(self.colormap)
- self.colormapDiag.setColormap(colormap1)
- del colormap1
- self.colormapDiag.setColormap(colormap2)
- del colormap2
- self.colormapDiag.setColormap(colormap3)
- del colormap3
-
- def testNotPreferredColormap(self):
- """Test that the colormapEditor is able to edit a colormap which is not
- part of the 'prefered colormap'
- """
- def getFirstNotPreferredColormap():
- cms = Colormap.getSupportedColormaps()
- preferred = preferredColormaps()
- for cm in cms:
- if cm not in preferred:
- return cm
- return None
-
- colormapName = getFirstNotPreferredColormap()
- assert colormapName is not None
- colormap = Colormap(name=colormapName)
- self.colormapDiag.setColormap(colormap)
- self.colormapDiag.show()
- self.qapp.processEvents()
- cb = self.colormapDiag._comboBoxColormap
- self.assertTrue(cb.getCurrentName() == colormapName)
- cb.setCurrentIndex(0)
- index = cb.findLutName(colormapName)
- assert index != 0 # if 0 then the rest of the test has no sense
- cb.setCurrentIndex(index)
- self.assertTrue(cb.getCurrentName() == colormapName)
-
- def testColormapEditableMode(self):
- """Test that the colormapDialog is correctly updated when changing the
- colormap editable status"""
- colormap = Colormap(normalization='linear', vmin=1.0, vmax=10.0)
- self.colormapDiag.show()
- self.qapp.processEvents()
- self.colormapDiag.setColormap(colormap)
- for editable in (True, False):
- with self.subTest(editable=editable):
- colormap.setEditable(editable)
- self.assertTrue(
- self.colormapDiag._comboBoxColormap.isEnabled() is editable)
- self.assertTrue(
- self.colormapDiag._minValue.isEnabled() is editable)
- self.assertTrue(
- self.colormapDiag._maxValue.isEnabled() is editable)
- self.assertTrue(
- self.colormapDiag._comboBoxNormalization.isEnabled() is editable)
-
- # Make sure the reset button is also set to enable when edition mode is
- # False
- self.colormapDiag.setModal(False)
- colormap.setEditable(True)
- self.colormapDiag._comboBoxNormalization.setCurrentIndex(
- self.colormapDiag._comboBoxNormalization.findData(Colormap.LOGARITHM))
- resetButton = self.colormapDiag._buttonsNonModal.button(qt.QDialogButtonBox.Reset)
- self.assertTrue(resetButton.isEnabled())
- colormap.setEditable(False)
- self.assertFalse(resetButton.isEnabled())
-
- def testImageData(self):
- data = numpy.random.rand(5, 5)
- self.colormapDiag.setData(data)
-
- def testEmptyData(self):
- data = numpy.empty((10, 0))
- self.colormapDiag.setData(data)
-
- def testNoneData(self):
- data = numpy.random.rand(5, 5)
- self.colormapDiag.setData(data)
- self.colormapDiag.setData(None)
-
- def testImageItem(self):
- """Check that an ImageData plot item can be used"""
- dialog = self.colormapDiag
- colormap = Colormap(name='gray', vmin=None, vmax=None)
- data = numpy.arange(3**2).reshape(3, 3)
- item = ImageData()
- item.setData(data, copy=False)
-
- dialog.setColormap(colormap)
- dialog.show()
- self.qapp.processEvents()
- dialog.setItem(item)
- vrange = dialog._getFiniteColormapRange()
- self.assertEqual(vrange, (0, 8))
-
- def testItemDel(self):
- """Check that the plot items are not hard linked to the dialog"""
- dialog = self.colormapDiag
- colormap = Colormap(name='gray', vmin=None, vmax=None)
- data = numpy.arange(3**2).reshape(3, 3)
- item = ImageData()
- item.setData(data, copy=False)
-
- dialog.setColormap(colormap)
- dialog.show()
- self.qapp.processEvents()
- dialog.setItem(item)
- previousRange = dialog._getFiniteColormapRange()
- del item
- vrange = dialog._getFiniteColormapRange()
- self.assertNotEqual(vrange, previousRange)
-
- def testDataDel(self):
- """Check that the data are not hard linked to the dialog"""
- dialog = self.colormapDiag
- colormap = Colormap(name='gray', vmin=None, vmax=None)
- data = numpy.arange(5)
-
- dialog.setColormap(colormap)
- dialog.show()
- self.qapp.processEvents()
- dialog.setData(data)
- previousRange = dialog._getFiniteColormapRange()
- del data
- vrange = dialog._getFiniteColormapRange()
- self.assertNotEqual(vrange, previousRange)
-
- def testDeleteWhileExec(self):
- colormapDiag = self.colormapDiag
- self.colormapDiag = None
- qt.QTimer.singleShot(1000, colormapDiag.deleteLater)
- result = colormapDiag.exec()
- self.assertEqual(result, 0)
+
+ def getFirstNotPreferredColormap():
+ cms = Colormap.getSupportedColormaps()
+ preferred = preferredColormaps()
+ for cm in cms:
+ if cm not in preferred:
+ return cm
+ return None
+
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ colormapName = getFirstNotPreferredColormap()
+ assert colormapName is not None
+ colormap = Colormap(name=colormapName)
+ dialog.setColormap(colormap)
+ qapp.processEvents()
+
+ cb = dialog._comboBoxColormap
+ assert cb.getCurrentName() == colormapName
+ cb.setCurrentIndex(0)
+ index = cb.findLutName(colormapName)
+ assert index != 0 # if 0 then the rest of the test has no sense
+ cb.setCurrentIndex(index)
+ assert cb.getCurrentName() == colormapName
+
+
+def testColormapEditableMode(qWidgetFactory):
+ """Test that the colormapDialog is correctly updated when changing the
+ colormap editable status"""
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ colormap = Colormap(normalization="linear", vmin=1.0, vmax=10.0)
+
+ dialog.setColormap(colormap)
+
+ for editable in (True, False):
+ colormap.setEditable(editable)
+ assert dialog._comboBoxColormap.isEnabled() is editable
+ assert dialog._minValue.isEnabled() is editable
+ assert dialog._maxValue.isEnabled() is editable
+ assert dialog._comboBoxNormalization.isEnabled() is editable
+
+ # Make sure the reset button is also set to enable when edition mode is
+ # False
+ dialog.setModal(False)
+ colormap.setEditable(True)
+ dialog._comboBoxNormalization.setCurrentIndex(
+ dialog._comboBoxNormalization.findData(Colormap.LOGARITHM)
+ )
+ resetButton = dialog._buttonsNonModal.button(qt.QDialogButtonBox.Reset)
+ assert resetButton.isEnabled()
+ colormap.setEditable(False)
+ assert not (resetButton.isEnabled())
+
+
+def testImageData(qWidgetFactory):
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ data = numpy.random.rand(5, 5)
+ dialog.setData(data)
+
+
+def testEmptyData(qWidgetFactory):
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ data = numpy.empty((10, 0))
+ dialog.setData(data)
+
+
+def testNoneData(qWidgetFactory):
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ data = numpy.random.rand(5, 5)
+ dialog.setData(data)
+ dialog.setData(None)
+
+
+def testImageItem(qapp, qWidgetFactory):
+ """Check that an ImageData plot item can be used"""
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ colormap = Colormap(name="gray", vmin=None, vmax=None)
+ data = numpy.arange(3**2).reshape(3, 3)
+ item = ImageData()
+ item.setData(data, copy=False)
+
+ dialog.setColormap(colormap)
+ qapp.processEvents()
+
+ dialog.setItem(item)
+ vrange = dialog._getFiniteColormapRange()
+ assert vrange == (0, 8)
+
+
+def testItemDel(qapp, qWidgetFactory):
+ """Check that the plot items are not hard linked to the dialog"""
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ colormap = Colormap(name="gray", vmin=None, vmax=None)
+ data = numpy.arange(3**2).reshape(3, 3)
+ item = ImageData()
+ item.setData(data, copy=False)
+
+ dialog.setColormap(colormap)
+ dialog.show()
+ qapp.processEvents()
+ dialog.setItem(item)
+ previousRange = dialog._getFiniteColormapRange()
+ del item
+ vrange = dialog._getFiniteColormapRange()
+ assert vrange != previousRange
+
+
+def testDataDel(qapp, qWidgetFactory):
+ """Check that the data are not hard linked to the dialog"""
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ colormap = Colormap(name="gray", vmin=None, vmax=None)
+ data = numpy.arange(5)
+
+ dialog.setColormap(colormap)
+ qapp.processEvents()
+
+ dialog.setData(data)
+ previousRange = dialog._getFiniteColormapRange()
+ del data
+ vrange = dialog._getFiniteColormapRange()
+ assert vrange != previousRange
+
+
+def testDeleteWhileExec(qWidgetFactory):
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+ qt.QTimer.singleShot(1000, dialog.deleteLater)
+ result = dialog.exec()
+ assert result == 0
+
+
+def testUpdateImageData(qapp, qWidgetFactory):
+ """Test that range/histogram takes into account item updates"""
+ dialog = qWidgetFactory(ColormapDialog.ColormapDialog)
+
+ item = ImageData()
+ item.setColormap(Colormap())
+ dialog.setItem(item)
+ dialog.setColormap(item.getColormap())
+ qapp.processEvents()
+
+ assert dialog._histoWidget.getFiniteRange() == (0, 1)
+
+ item.setData([(1, 2), (3, 4)])
+
+ assert dialog._histoWidget.getFiniteRange() == (1, 4)
diff --git a/src/silx/gui/dialog/test/test_datafiledialog.py b/src/silx/gui/dialog/test/test_datafiledialog.py
index 32d75c2..887ff1c 100644
--- a/src/silx/gui/dialog/test/test_datafiledialog.py
+++ b/src/silx/gui/dialog/test/test_datafiledialog.py
@@ -28,7 +28,6 @@ __license__ = "MIT"
__date__ = "08/03/2019"
-import unittest
import tempfile
import numpy
import shutil
@@ -65,7 +64,7 @@ def setUpModule():
f["complex_image"] = data * 1j
f["group/image"] = data
f["nxdata/foo"] = 10
- f["nxdata"].attrs["NX_class"] = u"NXdata"
+ f["nxdata"].attrs["NX_class"] = "NXdata"
f.close()
directory = os.path.join(_tmpDirectory, "data")
@@ -78,7 +77,7 @@ def setUpModule():
f["complex_image"] = data * 1j
f["group/image"] = data
f["nxdata/foo"] = 10
- f["nxdata"].attrs["NX_class"] = u"NXdata"
+ f["nxdata"].attrs["NX_class"] = "NXdata"
f.close()
filename = _tmpDirectory + "/badformat.h5"
@@ -99,7 +98,6 @@ def tearDownModule():
class _UtilsMixin(object):
-
def createDialog(self):
self._deleteDialog()
self._dialog = self._createDialog()
@@ -139,7 +137,6 @@ class _UtilsMixin(object):
class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
-
def tearDown(self):
self._deleteDialog()
testutils.TestCaseQt.tearDown(self)
@@ -219,7 +216,11 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
# select, then double click on the file
- index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/group"])
+ index = (
+ browser.rootIndex()
+ .model()
+ .indexFromH5Object(dialog._AbstractDataFileDialog__h5["/group"])
+ )
browser.selectIndex(index)
browser.activated.emit(index)
self.qWaitForPendingActions(dialog)
@@ -249,7 +250,11 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
# select, then double click on the file
- index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/scalar"])
+ index = (
+ browser.rootIndex()
+ .model()
+ .indexFromH5Object(dialog._AbstractDataFileDialog__h5["/scalar"])
+ )
browser.selectIndex(index)
browser.activated.emit(index)
self.qWaitForPendingActions(dialog)
@@ -276,12 +281,16 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
path = silx.io.url.DataUrl(file_path=filename, data_path="/group/image").path()
dialog.selectUrl(path)
self.qWaitForPendingActions(dialog)
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/image").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group/image"
+ ).path()
self.assertSamePath(url.text(), path)
# test
self.mouseClick(toParentButton, qt.Qt.LeftButton)
self.qWaitForPendingActions(dialog)
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/"
+ ).path()
self.assertSamePath(url.text(), path)
self.mouseClick(toParentButton, qt.Qt.LeftButton)
@@ -303,7 +312,9 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
filename = _tmpDirectory + "/data.h5"
# init state
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/image").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group/image"
+ ).path()
dialog.selectUrl(path)
self.qWaitForPendingActions(dialog)
self.assertSamePath(url.text(), path)
@@ -311,7 +322,9 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# test
self.mouseClick(button, qt.Qt.LeftButton)
self.qWaitForPendingActions(dialog)
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/"
+ ).path()
self.assertSamePath(url.text(), path)
# self.assertFalse(button.isEnabled())
@@ -329,7 +342,9 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
path = silx.io.url.DataUrl(file_path=filename, data_path="/group/image").path()
dialog.selectUrl(path)
self.qWaitForPendingActions(dialog)
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/image").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group/image"
+ ).path()
self.assertSamePath(url.text(), path)
self.assertTrue(button.isEnabled())
# test
@@ -348,8 +363,12 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForWindowExposed(dialog)
url = testutils.findChildren(dialog, qt.QLineEdit, name="url")[0]
- forwardAction = testutils.findChildren(dialog, qt.QAction, name="forwardAction")[0]
- backwardAction = testutils.findChildren(dialog, qt.QAction, name="backwardAction")[0]
+ forwardAction = testutils.findChildren(
+ dialog, qt.QAction, name="forwardAction"
+ )[0]
+ backwardAction = testutils.findChildren(
+ dialog, qt.QAction, name="backwardAction"
+ )[0]
filename = _tmpDirectory + "/data.h5"
dialog.setDirectory(_tmpDirectory)
@@ -358,10 +377,14 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# Then we feed the history using selectPath
dialog.selectUrl(filename)
self.qWaitForPendingActions(dialog)
- path2 = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/").path()
+ path2 = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/"
+ ).path()
dialog.selectUrl(path2)
self.qWaitForPendingActions(dialog)
- path3 = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group").path()
+ path3 = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group"
+ ).path()
dialog.selectUrl(path3)
self.qWaitForPendingActions(dialog)
self.assertFalse(forwardAction.isEnabled())
@@ -388,7 +411,11 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# init state
filename = _tmpDirectory + "/singleimage.edf"
- url = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/scan_0/instrument/detector_0/data")
+ url = silx.io.url.DataUrl(
+ scheme="silx",
+ file_path=filename,
+ data_path="/scan_0/instrument/detector_0/data",
+ )
dialog.selectUrl(url.path())
self.assertEqual(dialog._selectedData().shape, (100, 100))
self.assertSamePath(dialog.selectedFile(), filename)
@@ -401,7 +428,9 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# init state
filename = _tmpDirectory + "/data.h5"
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/image").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/image"
+ ).path()
dialog.selectUrl(path)
# test
self.assertEqual(dialog._selectedData().shape, (100, 100))
@@ -415,7 +444,9 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# init state
filename = _tmpDirectory + "/data.h5"
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/scalar").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/scalar"
+ ).path()
dialog.selectUrl(path)
# test
self.assertEqual(dialog._selectedData()[()], 10)
@@ -464,7 +495,9 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
browser = testutils.findChildren(dialog, qt.QWidget, name="browser")[0]
filename = _tmpDirectory + "/data.h5"
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/"
+ ).path()
index = browser.rootIndex().model().index(filename)
# click
browser.selectIndex(index)
@@ -508,11 +541,12 @@ class TestDataFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForWindowExposed(dialog)
dialog.selectUrl(_tmpDirectory)
self.qWaitForPendingActions(dialog)
- self.assertEqual(self._countSelectableItems(browser.model(), browser.rootIndex()), 4)
+ self.assertEqual(
+ self._countSelectableItems(browser.model(), browser.rootIndex()), 4
+ )
class TestDataFileDialog_FilterDataset(testutils.TestCaseQt, _UtilsMixin):
-
def tearDown(self):
self._deleteDialog()
testutils.TestCaseQt.tearDown(self)
@@ -539,7 +573,11 @@ class TestDataFileDialog_FilterDataset(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
# select, then double click on the file
- index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/group"])
+ index = (
+ browser.rootIndex()
+ .model()
+ .indexFromH5Object(dialog._AbstractDataFileDialog__h5["/group"])
+ )
browser.selectIndex(index)
browser.activated.emit(index)
self.qWaitForPendingActions(dialog)
@@ -564,7 +602,11 @@ class TestDataFileDialog_FilterDataset(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
# select, then double click on the file
- index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/scalar"])
+ index = (
+ browser.rootIndex()
+ .model()
+ .indexFromH5Object(dialog._AbstractDataFileDialog__h5["/scalar"])
+ )
browser.selectIndex(index)
browser.activated.emit(index)
self.qWaitForPendingActions(dialog)
@@ -582,7 +624,6 @@ class TestDataFileDialog_FilterDataset(testutils.TestCaseQt, _UtilsMixin):
class TestDataFileDialog_FilterGroup(testutils.TestCaseQt, _UtilsMixin):
-
def tearDown(self):
self._deleteDialog()
testutils.TestCaseQt.tearDown(self)
@@ -609,7 +650,11 @@ class TestDataFileDialog_FilterGroup(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
# select, then double click on the file
- index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/group"])
+ index = (
+ browser.rootIndex()
+ .model()
+ .indexFromH5Object(dialog._AbstractDataFileDialog__h5["/group"])
+ )
browser.selectIndex(index)
browser.activated.emit(index)
self.qWaitForPendingActions(dialog)
@@ -641,7 +686,11 @@ class TestDataFileDialog_FilterGroup(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
# select, then double click on the file
- index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/scalar"])
+ index = (
+ browser.rootIndex()
+ .model()
+ .indexFromH5Object(dialog._AbstractDataFileDialog__h5["/scalar"])
+ )
browser.selectIndex(index)
browser.activated.emit(index)
self.qWaitForPendingActions(dialog)
@@ -651,7 +700,6 @@ class TestDataFileDialog_FilterGroup(testutils.TestCaseQt, _UtilsMixin):
class TestDataFileDialog_FilterNXdata(testutils.TestCaseQt, _UtilsMixin):
-
def tearDown(self):
self._deleteDialog()
testutils.TestCaseQt.tearDown(self)
@@ -659,7 +707,7 @@ class TestDataFileDialog_FilterNXdata(testutils.TestCaseQt, _UtilsMixin):
def _createDialog(self):
def customFilter(obj):
if "NX_class" in obj.attrs:
- return obj.attrs["NX_class"] == u"NXdata"
+ return obj.attrs["NX_class"] == "NXdata"
return False
dialog = DataFileDialog()
@@ -684,7 +732,11 @@ class TestDataFileDialog_FilterNXdata(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
# select, then double click on the file
- index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/group"])
+ index = (
+ browser.rootIndex()
+ .model()
+ .indexFromH5Object(dialog._AbstractDataFileDialog__h5["/group"])
+ )
browser.selectIndex(index)
browser.activated.emit(index)
self.qWaitForPendingActions(dialog)
@@ -711,7 +763,11 @@ class TestDataFileDialog_FilterNXdata(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
# select, then double click on the file
- index = browser.rootIndex().model().indexFromH5Object(dialog._AbstractDataFileDialog__h5["/nxdata"])
+ index = (
+ browser.rootIndex()
+ .model()
+ .indexFromH5Object(dialog._AbstractDataFileDialog__h5["/nxdata"])
+ )
browser.selectIndex(index)
browser.activated.emit(index)
self.qWaitForPendingActions(dialog)
@@ -726,7 +782,6 @@ class TestDataFileDialog_FilterNXdata(testutils.TestCaseQt, _UtilsMixin):
class TestDataFileDialogApi(testutils.TestCaseQt, _UtilsMixin):
-
def tearDown(self):
self._deleteDialog()
testutils.TestCaseQt.tearDown(self)
@@ -779,46 +834,50 @@ class TestDataFileDialogApi(testutils.TestCaseQt, _UtilsMixin):
print()
print("\\\n".join(strings))
- STATE_VERSION1_QT4 = b''\
- b'\x00\x00\x00Z\x00s\x00i\x00l\x00x\x00.\x00g\x00u\x00i\x00.\x00'\
- b'd\x00i\x00a\x00l\x00o\x00g\x00.\x00D\x00a\x00t\x00a\x00F\x00i'\
- b'\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00D\x00a\x00t\x00'\
- b'a\x00F\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00\x00\x00'\
- b'\x01\x00\x00\x00\x0C\x00\x00\x00\x00"\x00\x00\x00\xFF\x00\x00'\
- b'\x00\x00\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'\
- b'\xFF\xFF\x01\x00\x00\x00\x06\x01\x00\x00\x00\x01\x00\x00\x00\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C\x00\x00\x00\x00'\
- b'}\x00\x00\x00\x0E\x00B\x00r\x00o\x00w\x00s\x00e\x00r\x00\x00\x00'\
- b'\x01\x00\x00\x00\x0C\x00\x00\x00\x00Z\x00\x00\x00\xFF\x00\x00'\
- b'\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
- b'\x00\x01\x90\x00\x00\x00\x04\x01\x01\x00\x00\x00\x00\x00\x00\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00d\xFF\xFF\xFF\xFF\x00\x00\x00\x81'\
- b'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x90\x00\x00\x00\x04'\
- b'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00'\
- b'\x01\xFF\xFF\xFF\xFF'
+ STATE_VERSION1_QT4 = (
+ b""
+ b"\x00\x00\x00Z\x00s\x00i\x00l\x00x\x00.\x00g\x00u\x00i\x00.\x00"
+ b"d\x00i\x00a\x00l\x00o\x00g\x00.\x00D\x00a\x00t\x00a\x00F\x00i"
+ b"\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00D\x00a\x00t\x00"
+ b"a\x00F\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00\x00\x00"
+ b'\x01\x00\x00\x00\x0C\x00\x00\x00\x00"\x00\x00\x00\xFF\x00\x00'
+ b"\x00\x00\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ b"\xFF\xFF\x01\x00\x00\x00\x06\x01\x00\x00\x00\x01\x00\x00\x00\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C\x00\x00\x00\x00"
+ b"}\x00\x00\x00\x0E\x00B\x00r\x00o\x00w\x00s\x00e\x00r\x00\x00\x00"
+ b"\x01\x00\x00\x00\x0C\x00\x00\x00\x00Z\x00\x00\x00\xFF\x00\x00"
+ b"\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x01\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ b"\x00\x01\x90\x00\x00\x00\x04\x01\x01\x00\x00\x00\x00\x00\x00\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00d\xFF\xFF\xFF\xFF\x00\x00\x00\x81"
+ b"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x90\x00\x00\x00\x04"
+ b"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00"
+ b"\x01\xFF\xFF\xFF\xFF"
+ )
"""Serialized state on Qt4. Generated using :meth:`printState`"""
- STATE_VERSION1_QT5 = b''\
- b'\x00\x00\x00Z\x00s\x00i\x00l\x00x\x00.\x00g\x00u\x00i\x00.\x00'\
- b'd\x00i\x00a\x00l\x00o\x00g\x00.\x00D\x00a\x00t\x00a\x00F\x00i'\
- b'\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00D\x00a\x00t\x00'\
- b'a\x00F\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00\x00\x00'\
- b'\x01\x00\x00\x00\x0C\x00\x00\x00\x00#\x00\x00\x00\xFF\x00\x00'\
- b'\x00\x01\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF'\
- b'\xFF\xFF\x01\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x01\x00\x00\x00\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C\x00\x00\x00'\
- b'\x00\xAA\x00\x00\x00\x0E\x00B\x00r\x00o\x00w\x00s\x00e\x00r\x00'\
- b'\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00\x87\x00\x00\x00\xFF'\
- b'\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00'\
- b'\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
- b'\x00\x00\x00\x01\x90\x00\x00\x00\x04\x01\x01\x00\x00\x00\x00\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xFF\xFF\xFF\xFF\x00\x00'\
- b'\x00\x81\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00d\x00\x00'\
- b'\x00\x01\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00'\
- b'\x00\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00'\
- b'\x00d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\xE8\x00\xFF'\
- b'\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x01'
+ STATE_VERSION1_QT5 = (
+ b""
+ b"\x00\x00\x00Z\x00s\x00i\x00l\x00x\x00.\x00g\x00u\x00i\x00.\x00"
+ b"d\x00i\x00a\x00l\x00o\x00g\x00.\x00D\x00a\x00t\x00a\x00F\x00i"
+ b"\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00D\x00a\x00t\x00"
+ b"a\x00F\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00\x00\x00"
+ b"\x01\x00\x00\x00\x0C\x00\x00\x00\x00#\x00\x00\x00\xFF\x00\x00"
+ b"\x00\x01\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ b"\xFF\xFF\x01\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x01\x00\x00\x00\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C\x00\x00\x00"
+ b"\x00\xAA\x00\x00\x00\x0E\x00B\x00r\x00o\x00w\x00s\x00e\x00r\x00"
+ b"\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00\x87\x00\x00\x00\xFF"
+ b"\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00"
+ b"\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ b"\x00\x00\x00\x01\x90\x00\x00\x00\x04\x01\x01\x00\x00\x00\x00\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xFF\xFF\xFF\xFF\x00\x00"
+ b"\x00\x81\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00\x00d\x00\x00"
+ b"\x00\x01\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00"
+ b"\x00\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00"
+ b"\x00d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03\xE8\x00\xFF"
+ b"\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00\x00\x00\x01"
+ )
"""Serialized state on Qt5. Generated using :meth:`printState`"""
def testAvoidRestoreRegression_Version1(self):
@@ -903,7 +962,9 @@ class TestDataFileDialogApi(testutils.TestCaseQt, _UtilsMixin):
browser = testutils.findChildren(dialog, qt.QWidget, name="browser")[0]
filename = _tmpDirectory + "/data.h5"
- url = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/foobar")
+ url = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group/foobar"
+ )
dialog.selectUrl(url.path())
self.qWaitForPendingActions(dialog)
self.assertIsNotNone(dialog._selectedData())
diff --git a/src/silx/gui/dialog/test/test_imagefiledialog.py b/src/silx/gui/dialog/test/test_imagefiledialog.py
index 79c12ed..9d2c414 100644
--- a/src/silx/gui/dialog/test/test_imagefiledialog.py
+++ b/src/silx/gui/dialog/test/test_imagefiledialog.py
@@ -28,7 +28,6 @@ __license__ = "MIT"
__date__ = "08/03/2019"
-import unittest
import tempfile
import numpy
import shutil
@@ -106,7 +105,6 @@ def tearDownModule():
class _UtilsMixin(object):
-
def createDialog(self):
self._deleteDialog()
self._dialog = self._createDialog()
@@ -146,7 +144,6 @@ class _UtilsMixin(object):
class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
-
def tearDown(self):
self._deleteDialog()
testutils.TestCaseQt.tearDown(self)
@@ -201,6 +198,9 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.assertEqual(dialog.result(), qt.QDialog.Accepted)
def testClickOnShortcut(self):
+ if qt.BINDING == "PySide6":
+ self.skipTest("Avoid segmentation fault with PySide6")
+
dialog = self.createDialog()
dialog.show()
self.qWaitForWindowExposed(dialog)
@@ -264,12 +264,16 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
path = silx.io.url.DataUrl(file_path=filename, data_path="/group/image").path()
dialog.selectUrl(path)
self.qWaitForPendingActions(dialog)
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/image").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group/image"
+ ).path()
self.assertSamePath(url.text(), path)
# test
self.mouseClick(toParentButton, qt.Qt.LeftButton)
self.qWaitForPendingActions(dialog)
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/"
+ ).path()
self.assertSamePath(url.text(), path)
self.mouseClick(toParentButton, qt.Qt.LeftButton)
@@ -291,7 +295,9 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
filename = _tmpDirectory + "/data.h5"
# init state
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/image").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group/image"
+ ).path()
dialog.selectUrl(path)
self.qWaitForPendingActions(dialog)
self.assertSamePath(url.text(), path)
@@ -299,7 +305,9 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# test
self.mouseClick(button, qt.Qt.LeftButton)
self.qWaitForPendingActions(dialog)
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/"
+ ).path()
self.assertSamePath(url.text(), path)
# self.assertFalse(button.isEnabled())
@@ -317,7 +325,9 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
path = silx.io.url.DataUrl(file_path=filename, data_path="/group/image").path()
dialog.selectUrl(path)
self.qWaitForPendingActions(dialog)
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/image").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group/image"
+ ).path()
self.assertSamePath(url.text(), path)
self.assertTrue(button.isEnabled())
# test
@@ -336,8 +346,12 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForWindowExposed(dialog)
url = testutils.findChildren(dialog, qt.QLineEdit, name="url")[0]
- forwardAction = testutils.findChildren(dialog, qt.QAction, name="forwardAction")[0]
- backwardAction = testutils.findChildren(dialog, qt.QAction, name="backwardAction")[0]
+ forwardAction = testutils.findChildren(
+ dialog, qt.QAction, name="forwardAction"
+ )[0]
+ backwardAction = testutils.findChildren(
+ dialog, qt.QAction, name="backwardAction"
+ )[0]
filename = _tmpDirectory + "/data.h5"
dialog.setDirectory(_tmpDirectory)
@@ -346,10 +360,14 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# Then we feed the history using selectPath
dialog.selectUrl(filename)
self.qWaitForPendingActions(dialog)
- path2 = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/").path()
+ path2 = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/"
+ ).path()
dialog.selectUrl(path2)
self.qWaitForPendingActions(dialog)
- path3 = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group").path()
+ path3 = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group"
+ ).path()
dialog.selectUrl(path3)
self.qWaitForPendingActions(dialog)
self.assertFalse(forwardAction.isEnabled())
@@ -412,7 +430,9 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# init state
filename = _tmpDirectory + "/multiframe.edf"
- path = silx.io.url.DataUrl(scheme="fabio", file_path=filename, data_slice=(1,)).path()
+ path = silx.io.url.DataUrl(
+ scheme="fabio", file_path=filename, data_slice=(1,)
+ ).path()
dialog.selectUrl(path)
# test
image = dialog.selectedImage()
@@ -442,7 +462,9 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# init state
filename = _tmpDirectory + "/data.h5"
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/image").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/image"
+ ).path()
dialog.selectUrl(path)
# test
self.assertEqual(dialog.selectedImage().shape, (100, 100))
@@ -459,7 +481,9 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForPendingActions(dialog)
browser = testutils.findChildren(dialog, qt.QWidget, name="browser")[0]
filename = _tmpDirectory + "/data.h5"
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/").path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/"
+ ).path()
index = browser.rootIndex().model().index(filename)
# click
browser.selectIndex(index)
@@ -476,7 +500,9 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# init state
filename = _tmpDirectory + "/data.h5"
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/cube", data_slice=(1, )).path()
+ path = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/cube", data_slice=(1,)
+ ).path()
dialog.selectUrl(path)
# test
self.assertEqual(dialog.selectedImage().shape, (100, 100))
@@ -491,7 +517,12 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
# init state
filename = _tmpDirectory + "/data.h5"
- path = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/single_frame", data_slice=(0, )).path()
+ path = silx.io.url.DataUrl(
+ scheme="silx",
+ file_path=filename,
+ data_path="/single_frame",
+ data_slice=(0,),
+ ).path()
dialog.selectUrl(path)
# test
self.assertEqual(dialog.selectedImage().shape, (100, 100))
@@ -534,25 +565,30 @@ class TestImageFileDialogInteraction(testutils.TestCaseQt, _UtilsMixin):
self.qWaitForWindowExposed(dialog)
dialog.selectUrl(_tmpDirectory)
self.qWaitForPendingActions(dialog)
- self.assertEqual(self._countSelectableItems(browser.model(), browser.rootIndex()), 6)
+ self.assertEqual(
+ self._countSelectableItems(browser.model(), browser.rootIndex()), 6
+ )
codecName = fabio.edfimage.EdfImage.codec_name()
index = filters.indexFromCodec(codecName)
filters.setCurrentIndex(index)
filters.activated[int].emit(index)
self.qWait(50)
- self.assertEqual(self._countSelectableItems(browser.model(), browser.rootIndex()), 4)
+ self.assertEqual(
+ self._countSelectableItems(browser.model(), browser.rootIndex()), 4
+ )
codecName = fabio.fit2dmaskimage.Fit2dMaskImage.codec_name()
index = filters.indexFromCodec(codecName)
filters.setCurrentIndex(index)
filters.activated[int].emit(index)
self.qWait(50)
- self.assertEqual(self._countSelectableItems(browser.model(), browser.rootIndex()), 2)
+ self.assertEqual(
+ self._countSelectableItems(browser.model(), browser.rootIndex()), 2
+ )
class TestImageFileDialogApi(testutils.TestCaseQt, _UtilsMixin):
-
def tearDown(self):
self._deleteDialog()
testutils.TestCaseQt.tearDown(self)
@@ -606,51 +642,55 @@ class TestImageFileDialogApi(testutils.TestCaseQt, _UtilsMixin):
print()
print("\\\n".join(strings))
- STATE_VERSION1_QT4 = b''\
- b'\x00\x00\x00^\x00s\x00i\x00l\x00x\x00.\x00g\x00u\x00i\x00.\x00'\
- b'd\x00i\x00a\x00l\x00o\x00g\x00.\x00I\x00m\x00a\x00g\x00e\x00F'\
- b'\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00I\x00m\x00'\
- b'a\x00g\x00e\x00F\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g'\
- b'\x00\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00"\x00\x00\x00'\
- b'\xFF\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF'\
- b'\xFF\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x06\x01\x00\x00\x00\x01\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C\x00'\
- b'\x00\x00\x00}\x00\x00\x00\x0E\x00B\x00r\x00o\x00w\x00s\x00e\x00'\
- b'r\x00\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00Z\x00\x00\x00'\
- b'\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00'\
- b'\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
- b'\x00\x00\x00\x00\x01\x90\x00\x00\x00\x04\x01\x01\x00\x00\x00\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xFF\xFF\xFF\xFF\x00'\
- b'\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x90\x00'\
- b'\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00'\
- b'\x00\x00\x0C\x00\x00\x00\x000\x00\x00\x00\x10\x00C\x00o\x00l\x00'\
- b'o\x00r\x00m\x00a\x00p\x00\x00\x00\x01\x00\x00\x00\x08\x00g\x00'\
- b'r\x00a\x00y\x01\x01\x00\x00\x00\x06\x00l\x00o\x00g'
+ STATE_VERSION1_QT4 = (
+ b""
+ b"\x00\x00\x00^\x00s\x00i\x00l\x00x\x00.\x00g\x00u\x00i\x00.\x00"
+ b"d\x00i\x00a\x00l\x00o\x00g\x00.\x00I\x00m\x00a\x00g\x00e\x00F"
+ b"\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00I\x00m\x00"
+ b"a\x00g\x00e\x00F\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g"
+ b'\x00\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00"\x00\x00\x00'
+ b"\xFF\x00\x00\x00\x00\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ b"\xFF\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x06\x01\x00\x00\x00\x01\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C\x00"
+ b"\x00\x00\x00}\x00\x00\x00\x0E\x00B\x00r\x00o\x00w\x00s\x00e\x00"
+ b"r\x00\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00Z\x00\x00\x00"
+ b"\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00"
+ b"\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ b"\x00\x00\x00\x00\x01\x90\x00\x00\x00\x04\x01\x01\x00\x00\x00\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xFF\xFF\xFF\xFF\x00"
+ b"\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x01\x90\x00"
+ b"\x00\x00\x04\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x01\x00"
+ b"\x00\x00\x0C\x00\x00\x00\x000\x00\x00\x00\x10\x00C\x00o\x00l\x00"
+ b"o\x00r\x00m\x00a\x00p\x00\x00\x00\x01\x00\x00\x00\x08\x00g\x00"
+ b"r\x00a\x00y\x01\x01\x00\x00\x00\x06\x00l\x00o\x00g"
+ )
"""Serialized state on Qt4. Generated using :meth:`printState`"""
- STATE_VERSION1_QT5 = b''\
- b'\x00\x00\x00^\x00s\x00i\x00l\x00x\x00.\x00g\x00u\x00i\x00.\x00'\
- b'd\x00i\x00a\x00l\x00o\x00g\x00.\x00I\x00m\x00a\x00g\x00e\x00F'\
- b'\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00I\x00m\x00'\
- b'a\x00g\x00e\x00F\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g'\
- b'\x00\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00#\x00\x00\x00'\
- b'\xFF\x00\x00\x00\x01\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF'\
- b'\xFF\xFF\xFF\xFF\xFF\x01\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x01\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C'\
- b'\x00\x00\x00\x00\xAA\x00\x00\x00\x0E\x00B\x00r\x00o\x00w\x00s'\
- b'\x00e\x00r\x00\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00\x87'\
- b'\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00'\
- b'\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x01\x90\x00\x00\x00\x04\x01\x01\x00'\
- b'\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xFF\xFF'\
- b'\xFF\xFF\x00\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00'\
- b'\x00d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00'\
- b'\x01\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00\x00'\
- b'\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03'\
- b'\xE8\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00'\
- b'\x00\x0C\x00\x00\x00\x000\x00\x00\x00\x10\x00C\x00o\x00l\x00o'\
- b'\x00r\x00m\x00a\x00p\x00\x00\x00\x01\x00\x00\x00\x08\x00g\x00'\
- b'r\x00a\x00y\x01\x01\x00\x00\x00\x06\x00l\x00o\x00g'
+ STATE_VERSION1_QT5 = (
+ b""
+ b"\x00\x00\x00^\x00s\x00i\x00l\x00x\x00.\x00g\x00u\x00i\x00.\x00"
+ b"d\x00i\x00a\x00l\x00o\x00g\x00.\x00I\x00m\x00a\x00g\x00e\x00F"
+ b"\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g\x00.\x00I\x00m\x00"
+ b"a\x00g\x00e\x00F\x00i\x00l\x00e\x00D\x00i\x00a\x00l\x00o\x00g"
+ b"\x00\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00#\x00\x00\x00"
+ b"\xFF\x00\x00\x00\x01\x00\x00\x00\x03\xFF\xFF\xFF\xFF\xFF\xFF\xFF"
+ b"\xFF\xFF\xFF\xFF\xFF\x01\xFF\xFF\xFF\xFF\x01\x00\x00\x00\x01\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x0C"
+ b"\x00\x00\x00\x00\xAA\x00\x00\x00\x0E\x00B\x00r\x00o\x00w\x00s"
+ b"\x00e\x00r\x00\x00\x00\x01\x00\x00\x00\x0C\x00\x00\x00\x00\x87"
+ b"\x00\x00\x00\xFF\x00\x00\x00\x00\x00\x00\x00\x01\x00\x00\x00\x00"
+ b"\x00\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x01\x90\x00\x00\x00\x04\x01\x01\x00"
+ b"\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00d\xFF\xFF"
+ b"\xFF\xFF\x00\x00\x00\x81\x00\x00\x00\x00\x00\x00\x00\x04\x00\x00"
+ b"\x00d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00"
+ b"\x01\x00\x00\x00\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00\x00"
+ b"\x00\x00\x00\x00d\x00\x00\x00\x01\x00\x00\x00\x00\x00\x00\x03"
+ b"\xE8\x00\xFF\xFF\xFF\xFF\x00\x00\x00\x01\x00\x00\x00\x01\x00\x00"
+ b"\x00\x0C\x00\x00\x00\x000\x00\x00\x00\x10\x00C\x00o\x00l\x00o"
+ b"\x00r\x00m\x00a\x00p\x00\x00\x00\x01\x00\x00\x00\x08\x00g\x00"
+ b"r\x00a\x00y\x01\x01\x00\x00\x00\x06\x00l\x00o\x00g"
+ )
"""Serialized state on Qt5. Generated using :meth:`printState`"""
def testAvoidRestoreRegression_Version1(self):
@@ -757,7 +797,9 @@ class TestImageFileDialogApi(testutils.TestCaseQt, _UtilsMixin):
browser = testutils.findChildren(dialog, qt.QWidget, name="browser")[0]
filename = _tmpDirectory + "/data.h5"
- url = silx.io.url.DataUrl(scheme="silx", file_path=filename, data_path="/group/foobar")
+ url = silx.io.url.DataUrl(
+ scheme="silx", file_path=filename, data_path="/group/foobar"
+ )
dialog.selectUrl(url.path())
self.qWaitForPendingActions(dialog)
self.assertIsNone(dialog._selectedData())
diff --git a/src/silx/gui/dialog/utils.py b/src/silx/gui/dialog/utils.py
index e07cf9f..1697bcf 100644
--- a/src/silx/gui/dialog/utils.py
+++ b/src/silx/gui/dialog/utils.py
@@ -85,7 +85,7 @@ def patchToConsumeReturnKey(widget):
Monkey-patch a widget to consume the return key instead of propagating it
to the dialog.
"""
- assert(not hasattr(widget, "_oldKeyPressEvent"))
+ assert not hasattr(widget, "_oldKeyPressEvent")
def keyPressEvent(self, event):
k = event.key()