Commit c1960275 authored by Damien Naudet's avatar Damien Naudet

Added mouse position widgets.

parent 8fe9a9a5
......@@ -295,6 +295,8 @@ class DropPlotWidget(XsocsPlot2D):
self.setKeepDataAspectRatio(True)
self.setAcceptDrops(True)
self.setPointSelectionEnabled(True)
self.setShowMousePosition(True)
self.setShowSelectedCoordinates(True)
def dropEvent(self, event):
mimeData = event.mimeData()
......@@ -423,18 +425,24 @@ class FitView(Qt.QMainWindow):
grpLayout.addWidget(plot)
self.__fitPlots.append(plot)
plot.setGraphTitle('Qx fit')
self.setShowMousePosition(True)
self.setShowSelectedCoordinates(True)
plot = XsocsPlot2D()
plot.setKeepDataAspectRatio(False)
grpLayout.addWidget(plot)
self.__fitPlots.append(plot)
plot.setGraphTitle('Qy fit')
self.setShowMousePosition(True)
self.setShowSelectedCoordinates(True)
plot = XsocsPlot2D()
plot.setKeepDataAspectRatio(False)
grpLayout.addWidget(plot)
self.__fitPlots.append(plot)
plot.setGraphTitle('Qz fit')
self.setShowMousePosition(True)
self.setShowSelectedCoordinates(True)
layout.addWidget(grpBox, 0, 2)
......
......@@ -72,25 +72,25 @@ class RectRoiWidget(Qt.QWidget):
layout.addWidget(roiToolBar, row, 0, 1, 2, Qt.Qt.AlignTop)
row += 1
self._xEdit = edit = StyledLineEdit()
self._xEdit = edit = StyledLineEdit(nChar=6)
edit.setReadOnly(True)
layout.addWidget(Qt.QLabel('x='), row, 0, Qt.Qt.AlignTop)
layout.addWidget(edit, row, 1, Qt.Qt.AlignTop)
row += 1
self._yEdit = edit = StyledLineEdit()
self._yEdit = edit = StyledLineEdit(nChar=6)
edit.setReadOnly(True)
layout.addWidget(Qt.QLabel('y='), row, 0, Qt.Qt.AlignTop)
layout.addWidget(edit, row, 1, Qt.Qt.AlignTop)
row += 1
self._wEdit = edit = StyledLineEdit()
self._wEdit = edit = StyledLineEdit(nChar=6)
edit.setReadOnly(True)
layout.addWidget(Qt.QLabel('w='), row, 0, Qt.Qt.AlignTop)
layout.addWidget(edit, row, 1, Qt.Qt.AlignTop)
row += 1
self._hEdit = edit = StyledLineEdit()
self._hEdit = edit = StyledLineEdit(nChar=6)
edit.setReadOnly(True)
layout.addWidget(Qt.QLabel('h='), row, 0, Qt.Qt.AlignTop)
layout.addWidget(edit, row, 1, Qt.Qt.AlignTop)
......@@ -215,6 +215,8 @@ class IntensityView(Qt.QMainWindow):
self.setWindowTitle('[XSOCS] {0}'.format(node.h5Path))
self.__plotWindow = plotWindow = XsocsPlot2D()
plotWindow.setShowMousePosition(True)
plotWindow.setShowSelectedCoordinates(False)
dock = Qt.QDockWidget(self)
tree = IntensityTree(self, model=model)
......
......@@ -62,8 +62,8 @@ class RoiAxisWidget(Qt.QWidget):
layout = Qt.QGridLayout(self)
label = Qt.QLabel(label)
slider = self.__slider = RangeSlider()
leftEdit = self.__leftEdit = StyledLineEdit(nChar=5)
rightEdit = self.__rightEdit = StyledLineEdit(nChar=5)
leftEdit = self.__leftEdit = StyledLineEdit(nChar=7)
rightEdit = self.__rightEdit = StyledLineEdit(nChar=7)
leftEdit.setReadOnly(True)
rightEdit.setReadOnly(True)
......@@ -86,28 +86,13 @@ class PlotIntensityMap(XsocsPlot2D):
:param parent: QWidget's parent
"""
def __init__(self, parent=None):
super(PlotIntensityMap, self).__init__(
parent=parent, backend=None,
resetzoom=True, autoScale=False,
logScale=False, grid=True,
curveStyle=False, colormap=False,
aspectRatio=True, yInverted=False,
copy=True, save=True, print_=True,
control=False, position=False,
roi=False, mask=False, fit=False)
def __init__(self, parent=None, **kwargs):
super(PlotIntensityMap, self).__init__(**kwargs)
self.setMinimumSize(150, 150)
self.setDataMargins(0.2, 0.2, 0.2, 0.2)
# def setSelectedPosition(self, x, y):
# """Set the selected position.
#
# :param float x:
# :param float y:
# """
# self.addXMarker(x, legend='Xselection', color='pink')
# self.addYMarker(y, legend='Yselection', color='pink')
self.setShowMousePosition(True)
self.setShowSelectedCoordinates(True)
def sizeHint(self):
return Qt.QSize(200, 200)
......
......@@ -91,9 +91,57 @@ class StyledLineEdit(Qt.QLineEdit):
# There are two stylesheet units "em" and "xm" that I tried,
# but the results were not satisfactory.
fm = self.fontMetrics()
text = 'M' * (self.__nChar + self._padding)
width = fm.width(text)
# text = 'M' * (self.__nChar + self._padding)
# width = fm.width(text)
width = fm.width('M') * self.__nChar
height = fm.height()
sheet += """StyledLineEdit{{ max-width: {0}px;
min-width: {0}px; }}
""".format(width)
min-width: {0}px;
max-height: {1}px;
min-height: {1}px;}}
""".format(width, height)
self.setStyleSheet(sheet)
class StyledLabel(Qt.QLabel):
"""
Styled QLabel.
"""
_padding = 2
def __init__(self, parent=None, nChar=None):
super(StyledLabel, self).__init__(parent)
self.__nChar = nChar
self.setAlignment(Qt.Qt.AlignLeft)
self.setFrameStyle(Qt.QFrame.Panel | Qt.QFrame.Sunken)
self._updateStyleSheet()
def setNChar(self, nChar):
"""
Sets the number of characters to be displayed.
:param nChar: None to reset to default.
:return:
"""
self.__nChar = nChar
self._updateStyleSheet()
def _updateStyleSheet(self):
"""
Sets the style sheet.
:return:
"""
sheet = ''
if self.__nChar is not None:
# There are two stylesheet units "em" and "xm" that I tried,
# but the results were not satisfactory.
fm = self.fontMetrics()
width = fm.width('M') * self.__nChar
height = fm.height()
sheet += """StyledLabel{{ max-width: {0}px;
min-width: {0}px;
max-height: {1}px;
min-height: {1}px;}}
""".format(width, height)
self.setStyleSheet(sheet)
# coding: utf-8
# /*##########################################################################
#
# Copyright (c) 2015-2016 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
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
# THE SOFTWARE.
#
# ###########################################################################*/
from __future__ import absolute_import
__authors__ = ["D. Naudet"]
__license__ = "MIT"
__date__ = "15/09/2016"
from silx.gui import qt as Qt
from .Input import StyledLabel, StyledLineEdit
class PointWidget(Qt.QFrame):
def __init__(self, **kwargs):
super(PointWidget, self).__init__(**kwargs)
layout = Qt.QHBoxLayout(self)
layout.setContentsMargins(0, 0, 0, 0)
self.__xEdit = xEdit = StyledLineEdit(nChar=6)
self.__yEdit = yEdit = StyledLineEdit(nChar=6)
xLabel = 'x'
yLabel = 'y'
layout.addWidget(StyledLabel(xLabel, nChar=len(xLabel)))
layout.addWidget(xEdit)
layout.addWidget(StyledLabel(yLabel, nChar=len(yLabel)))
layout.addWidget(yEdit)
def setPoint(self, x, y):
self.__xEdit.setText('{0:6g}'.format(x))
self.__yEdit.setText('{0:6g}'.format(y))
......@@ -34,7 +34,7 @@ import weakref
from collections import namedtuple
import numpy as np
from matplotlib import cm, colors as mpl_colors
from matplotlib import cm
from silx.gui import qt as Qt
......@@ -43,10 +43,11 @@ from silx.gui.icons import getQIcon
from silx.gui.plot import PlotWindow
from silx.math.histogram import Histogramnd
from ...gui.icons import getQIcon as getKmapIcon
from ..widgets.RangeSlider import RangeSlider
from ..widgets.Input import StyledLineEdit
from ..widgets.Containers import GroupBox
from ..widgets.RangeSlider import RangeSlider
from ..widgets.PointWidget import PointWidget
from ...gui.icons import getQIcon as getKmapIcon
from ..widgets.Input import StyledLineEdit, StyledLabel
_defaultNColors = 256
......@@ -55,13 +56,12 @@ XsocsPlot2DColormap = namedtuple('XsocsPlot2DColormap',
['colormap', 'minVal', 'maxVal', 'nColors'])
def _arrayToIndexedPixmap(vector, cmap, nColors=256, range=None):
def _arrayToIndexedPixmap(vector, cmap, nColors=256):
"""
:param vector:
:param cmap:
:param nColors:
:param range:
:return:
"""
assert vector.ndim <= 2
......@@ -307,6 +307,70 @@ class XsocsPlot2DColorDialog(Qt.QDialog):
XsocsPlot2DPoint = namedtuple('XsocsPlot2DPoint', ['x', 'y', 'xIdx', 'yIdx'])
class DoublePointDock(Qt.QDockWidget):
"""
Widget for displaying selected point and mouse coordinate
"""
mousePoint = property(lambda self: self.__mousePoint)
selectedPoint = property(lambda self: self.__selectedPoint)
def __init__(self, *args, **kwargs):
super(DoublePointDock, self).__init__(*args, **kwargs)
widget = Qt.QWidget()
layout = Qt.QGridLayout(widget)
layout.setContentsMargins(0, 0, 0, 0)
self.__mouseVisible = True
self.__selectedVisible = True
self.__mousePoint = mousePoint = PointWidget()
self.__mouseLabel = mouseLabel = Qt.QLabel('Mouse')
mousePoint.setFrameStyle(Qt.QFrame.Box)
self.__selectedPoint = selectedPoint = PointWidget()
self.__selectedLabel = selectedLabel = Qt.QLabel('Selected')
selectedPoint.setFrameStyle(Qt.QFrame.Box)
layout.addWidget(mouseLabel, 0, 0)
layout.addWidget(mousePoint, 0, 1)
layout.addWidget(selectedLabel, 1, 0)
layout.addWidget(selectedPoint, 1, 1)
layout.setColumnStretch(layout.columnCount(), 1)
layout.setRowStretch(layout.rowCount(), 1)
widget.installEventFilter(self)
self.setWidget(widget)
def eventFilter(self, obj, event):
if event.type() == Qt.QEvent.Resize:
self.setFixedHeight(event.size().height())
return super(DoublePointDock, self).eventFilter(obj, event)
def sizeHint(self):
return Qt.QSize(0, 0)
def setShowSelectedPoint(self, show):
if show != self.__selectedVisible:
layout = self.layout()
if show:
layout.addWidget(self.__selectedPoint, 1, 0)
layout.addWidget(self.__selectedLabel, 1, 1)
else:
layout.takeAt(layout.indexOf(self.__selectedPoint))
self.__selectedPoint.setParent(None)
layout.takeAt(layout.indexOf(self.__selectedLabel))
self.__selectedLabel.setParent(None)
self.__selectedVisible = show
# self.updateGeometry()
# self.parent().adjustSize()
def setShowMousePoint(self, show):
self.__mousePoint.setVisible(show)
self.__mouseLabel.setVisible(show)
class XsocsPlot2D(PlotWindow):
"""
Base class for the 2D scatter plot.
......@@ -323,18 +387,44 @@ class XsocsPlot2D(PlotWindow):
self.__sigPlotConnected = False
self.__pointSelectionEnabled = False
self.__showSelectedCoordinates = False
self.__showMousePosition = False
self.__logScatter = False
self.__colormap = cm.jet
self.__values = {}
self.__cmapDialog = None
pointDock = self.__pointWidget = DoublePointDock()
# dock = self.__pointDock = Qt.QDockWidget()
# dock.setWidget(pointWidget)
features = Qt.QDockWidget.DockWidgetVerticalTitleBar | Qt.QDockWidget.DockWidgetClosable
pointDock.setFeatures(features)
pointDock.sizeHint = lambda: Qt.QSize()
self.addDockWidget(Qt.Qt.BottomDockWidgetArea, pointDock)
pointDockAction = pointDock.toggleViewAction()
pointDockAction.setIcon(getQIcon('crosshair'))
pointDockAction.setIconVisibleInMenu(True)
pointDockBn = Qt.QToolButton()
pointDockBn.setDefaultAction(pointDockAction)
closeButton = Qt.QToolButton()
style = Qt.QApplication.style()
icon = style.standardIcon(Qt.QStyle.SP_TitleBarCloseButton)
closeButton.setIcon(icon)
closeButton.setFixedSize(closeButton.iconSize())
closeButton.clicked.connect(pointDockAction.trigger)
pointDock.setTitleBarWidget(closeButton)
toolbars = self.findChildren(Qt.QToolBar)
for toolbar in toolbars:
toolbar.hide()
centralWid = self.centralWidget()
centralWid.installEventFilter(self)
self.__optionsBase = optionsBase = Qt.QWidget(centralWid)
optionsLayout = Qt.QHBoxLayout(optionsBase)
optionsLayout.setContentsMargins(0, 0, 0, 0)
......@@ -367,6 +457,11 @@ class XsocsPlot2D(PlotWindow):
optionsLayoutB.setContentsMargins(0, 0, 0, 0)
optionsLayoutB.setSpacing(0)
# coordinates dock action
pointDockBn = Qt.QToolButton()
pointDockBn.setDefaultAction(pointDockAction)
optionsLayoutB.addWidget(pointDockBn)
# colormap dialog action
self.__colormapBn = colormapBn = Qt.QToolButton()
colormapBn.setDisabled(True)
......@@ -461,9 +556,16 @@ class XsocsPlot2D(PlotWindow):
self.addXMarker(x, legend='Xselection', color='pink')
self.addYMarker(y, legend='Yselection', color='pink')
def __displaySelectedCoordinates(self, x, y):
if self.__showSelectedCoordinates:
self.__pointWidget.selectedPoint.setPoint(x, y)
def __displayMousePosition(self, x, y):
self.__pointWidget.mousePoint.setPoint(x, y)
def __onPlotSignal(self, event):
if self.__pointSelectionEnabled:
if event['event'] in ('mouseClicked'):
if self.__pointSelectionEnabled or self.__showSelectedCoordinates:
if event['event'] == 'mouseClicked':
x, y = event['x'], event['y']
self.selectPoint(x, y)
......@@ -481,7 +583,11 @@ class XsocsPlot2D(PlotWindow):
point = XsocsPlot2DPoint(x=x, y=y, xIdx=xIdx, yIdx=yIdx)
self.selectPoint(x, y)
self.sigPointSelected.emit(point)
if self.__showMousePosition:
if event['event'] == 'mouseMoved':
self.__displayMousePosition(event['x'], event['y'])
def selectPoint(self, x, y):
"""
......@@ -493,21 +599,47 @@ class XsocsPlot2D(PlotWindow):
:param y:
:return:
"""
self.__displaySelectedCoordinates(x, y)
self.__drawSelectedPosition(x, y)
def setShowSelectedCoordinates(self, show):
self.__pointWidget.setShowSelectedPoint(show)
self.__connectPlotSignal(showSelectedCoordinates=show)
def getShowSelectedCoordinates(self):
return self.__showSelectedCoordinates
def setShowMousePosition(self, show):
self.__connectPlotSignal(showMousePosition=show)
def getShowMousePosition(self):
return self.__showMousePosition
def setPointSelectionEnabled(self, enabled):
self.__connectPlotSignal(pointSelection=enabled)
def isPointSelectionEnabled(self, enabled):
return self.__pointSelectionEnabled
def __connectPlotSignal(self, pointSelection=None):
def __connectPlotSignal(self,
pointSelection=None,
showSelectedCoordinates=None,
showMousePosition=None):
currentState = self.__sigPlotConnected
if pointSelection is not None:
self.__pointSelectionEnabled = pointSelection
newState = self.__pointSelectionEnabled
if showSelectedCoordinates is not None:
self.__showSelectedCoordinates = showSelectedCoordinates
if showMousePosition is not None:
self.__showMousePosition = showMousePosition
newState = (self.__pointSelectionEnabled |
self.__showSelectedCoordinates |
self.__showMousePosition)
if currentState != newState:
if newState:
self.sigPlotSignal.connect(self.__onPlotSignal)
......@@ -581,9 +713,10 @@ class XsocsPlot2D(PlotWindow):
last_bin_closed=True)
return histo
def resizeEvent(self, event):
super(XsocsPlot2D, self).resizeEvent(event)
self.__moveOptionBar()
def eventFilter(self, obj, event):
if event.type() == Qt.QEvent.Resize:
self.__moveOptionBar()
return super(XsocsPlot2D, self).eventFilter(obj, event)
def __moveOptionBar(self):
optionsBase = self.__optionsBase
......@@ -712,8 +845,9 @@ class XsocsPlot2D(PlotWindow):
colors = None
if values is not None and self.__values:
raise ValueError('XsocsPlot2D only supports one 2D scatter plot.')
# TODO
# if values is not None and self.__values:
# raise ValueError('XsocsPlot2D only supports one 2D scatter plot.')
if colormap is None:
colormap = XsocsPlot2DColormap(colormap=cm.jet,
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment