CheckTable now remembers and reloads the state of rows that disappear temporarily
Flowchart updates - added/fixed some display nodes Merge from Kratz: - documentation updates - ComboBox class (updateList() allows entire item list to change while remembering previous setting)
This commit is contained in:
parent
3bf4c2e336
commit
a71e4a5862
@ -5,4 +5,15 @@ GradientEditorItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.GradientEditorItem.__init__
|
||||
|
||||
|
||||
TickSliderItem
|
||||
==================
|
||||
|
||||
.. autoclass:: pyqtgraph.TickSliderItem
|
||||
:members:
|
||||
|
||||
.. automethod:: pyqtgraph.TickSliderItem.__init__
|
||||
|
||||
|
||||
|
||||
|
@ -19,6 +19,7 @@ Contents:
|
||||
graphicslayout
|
||||
plotcurveitem
|
||||
scatterplotitem
|
||||
isocurveitem
|
||||
axisitem
|
||||
arrowitem
|
||||
curvepoint
|
||||
|
@ -59,6 +59,7 @@ class ImageExporter(Exporter):
|
||||
painter = QtGui.QPainter(self.png)
|
||||
try:
|
||||
self.setExportMode(True, {'antialias': self.params['antialias'], 'background': self.params['background']})
|
||||
painter.setRenderHint(QtGui.QPainter.Antialiasing, self.params['antialias'])
|
||||
self.getScene().render(painter, QtCore.QRectF(targetRect), sourceRect)
|
||||
finally:
|
||||
self.setExportMode(False)
|
||||
|
@ -45,7 +45,7 @@ class PlotWidgetNode(Node):
|
||||
|
||||
for val in vals:
|
||||
vid = id(val)
|
||||
if vid in self.items:
|
||||
if vid in self.items and self.items[vid].scene() is self.plot.scene():
|
||||
items.add(vid)
|
||||
else:
|
||||
#if isinstance(val, PlotCurveItem):
|
||||
@ -67,6 +67,11 @@ class PlotWidgetNode(Node):
|
||||
self.plot.removeItem(self.items[vid])
|
||||
del self.items[vid]
|
||||
|
||||
def processBypassed(self, args):
|
||||
for item in self.items.values():
|
||||
self.plot.removeItem(item)
|
||||
self.items = {}
|
||||
|
||||
#def setInput(self, **args):
|
||||
#for k in args:
|
||||
#self.plot.plot(args[k])
|
||||
|
@ -21,8 +21,23 @@ Gradients = collections.OrderedDict([
|
||||
|
||||
|
||||
class TickSliderItem(GraphicsWidget):
|
||||
## public class
|
||||
"""**Bases:** :class:`GraphicsWidget <pyqtgraph.GraphicsWidget>`
|
||||
|
||||
A rectangular item with tick marks along its length that can (optionally) be moved by the user."""
|
||||
|
||||
def __init__(self, orientation='bottom', allowAdd=True, **kargs):
|
||||
"""
|
||||
============= =================================================================================
|
||||
**Arguments**
|
||||
orientation Set the orientation of the gradient. Options are: 'left', 'right'
|
||||
'top', and 'bottom'.
|
||||
allowAdd Specifies whether ticks can be added to the item by the user.
|
||||
tickPen Default is white. Specifies the color of the outline of the ticks.
|
||||
Can be any of the valid arguments for :func:`mkPen <pyqtgraph.mkPen>`
|
||||
============= =================================================================================
|
||||
"""
|
||||
## public
|
||||
GraphicsWidget.__init__(self)
|
||||
self.orientation = orientation
|
||||
self.length = 100
|
||||
@ -77,10 +92,21 @@ class TickSliderItem(GraphicsWidget):
|
||||
self.setMaximumHeight(16777215)
|
||||
|
||||
|
||||
def setOrientation(self, ort):
|
||||
self.orientation = ort
|
||||
def setOrientation(self, orientation):
|
||||
## public
|
||||
"""Set the orientation of the TickSliderItem.
|
||||
|
||||
============= ===================================================================
|
||||
**Arguments**
|
||||
orientation Options are: 'left', 'right', 'top', 'bottom'
|
||||
The orientation option specifies which side of the slider the
|
||||
ticks are on, as well as whether the slider is vertical ('right'
|
||||
and 'left') or horizontal ('top' and 'bottom').
|
||||
============= ===================================================================
|
||||
"""
|
||||
self.setMaxDim()
|
||||
self.resetTransform()
|
||||
ort = orientation
|
||||
if ort == 'top':
|
||||
self.scale(1, -1)
|
||||
self.translate(0, -self.height())
|
||||
@ -92,10 +118,25 @@ class TickSliderItem(GraphicsWidget):
|
||||
self.rotate(270)
|
||||
self.translate(-self.height(), 0)
|
||||
#self.setPos(0, -self.height())
|
||||
elif ort != 'bottom':
|
||||
raise Exception("%s is not a valid orientation. Options are 'left', 'right', 'top', and 'bottom'" %str(ort))
|
||||
|
||||
self.translate(self.tickSize/2., 0)
|
||||
|
||||
def addTick(self, x, color=None, movable=True):
|
||||
## public
|
||||
"""
|
||||
Add a tick to the item.
|
||||
|
||||
============= ==================================================================
|
||||
**Arguments**
|
||||
x Position where tick should be added.
|
||||
color Color of added tick. If color is not specified, the color will be
|
||||
white.
|
||||
movable Specifies whether the tick is movable with the mouse.
|
||||
============= ==================================================================
|
||||
"""
|
||||
|
||||
if color is None:
|
||||
color = QtGui.QColor(255,255,255)
|
||||
tick = Tick(self, [x*self.length, 0], color, movable, self.tickSize, pen=self.tickPen)
|
||||
@ -104,6 +145,10 @@ class TickSliderItem(GraphicsWidget):
|
||||
return tick
|
||||
|
||||
def removeTick(self, tick):
|
||||
## public
|
||||
"""
|
||||
Removes the specified tick.
|
||||
"""
|
||||
del self.ticks[tick]
|
||||
tick.setParentItem(None)
|
||||
if self.scene() is not None:
|
||||
@ -138,6 +183,7 @@ class TickSliderItem(GraphicsWidget):
|
||||
#self.fitInView(bounds, QtCore.Qt.KeepAspectRatio)
|
||||
|
||||
def setLength(self, newLen):
|
||||
#private
|
||||
for t, x in self.ticks.items():
|
||||
t.setPos(x * newLen, t.pos().y())
|
||||
self.length = float(newLen)
|
||||
@ -206,12 +252,36 @@ class TickSliderItem(GraphicsWidget):
|
||||
pass
|
||||
|
||||
def setTickColor(self, tick, color):
|
||||
"""Set the color of the specified tick.
|
||||
|
||||
============= ==================================================================
|
||||
**Arguments**
|
||||
tick Can be either an integer corresponding to the index of the tick
|
||||
or a Tick object. Ex: if you had a slider with 3 ticks and you
|
||||
wanted to change the middle tick, the index would be 1.
|
||||
color The color to make the tick. Can be any argument that is valid for
|
||||
:func:`mkBrush <pyqtgraph.mkBrush>`
|
||||
============= ==================================================================
|
||||
"""
|
||||
tick = self.getTick(tick)
|
||||
tick.color = color
|
||||
tick.update()
|
||||
#tick.setBrush(QtGui.QBrush(QtGui.QColor(tick.color)))
|
||||
|
||||
def setTickValue(self, tick, val):
|
||||
## public
|
||||
"""
|
||||
Set the position (along the slider) of the tick.
|
||||
|
||||
============= ==================================================================
|
||||
**Arguments**
|
||||
tick Can be either an integer corresponding to the index of the tick
|
||||
or a Tick object. Ex: if you had a slider with 3 ticks and you
|
||||
wanted to change the middle tick, the index would be 1.
|
||||
val The desired position of the tick. If val is < 0, position will be
|
||||
set to 0. If val is > 1, position will be set to 1.
|
||||
============= ==================================================================
|
||||
"""
|
||||
tick = self.getTick(tick)
|
||||
val = min(max(0.0, val), 1.0)
|
||||
x = val * self.length
|
||||
@ -221,10 +291,29 @@ class TickSliderItem(GraphicsWidget):
|
||||
self.ticks[tick] = val
|
||||
|
||||
def tickValue(self, tick):
|
||||
## public
|
||||
"""Return the value (from 0.0 to 1.0) of the specified tick.
|
||||
|
||||
============= ==================================================================
|
||||
**Arguments**
|
||||
tick Can be either an integer corresponding to the index of the tick
|
||||
or a Tick object. Ex: if you had a slider with 3 ticks and you
|
||||
wanted the value of the middle tick, the index would be 1.
|
||||
============= ==================================================================
|
||||
"""
|
||||
tick = self.getTick(tick)
|
||||
return self.ticks[tick]
|
||||
|
||||
def getTick(self, tick):
|
||||
## public
|
||||
"""Return the Tick object at the specified index.
|
||||
|
||||
============= ==================================================================
|
||||
**Arguments**
|
||||
tick An integer corresponding to the index of the desired tick. If the
|
||||
argument is not an integer it will be returned unchanged.
|
||||
============= ==================================================================
|
||||
"""
|
||||
if type(tick) is int:
|
||||
tick = self.listTicks()[tick][0]
|
||||
return tick
|
||||
@ -233,17 +322,46 @@ class TickSliderItem(GraphicsWidget):
|
||||
#QtGui.QGraphicsView.mouseMoveEvent(self, ev)
|
||||
|
||||
def listTicks(self):
|
||||
"""Return a sorted list of all the Tick objects on the slider."""
|
||||
## public
|
||||
ticks = self.ticks.items()
|
||||
ticks.sort(lambda a,b: cmp(a[1], b[1]))
|
||||
return ticks
|
||||
|
||||
|
||||
class GradientEditorItem(TickSliderItem):
|
||||
"""
|
||||
**Bases:** :class:`TickSliderItem <pyqtgraph.TickSliderItem>`
|
||||
|
||||
An item that can be used to define a color gradient. Implements common pre-defined gradients that are
|
||||
customizable by the user. :class: `GradientWidget <pyqtgraph.widgets.GradientWidget>` provides a widget
|
||||
with a GradientEditorItem that can be added to a GUI.
|
||||
|
||||
======================== ===========================================================
|
||||
**Signals**
|
||||
sigGradientChanged(self) Signal is emitted anytime the gradient changes. The signal
|
||||
is emitted in real time while ticks are being dragged or
|
||||
colors are being changed.
|
||||
======================== ===========================================================
|
||||
|
||||
"""
|
||||
|
||||
sigGradientChanged = QtCore.Signal(object)
|
||||
|
||||
def __init__(self, *args, **kargs):
|
||||
"""
|
||||
Create a new GradientEditorItem.
|
||||
All arguments are passed to :func:`TickSliderItem.__init__ <pyqtgraph.TickSliderItem.__init__>`
|
||||
|
||||
============= =================================================================================
|
||||
**Arguments**
|
||||
orientation Set the orientation of the gradient. Options are: 'left', 'right'
|
||||
'top', and 'bottom'.
|
||||
allowAdd Default is True. Specifies whether ticks can be added to the item.
|
||||
tickPen Default is white. Specifies the color of the outline of the ticks.
|
||||
Can be any of the valid arguments for :func:`mkPen <pyqtgraph.mkPen>'
|
||||
============= =================================================================================
|
||||
"""
|
||||
self.currentTick = None
|
||||
self.currentTickColor = None
|
||||
self.rectSize = 15
|
||||
@ -308,22 +426,47 @@ class GradientEditorItem(TickSliderItem):
|
||||
self.setColorMode('rgb')
|
||||
self.updateGradient()
|
||||
|
||||
def setOrientation(self, ort):
|
||||
TickSliderItem.setOrientation(self, ort)
|
||||
def setOrientation(self, orientation):
|
||||
## public
|
||||
"""
|
||||
Set the orientation of the GradientEditorItem.
|
||||
|
||||
============= ===================================================================
|
||||
**Arguments**
|
||||
orientation Options are: 'left', 'right', 'top', 'bottom'
|
||||
The orientation option specifies which side of the gradient the
|
||||
ticks are on, as well as whether the gradient is vertical ('right'
|
||||
and 'left') or horizontal ('top' and 'bottom').
|
||||
============= ===================================================================
|
||||
"""
|
||||
TickSliderItem.setOrientation(self, orientation)
|
||||
self.translate(0, self.rectSize)
|
||||
|
||||
def showMenu(self, ev):
|
||||
#private
|
||||
self.menu.popup(ev.screenPos().toQPoint())
|
||||
|
||||
def contextMenuClicked(self, b=None):
|
||||
global Gradients
|
||||
#private
|
||||
#global Gradients
|
||||
act = self.sender()
|
||||
self.loadPreset(act.name)
|
||||
|
||||
def loadPreset(self, name):
|
||||
"""
|
||||
Load a predefined gradient.
|
||||
|
||||
""" ## TODO: provide image with names of defined gradients
|
||||
#global Gradients
|
||||
self.restoreState(Gradients[name])
|
||||
|
||||
def setColorMode(self, cm):
|
||||
"""
|
||||
Set the color mode for the gradient. Options are: 'hsv', 'rgb'
|
||||
|
||||
"""
|
||||
|
||||
## public
|
||||
if cm not in ['rgb', 'hsv']:
|
||||
raise Exception("Unknown color mode %s. Options are 'rgb' and 'hsv'." % str(cm))
|
||||
|
||||
@ -339,26 +482,31 @@ class GradientEditorItem(TickSliderItem):
|
||||
self.updateGradient()
|
||||
|
||||
def updateGradient(self):
|
||||
#private
|
||||
self.gradient = self.getGradient()
|
||||
self.gradRect.setBrush(QtGui.QBrush(self.gradient))
|
||||
self.sigGradientChanged.emit(self)
|
||||
|
||||
def setLength(self, newLen):
|
||||
#private (but maybe public)
|
||||
TickSliderItem.setLength(self, newLen)
|
||||
self.backgroundRect.setRect(0, -self.rectSize, newLen, self.rectSize)
|
||||
self.gradRect.setRect(0, -self.rectSize, newLen, self.rectSize)
|
||||
self.updateGradient()
|
||||
|
||||
def currentColorChanged(self, color):
|
||||
#private
|
||||
if color.isValid() and self.currentTick is not None:
|
||||
self.setTickColor(self.currentTick, color)
|
||||
self.updateGradient()
|
||||
|
||||
def currentColorRejected(self):
|
||||
#private
|
||||
self.setTickColor(self.currentTick, self.currentTickColor)
|
||||
self.updateGradient()
|
||||
|
||||
def tickClicked(self, tick, ev):
|
||||
#private
|
||||
if ev.button() == QtCore.Qt.LeftButton:
|
||||
if not tick.colorChangeAllowed:
|
||||
return
|
||||
@ -378,11 +526,13 @@ class GradientEditorItem(TickSliderItem):
|
||||
self.updateGradient()
|
||||
|
||||
def tickMoved(self, tick, pos):
|
||||
#private
|
||||
TickSliderItem.tickMoved(self, tick, pos)
|
||||
self.updateGradient()
|
||||
|
||||
|
||||
def getGradient(self):
|
||||
"""Return a QLinearGradient object."""
|
||||
g = QtGui.QLinearGradient(QtCore.QPointF(0,0), QtCore.QPointF(self.length,0))
|
||||
if self.colorMode == 'rgb':
|
||||
ticks = self.listTicks()
|
||||
@ -403,6 +553,15 @@ class GradientEditorItem(TickSliderItem):
|
||||
return g
|
||||
|
||||
def getColor(self, x, toQColor=True):
|
||||
"""
|
||||
Return a color for a given value.
|
||||
|
||||
============= ==================================================================
|
||||
**Arguments**
|
||||
x Value (position on gradient) of requested color.
|
||||
toQColor If true, returns a QColor object, else returns a (r,g,b,a) tuple.
|
||||
============= ==================================================================
|
||||
"""
|
||||
ticks = self.listTicks()
|
||||
if x <= ticks[0][1]:
|
||||
c = ticks[0][0].color
|
||||
@ -453,8 +612,19 @@ class GradientEditorItem(TickSliderItem):
|
||||
else:
|
||||
return (c.red(), c.green(), c.blue(), c.alpha())
|
||||
|
||||
def getLookupTable(self, nPts, alpha=True):
|
||||
"""Return an RGB/A lookup table."""
|
||||
def getLookupTable(self, nPts, alpha=None):
|
||||
"""
|
||||
Return an RGB(A) lookup table (ndarray).
|
||||
|
||||
============= ============================================================================
|
||||
**Arguments**
|
||||
nPts The number of points in the returned lookup table.
|
||||
alpha True, False, or None - Specifies whether or not alpha values are included
|
||||
in the table.If alpha is None, alpha will be automatically determined.
|
||||
============= ============================================================================
|
||||
"""
|
||||
if alpha is None:
|
||||
alpha = self.usesAlpha()
|
||||
if alpha:
|
||||
table = np.empty((nPts,4), dtype=np.ubyte)
|
||||
else:
|
||||
@ -466,9 +636,19 @@ class GradientEditorItem(TickSliderItem):
|
||||
table[i] = color[:table.shape[1]]
|
||||
|
||||
return table
|
||||
|
||||
def usesAlpha(self):
|
||||
"""Return True if any ticks have an alpha < 255"""
|
||||
|
||||
ticks = self.listTicks()
|
||||
for t in ticks:
|
||||
if t[0].color.alpha() < 255:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def isLookupTrivial(self):
|
||||
"""Return true if the gradient has exactly two stops in it: black at 0.0 and white at 1.0"""
|
||||
"""Return True if the gradient has exactly two stops in it: black at 0.0 and white at 1.0"""
|
||||
ticks = self.listTicks()
|
||||
if len(ticks) != 2:
|
||||
return False
|
||||
@ -482,10 +662,24 @@ class GradientEditorItem(TickSliderItem):
|
||||
|
||||
|
||||
def mouseReleaseEvent(self, ev):
|
||||
#private
|
||||
TickSliderItem.mouseReleaseEvent(self, ev)
|
||||
self.updateGradient()
|
||||
|
||||
def addTick(self, x, color=None, movable=True):
|
||||
"""
|
||||
Add a tick to the gradient. Return the tick.
|
||||
|
||||
============= ==================================================================
|
||||
**Arguments**
|
||||
x Position where tick should be added.
|
||||
color Color of added tick. If color is not specified, the color will be
|
||||
the color of the gradient at the specified position.
|
||||
movable Specifies whether the tick is movable with the mouse.
|
||||
============= ==================================================================
|
||||
"""
|
||||
|
||||
|
||||
if color is None:
|
||||
color = self.getColor(x)
|
||||
t = TickSliderItem.addTick(self, x, color=color, movable=movable)
|
||||
@ -494,6 +688,13 @@ class GradientEditorItem(TickSliderItem):
|
||||
return t
|
||||
|
||||
def saveState(self):
|
||||
"""
|
||||
Return a dictionary with parameters for rebuilding the gradient. Keys will include:
|
||||
|
||||
- 'mode': hsv or rgb
|
||||
- 'ticks': a list of tuples (pos, (r,g,b,a))
|
||||
"""
|
||||
## public
|
||||
ticks = []
|
||||
for t in self.ticks:
|
||||
c = t.color
|
||||
@ -502,6 +703,21 @@ class GradientEditorItem(TickSliderItem):
|
||||
return state
|
||||
|
||||
def restoreState(self, state):
|
||||
"""
|
||||
Restore the gradient specified in state.
|
||||
|
||||
============= ====================================================================
|
||||
**Arguments**
|
||||
state A dictionary with same structure as those returned by
|
||||
:func:`saveState <pyqtgraph.GradientEditorItem.saveState>`
|
||||
|
||||
Keys must include:
|
||||
|
||||
- 'mode': hsv or rgb
|
||||
- 'ticks': a list of tuples (pos, (r,g,b,a))
|
||||
============= ====================================================================
|
||||
"""
|
||||
## public
|
||||
self.setColorMode(state['mode'])
|
||||
for t in self.ticks.keys():
|
||||
self.removeTick(t)
|
||||
@ -512,6 +728,7 @@ class GradientEditorItem(TickSliderItem):
|
||||
|
||||
|
||||
class Tick(GraphicsObject):
|
||||
## private class
|
||||
|
||||
sigMoving = QtCore.Signal(object)
|
||||
sigMoved = QtCore.Signal(object)
|
||||
|
@ -6,6 +6,8 @@ from pyqtgraph.Point import Point
|
||||
__all__ = ['GridItem']
|
||||
class GridItem(UIGraphicsItem):
|
||||
"""
|
||||
**Bases:** `UIGraphicsItem <pyqtgraph.UIGraphicsItem>'
|
||||
|
||||
Displays a rectangular grid of lines indicating major divisions within a coordinate system.
|
||||
Automatically determines what divisions to use.
|
||||
"""
|
||||
|
@ -160,7 +160,7 @@ class HistogramLUTItem(GraphicsWidget):
|
||||
#self.imageItem.setLookupTable(self.gradient.getLookupTable(512))
|
||||
self.sigLookupTableChanged.emit(self)
|
||||
|
||||
def getLookupTable(self, img=None, n=None, alpha=False):
|
||||
def getLookupTable(self, img=None, n=None, alpha=None):
|
||||
if n is None:
|
||||
if img.dtype == np.uint8:
|
||||
n = 256
|
||||
|
@ -258,6 +258,8 @@ class ImageItem(GraphicsObject):
|
||||
lut = self.lut(self.image)
|
||||
else:
|
||||
lut = self.lut
|
||||
#print lut.shape
|
||||
#print self.lut
|
||||
|
||||
argb, alpha = fn.makeARGB(self.image, lut=lut, levels=self.levels)
|
||||
self.qimage = fn.makeQImage(argb, alpha)
|
||||
|
@ -9,8 +9,17 @@ import weakref
|
||||
__all__ = ['InfiniteLine']
|
||||
class InfiniteLine(UIGraphicsItem):
|
||||
"""
|
||||
**Bases:** :class:`UIGraphicsItem <pyqtgraph.UIGraphicsItem>`
|
||||
|
||||
Displays a line of infinite length.
|
||||
This line may be dragged to indicate a position in data coordinates.
|
||||
|
||||
=============================== ===================================================
|
||||
**Signals**
|
||||
sigDragged(self)
|
||||
sigPositionChangeFinished(self)
|
||||
sigPositionChanged(self)
|
||||
=============================== ===================================================
|
||||
"""
|
||||
|
||||
sigDragged = QtCore.Signal(object)
|
||||
@ -19,12 +28,18 @@ class InfiniteLine(UIGraphicsItem):
|
||||
|
||||
def __init__(self, pos=None, angle=90, pen=None, movable=False, bounds=None):
|
||||
"""
|
||||
Initialization options:
|
||||
pos - Position of the line. This can be a QPointF or a single value for vertical/horizontal lines.
|
||||
angle - Angle of line in degrees. 0 is horizontal, 90 is vertical.
|
||||
pen - Pen to use when drawing line
|
||||
movable - If True, the line can be dragged to a new position by the user
|
||||
bounds - Optional [min, max] bounding values. Bounds are only valid if the line is vertical or horizontal.
|
||||
============= ==================================================================
|
||||
**Arguments**
|
||||
pos Position of the line. This can be a QPointF or a single value for
|
||||
vertical/horizontal lines.
|
||||
angle Angle of line in degrees. 0 is horizontal, 90 is vertical.
|
||||
pen Pen to use when drawing line. Can be any arguments that are valid
|
||||
for :func:`mkPen <pyqtgraph.mkPen>`. Default pen is transparent
|
||||
yellow.
|
||||
movable If True, the line can be dragged to a new position by the user.
|
||||
bounds Optional [min, max] bounding values. Bounds are only valid if the
|
||||
line is vertical or horizontal.
|
||||
============= ==================================================================
|
||||
"""
|
||||
|
||||
UIGraphicsItem.__init__(self)
|
||||
@ -49,6 +64,7 @@ class InfiniteLine(UIGraphicsItem):
|
||||
#self.setFlag(self.ItemSendsScenePositionChanges)
|
||||
|
||||
def setMovable(self, m):
|
||||
"""Set whether the line is movable by the user."""
|
||||
self.movable = m
|
||||
self.setAcceptHoverEvents(m)
|
||||
|
||||
@ -58,6 +74,8 @@ class InfiniteLine(UIGraphicsItem):
|
||||
self.setValue(self.value())
|
||||
|
||||
def setPen(self, pen):
|
||||
"""Set the pen for drawing the line. Allowable arguments are any that are valid
|
||||
for :func:`mkPen <pyqtgraph.mkPen>`."""
|
||||
self.pen = fn.mkPen(pen)
|
||||
self.currentPen = self.pen
|
||||
self.update()
|
||||
@ -76,6 +94,7 @@ class InfiniteLine(UIGraphicsItem):
|
||||
self.update()
|
||||
|
||||
def setPos(self, pos):
|
||||
|
||||
if type(pos) in [list, tuple]:
|
||||
newPos = pos
|
||||
elif isinstance(pos, QtCore.QPointF):
|
||||
@ -116,6 +135,8 @@ class InfiniteLine(UIGraphicsItem):
|
||||
return self.p
|
||||
|
||||
def value(self):
|
||||
"""Return the value of the line. Will be a single number for horizontal and
|
||||
vertical lines, and a list of [x,y] values for diagonal lines."""
|
||||
if self.angle%180 == 0:
|
||||
return self.getYPos()
|
||||
elif self.angle%180 == 90:
|
||||
@ -124,6 +145,9 @@ class InfiniteLine(UIGraphicsItem):
|
||||
return self.getPos()
|
||||
|
||||
def setValue(self, v):
|
||||
"""Set the position of the line. If line is horizontal or vertical, v can be
|
||||
a single value. Otherwise, a 2D coordinate must be specified (list, tuple and
|
||||
QPointF are all acceptable)."""
|
||||
self.setPos(v)
|
||||
|
||||
## broken in 4.7
|
||||
|
@ -7,22 +7,51 @@ from pyqtgraph.Qt import QtGui, QtCore
|
||||
|
||||
class IsocurveItem(GraphicsObject):
|
||||
"""
|
||||
Item displaying an isocurve of a 2D array.
|
||||
**Bases:** :class:`GraphicsObject <pyqtgraph.GraphicsObject>`
|
||||
|
||||
To align this item correctly with an ImageItem,
|
||||
call isocurve.setParentItem(image)
|
||||
Item displaying an isocurve of a 2D array.To align this item correctly with an
|
||||
ImageItem,call isocurve.setParentItem(image)
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, data=None, level=0, pen='w'):
|
||||
"""
|
||||
Create a new isocurve item.
|
||||
|
||||
============= ===============================================================
|
||||
**Arguments**
|
||||
data A 2-dimensional ndarray. Can be initialized as None, and set
|
||||
later using :func:`setData <pyqtgraph.IsocurveItem.setData>`
|
||||
level The cutoff value at which to draw the isocurve.
|
||||
pen The color of the curve item. Can be anything valid for
|
||||
:func:`mkPen <pyqtgraph.mkPen>`
|
||||
============= ===============================================================
|
||||
"""
|
||||
GraphicsObject.__init__(self)
|
||||
self.level = 0
|
||||
|
||||
self.level = level
|
||||
self.data = None
|
||||
self.path = None
|
||||
self.setData(data, level)
|
||||
self.setPen(pen)
|
||||
self.setData(data, level)
|
||||
|
||||
|
||||
|
||||
#if data is not None and level is not None:
|
||||
#self.updateLines(data, level)
|
||||
|
||||
|
||||
def setData(self, data, level=None):
|
||||
"""
|
||||
Set the data/image to draw isocurves for.
|
||||
|
||||
============= ================================================================
|
||||
**Arguments**
|
||||
data A 2-dimensional ndarray.
|
||||
level The cutoff value at which to draw the curve. If level is not specified,
|
||||
the previous level is used.
|
||||
============= ================================================================
|
||||
"""
|
||||
if level is None:
|
||||
level = self.level
|
||||
self.level = level
|
||||
@ -31,15 +60,33 @@ class IsocurveItem(GraphicsObject):
|
||||
self.prepareGeometryChange()
|
||||
self.update()
|
||||
|
||||
|
||||
def setLevel(self, level):
|
||||
"""Set the level at which the isocurve is drawn."""
|
||||
self.level = level
|
||||
self.path = None
|
||||
self.update()
|
||||
|
||||
|
||||
def setPen(self, *args, **kwargs):
|
||||
"""Set the pen used to draw the isocurve. Arguments can be any that are valid
|
||||
for :func:`mkPen <pyqtgraph.mkPen>`"""
|
||||
self.pen = fn.mkPen(*args, **kwargs)
|
||||
self.update()
|
||||
|
||||
|
||||
def updateLines(self, data, level):
|
||||
##print "data:", data
|
||||
##print "level", level
|
||||
#lines = fn.isocurve(data, level)
|
||||
##print len(lines)
|
||||
#self.path = QtGui.QPainterPath()
|
||||
#for line in lines:
|
||||
#self.path.moveTo(*line[0])
|
||||
#self.path.lineTo(*line[1])
|
||||
#self.update()
|
||||
self.setData(data, level)
|
||||
|
||||
def boundingRect(self):
|
||||
if self.path is None:
|
||||
return QtCore.QRectF()
|
||||
|
@ -28,6 +28,23 @@ class LinearRegionItem(UIGraphicsItem):
|
||||
Horizontal = 1
|
||||
|
||||
def __init__(self, values=[0,1], orientation=None, brush=None, movable=True, bounds=None):
|
||||
"""Create a new LinearRegionItem.
|
||||
|
||||
============= =====================================================================
|
||||
**Arguments**
|
||||
values A list of the positions of the lines in the region. These are not
|
||||
limits; limits can be set by specifying bounds.
|
||||
orientation Options are LinearRegionItem.Vertical or LinearRegionItem.Horizontal.
|
||||
If not specified it will be vertical.
|
||||
brush Defines the brush that fills the region. Can be any arguments that
|
||||
are valid for :func:`mkBrush <pyqtgraph.mkBrush>`. Default is
|
||||
transparent blue.
|
||||
movable If True, the region and individual lines are movable by the user; if
|
||||
False, they are static.
|
||||
bounds Optional [min, max] bounding values for the region
|
||||
============= =====================================================================
|
||||
"""
|
||||
|
||||
UIGraphicsItem.__init__(self)
|
||||
if orientation is None:
|
||||
orientation = LinearRegionItem.Vertical
|
||||
@ -70,6 +87,13 @@ class LinearRegionItem(UIGraphicsItem):
|
||||
return (min(r), max(r))
|
||||
|
||||
def setRegion(self, rgn):
|
||||
"""Set the values for the edges of the region.
|
||||
|
||||
============= ==============================================
|
||||
**Arguments**
|
||||
rgn A list or tuple of the lower and upper values.
|
||||
============= ==============================================
|
||||
"""
|
||||
if self.lines[0].value() == rgn[0] and self.lines[1].value() == rgn[1]:
|
||||
return
|
||||
self.blockLineSignal = True
|
||||
@ -80,15 +104,25 @@ class LinearRegionItem(UIGraphicsItem):
|
||||
self.lineMoved()
|
||||
self.lineMoveFinished()
|
||||
|
||||
def setBrush(self, br):
|
||||
self.brush = fn.mkBrush(br)
|
||||
def setBrush(self, *br, **kargs):
|
||||
"""Set the brush that fills the region. Can have any arguments that are valid
|
||||
for :func:`mkBrush <pyqtgraph.mkBrush>`.
|
||||
"""
|
||||
self.brush = fn.mkBrush(*br, **kargs)
|
||||
self.currentBrush = self.brush
|
||||
|
||||
def setBounds(self, bounds):
|
||||
"""Optional [min, max] bounding values for the region. To have no bounds on the
|
||||
region use [None, None].
|
||||
Does not affect the current position of the region unless it is outside the new bounds.
|
||||
See :func:`setRegion <pyqtgraph.LinearRegionItem.setRegion>` to set the position
|
||||
of the region."""
|
||||
for l in self.lines:
|
||||
l.setBounds(bounds)
|
||||
|
||||
def setMovable(self, m):
|
||||
"""Set lines to be movable by the user, or not. If lines are movable, they will
|
||||
also accept HoverEvents."""
|
||||
for l in self.lines:
|
||||
l.setMovable(m)
|
||||
self.movable = m
|
||||
|
@ -58,7 +58,7 @@ class ScatterPlotItem(GraphicsObject):
|
||||
* If there is only one unnamed argument, it will be interpreted like the 'spots' argument.
|
||||
* If there are two unnamed arguments, they will be interpreted as sequences of x and y values.
|
||||
|
||||
====================== =================================================================================================
|
||||
====================== ===============================================================================================
|
||||
**Keyword Arguments:**
|
||||
*spots* Optional list of dicts. Each dict specifies parameters for a single spot:
|
||||
{'pos': (x,y), 'size', 'pen', 'brush', 'symbol'}. This is just an alternate method
|
||||
@ -83,7 +83,7 @@ class ScatterPlotItem(GraphicsObject):
|
||||
*size* The size (or list of sizes) of spots. If *pxMode* is True, this value is in pixels. Otherwise,
|
||||
it is in the item's local coordinate system.
|
||||
*data* a list of python objects used to uniquely identify each spot.
|
||||
====================== =================================================================================================
|
||||
====================== ===============================================================================================
|
||||
"""
|
||||
|
||||
self.clear()
|
||||
|
@ -11,12 +11,24 @@ from UIGraphicsItem import UIGraphicsItem
|
||||
__all__ = ['VTickGroup']
|
||||
class VTickGroup(UIGraphicsItem):
|
||||
"""
|
||||
**Bases:** :class:`UIGraphicsItem <pyqtgraph.UIGraphicsItem>`
|
||||
|
||||
Draws a set of tick marks which always occupy the same vertical range of the view,
|
||||
but have x coordinates relative to the data within the view.
|
||||
|
||||
"""
|
||||
def __init__(self, xvals=None, yrange=None, pen=None):
|
||||
|
||||
"""
|
||||
============= ===================================================================
|
||||
**Arguments**
|
||||
xvals A list of x values (in data coordinates) at which to draw ticks.
|
||||
yrange A list of [low, high] limits for the tick. 0 is the bottom of
|
||||
the view, 1 is the top. [0.8, 1] would draw ticks in the top
|
||||
fifth of the view.
|
||||
pen The pen to use for drawing ticks. Default is grey. Can be specified
|
||||
as any argument valid for :func:`mkPen<pyqtgraph.mkPen>`
|
||||
============= ===================================================================
|
||||
"""
|
||||
if yrange is None:
|
||||
yrange = [0, 1]
|
||||
if xvals is None:
|
||||
@ -42,15 +54,26 @@ class VTickGroup(UIGraphicsItem):
|
||||
self.setXVals(xvals)
|
||||
#self.valid = False
|
||||
|
||||
def setPen(self, pen):
|
||||
self.pen = fn.mkPen(pen)
|
||||
def setPen(self, *args, **kwargs):
|
||||
"""Set the pen to use for drawing ticks. Can be specified as any arguments valid
|
||||
for :func:`mkPen<pyqtgraph.mkPen>`"""
|
||||
self.pen = fn.mkPen(*args, **kwargs)
|
||||
|
||||
def setXVals(self, vals):
|
||||
"""Set the x values for the ticks.
|
||||
|
||||
============= =====================================================================
|
||||
**Arguments**
|
||||
vals A list of x values (in data/plot coordinates) at which to draw ticks.
|
||||
============= =====================================================================
|
||||
"""
|
||||
self.xvals = vals
|
||||
self.rebuildTicks()
|
||||
#self.valid = False
|
||||
|
||||
def setYRange(self, vals):
|
||||
"""Set the y range [low, high] that the ticks are drawn on. 0 is the bottom of
|
||||
the view, 1 is the top."""
|
||||
self.yrange = vals
|
||||
#self.relative = relative
|
||||
#if self.view is not None:
|
||||
|
@ -24,6 +24,7 @@ class CheckTable(QtGui.QWidget):
|
||||
|
||||
self.rowNames = []
|
||||
self.rowWidgets = []
|
||||
self.oldRows = {} ## remember settings from removed rows; reapply if they reappear.
|
||||
|
||||
|
||||
def updateRows(self, rows):
|
||||
@ -47,6 +48,8 @@ class CheckTable(QtGui.QWidget):
|
||||
self.layout.addWidget(check, row, col)
|
||||
checks.append(check)
|
||||
col += 1
|
||||
if name in self.oldRows:
|
||||
check.setChecked(self.oldRows[name])
|
||||
#QtCore.QObject.connect(check, QtCore.SIGNAL('stateChanged(int)'), self.checkChanged)
|
||||
check.stateChanged.connect(self.checkChanged)
|
||||
self.rowNames.append(name)
|
||||
@ -54,6 +57,7 @@ class CheckTable(QtGui.QWidget):
|
||||
|
||||
def removeRow(self, name):
|
||||
row = self.rowNames.index(name)
|
||||
self.oldRows[name] = self.saveState['rows'][name] ## save for later
|
||||
self.rowNames.pop(row)
|
||||
for w in self.rowWidgets[row]:
|
||||
w.setParent(None)
|
||||
|
41
widgets/ComboBox.py
Normal file
41
widgets/ComboBox.py
Normal file
@ -0,0 +1,41 @@
|
||||
from pyqtgraph.Qt import QtGui, QtCore
|
||||
from pyqtgraph.SignalProxy import SignalProxy
|
||||
|
||||
|
||||
class ComboBox(QtGui.QComboBox):
|
||||
"""Extends QComboBox to add extra functionality.
|
||||
- updateList() - updates the items in the comboBox while blocking signals, remembers and resets to the previous values if it's still in the list
|
||||
"""
|
||||
|
||||
|
||||
def __init__(self, parent=None, items=None, default=None):
|
||||
QtGui.QComboBox.__init__(self, parent)
|
||||
|
||||
#self.value = default
|
||||
|
||||
if items is not None:
|
||||
self.addItems(items)
|
||||
if default is not None:
|
||||
self.setValue(default)
|
||||
|
||||
def setValue(self, value):
|
||||
ind = self.findText(value)
|
||||
if ind == -1:
|
||||
return
|
||||
#self.value = value
|
||||
self.setCurrentIndex(ind)
|
||||
|
||||
def updateList(self, items):
|
||||
prevVal = str(self.currentText())
|
||||
try:
|
||||
self.blockSignals(True)
|
||||
self.clear()
|
||||
self.addItems(items)
|
||||
self.setValue(prevVal)
|
||||
|
||||
finally:
|
||||
self.blockSignals(False)
|
||||
|
||||
if str(self.currentText()) != prevVal:
|
||||
self.currentIndexChanged.emit(self.currentIndex())
|
||||
|
Loading…
Reference in New Issue
Block a user