Merge tag 'pyqtgraph-0.9.7' into pyqtgraph-core
This commit is contained in:
commit
ef0ee7c60b
@ -34,8 +34,12 @@ class ExportDialog(QtGui.QWidget):
|
|||||||
|
|
||||||
def show(self, item=None):
|
def show(self, item=None):
|
||||||
if item is not None:
|
if item is not None:
|
||||||
|
## Select next exportable parent of the item originally clicked on
|
||||||
while not isinstance(item, pg.ViewBox) and not isinstance(item, pg.PlotItem) and item is not None:
|
while not isinstance(item, pg.ViewBox) and not isinstance(item, pg.PlotItem) and item is not None:
|
||||||
item = item.parentItem()
|
item = item.parentItem()
|
||||||
|
## if this is a ViewBox inside a PlotItem, select the parent instead.
|
||||||
|
if isinstance(item, pg.ViewBox) and isinstance(item.parentItem(), pg.PlotItem):
|
||||||
|
item = item.parentItem()
|
||||||
self.updateItemList(select=item)
|
self.updateItemList(select=item)
|
||||||
self.setVisible(True)
|
self.setVisible(True)
|
||||||
self.activateWindow()
|
self.activateWindow()
|
||||||
|
@ -22,7 +22,7 @@ class PlotData(object):
|
|||||||
self.maxVals = {} ## cache for max/min
|
self.maxVals = {} ## cache for max/min
|
||||||
self.minVals = {}
|
self.minVals = {}
|
||||||
|
|
||||||
def addFields(self, fields):
|
def addFields(self, **fields):
|
||||||
for f in fields:
|
for f in fields:
|
||||||
if f not in self.fields:
|
if f not in self.fields:
|
||||||
self.fields[f] = None
|
self.fields[f] = None
|
||||||
|
@ -10,7 +10,7 @@ as it can be converted to/from a string using repr and eval.
|
|||||||
"""
|
"""
|
||||||
|
|
||||||
import re, os, sys
|
import re, os, sys
|
||||||
from pgcollections import OrderedDict
|
from .pgcollections import OrderedDict
|
||||||
GLOBAL_PATH = None # so not thread safe.
|
GLOBAL_PATH = None # so not thread safe.
|
||||||
from . import units
|
from . import units
|
||||||
from .python2_3 import asUnicode
|
from .python2_3 import asUnicode
|
||||||
|
@ -212,6 +212,19 @@ class Dock(QtGui.QWidget, DockDrop):
|
|||||||
def __repr__(self):
|
def __repr__(self):
|
||||||
return "<Dock %s %s>" % (self.name(), self.stretch())
|
return "<Dock %s %s>" % (self.name(), self.stretch())
|
||||||
|
|
||||||
|
## PySide bug: We need to explicitly redefine these methods
|
||||||
|
## or else drag/drop events will not be delivered.
|
||||||
|
def dragEnterEvent(self, *args):
|
||||||
|
DockDrop.dragEnterEvent(self, *args)
|
||||||
|
|
||||||
|
def dragMoveEvent(self, *args):
|
||||||
|
DockDrop.dragMoveEvent(self, *args)
|
||||||
|
|
||||||
|
def dragLeaveEvent(self, *args):
|
||||||
|
DockDrop.dragLeaveEvent(self, *args)
|
||||||
|
|
||||||
|
def dropEvent(self, *args):
|
||||||
|
DockDrop.dropEvent(self, *args)
|
||||||
|
|
||||||
class DockLabel(VerticalLabel):
|
class DockLabel(VerticalLabel):
|
||||||
|
|
||||||
|
@ -33,12 +33,13 @@ class DockArea(Container, QtGui.QWidget, DockDrop):
|
|||||||
def type(self):
|
def type(self):
|
||||||
return "top"
|
return "top"
|
||||||
|
|
||||||
def addDock(self, dock, position='bottom', relativeTo=None):
|
def addDock(self, dock=None, position='bottom', relativeTo=None, **kwds):
|
||||||
"""Adds a dock to this area.
|
"""Adds a dock to this area.
|
||||||
|
|
||||||
=========== =================================================================
|
=========== =================================================================
|
||||||
Arguments:
|
Arguments:
|
||||||
dock The new Dock object to add.
|
dock The new Dock object to add. If None, then a new Dock will be
|
||||||
|
created.
|
||||||
position 'bottom', 'top', 'left', 'right', 'over', or 'under'
|
position 'bottom', 'top', 'left', 'right', 'over', or 'under'
|
||||||
relativeTo If relativeTo is None, then the new Dock is added to fill an
|
relativeTo If relativeTo is None, then the new Dock is added to fill an
|
||||||
entire edge of the window. If relativeTo is another Dock, then
|
entire edge of the window. If relativeTo is another Dock, then
|
||||||
@ -46,7 +47,12 @@ class DockArea(Container, QtGui.QWidget, DockDrop):
|
|||||||
configuration for 'over' and 'under').
|
configuration for 'over' and 'under').
|
||||||
=========== =================================================================
|
=========== =================================================================
|
||||||
|
|
||||||
|
All extra keyword arguments are passed to Dock.__init__() if *dock* is
|
||||||
|
None.
|
||||||
"""
|
"""
|
||||||
|
if dock is None:
|
||||||
|
dock = Dock(**kwds)
|
||||||
|
|
||||||
|
|
||||||
## Determine the container to insert this dock into.
|
## Determine the container to insert this dock into.
|
||||||
## If there is no neighbor, then the container is the top.
|
## If there is no neighbor, then the container is the top.
|
||||||
@ -100,6 +106,8 @@ class DockArea(Container, QtGui.QWidget, DockDrop):
|
|||||||
dock.area = self
|
dock.area = self
|
||||||
self.docks[dock.name()] = dock
|
self.docks[dock.name()] = dock
|
||||||
|
|
||||||
|
return dock
|
||||||
|
|
||||||
def moveDock(self, dock, position, neighbor):
|
def moveDock(self, dock, position, neighbor):
|
||||||
"""
|
"""
|
||||||
Move an existing Dock to a new location.
|
Move an existing Dock to a new location.
|
||||||
@ -293,5 +301,19 @@ class DockArea(Container, QtGui.QWidget, DockDrop):
|
|||||||
self.home.removeTempArea(self)
|
self.home.removeTempArea(self)
|
||||||
#self.close()
|
#self.close()
|
||||||
|
|
||||||
|
## PySide bug: We need to explicitly redefine these methods
|
||||||
|
## or else drag/drop events will not be delivered.
|
||||||
|
def dragEnterEvent(self, *args):
|
||||||
|
DockDrop.dragEnterEvent(self, *args)
|
||||||
|
|
||||||
|
def dragMoveEvent(self, *args):
|
||||||
|
DockDrop.dragMoveEvent(self, *args)
|
||||||
|
|
||||||
|
def dragLeaveEvent(self, *args):
|
||||||
|
DockDrop.dragLeaveEvent(self, *args)
|
||||||
|
|
||||||
|
def dropEvent(self, *args):
|
||||||
|
DockDrop.dropEvent(self, *args)
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -14,6 +14,7 @@ class CSVExporter(Exporter):
|
|||||||
Exporter.__init__(self, item)
|
Exporter.__init__(self, item)
|
||||||
self.params = Parameter(name='params', type='group', children=[
|
self.params = Parameter(name='params', type='group', children=[
|
||||||
{'name': 'separator', 'type': 'list', 'value': 'comma', 'values': ['comma', 'tab']},
|
{'name': 'separator', 'type': 'list', 'value': 'comma', 'values': ['comma', 'tab']},
|
||||||
|
{'name': 'precision', 'type': 'int', 'value': 10, 'limits': [0, None]},
|
||||||
])
|
])
|
||||||
|
|
||||||
def parameters(self):
|
def parameters(self):
|
||||||
@ -42,18 +43,15 @@ class CSVExporter(Exporter):
|
|||||||
|
|
||||||
fd.write(sep.join(header) + '\n')
|
fd.write(sep.join(header) + '\n')
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
numFormat = '%%0.%dg' % self.params['precision']
|
||||||
done = True
|
numRows = reduce(max, [len(d[0]) for d in data])
|
||||||
|
for i in range(numRows):
|
||||||
for d in data:
|
for d in data:
|
||||||
if i < len(d[0]):
|
if i < len(d[0]):
|
||||||
fd.write('%g%s%g%s'%(d[0][i], sep, d[1][i], sep))
|
fd.write(numFormat % d[0][i] + sep + numFormat % d[1][i] + sep)
|
||||||
done = False
|
|
||||||
else:
|
else:
|
||||||
fd.write(' %s %s' % (sep, sep))
|
fd.write(' %s %s' % (sep, sep))
|
||||||
fd.write('\n')
|
fd.write('\n')
|
||||||
if done:
|
|
||||||
break
|
|
||||||
i += 1
|
|
||||||
fd.close()
|
fd.close()
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,17 +206,12 @@ class Flowchart(Node):
|
|||||||
item = node.graphicsItem()
|
item = node.graphicsItem()
|
||||||
item.setZValue(self.nextZVal*2)
|
item.setZValue(self.nextZVal*2)
|
||||||
self.nextZVal += 1
|
self.nextZVal += 1
|
||||||
#item.setParentItem(self.chartGraphicsItem())
|
|
||||||
self.viewBox.addItem(item)
|
self.viewBox.addItem(item)
|
||||||
#item.setPos(pos2.x(), pos2.y())
|
|
||||||
item.moveBy(*pos)
|
item.moveBy(*pos)
|
||||||
self._nodes[name] = node
|
self._nodes[name] = node
|
||||||
self.widget().addNode(node)
|
self.widget().addNode(node)
|
||||||
#QtCore.QObject.connect(node, QtCore.SIGNAL('closed'), self.nodeClosed)
|
|
||||||
node.sigClosed.connect(self.nodeClosed)
|
node.sigClosed.connect(self.nodeClosed)
|
||||||
#QtCore.QObject.connect(node, QtCore.SIGNAL('renamed'), self.nodeRenamed)
|
|
||||||
node.sigRenamed.connect(self.nodeRenamed)
|
node.sigRenamed.connect(self.nodeRenamed)
|
||||||
#QtCore.QObject.connect(node, QtCore.SIGNAL('outputChanged'), self.nodeOutputChanged)
|
|
||||||
node.sigOutputChanged.connect(self.nodeOutputChanged)
|
node.sigOutputChanged.connect(self.nodeOutputChanged)
|
||||||
|
|
||||||
def removeNode(self, node):
|
def removeNode(self, node):
|
||||||
@ -225,17 +220,14 @@ class Flowchart(Node):
|
|||||||
def nodeClosed(self, node):
|
def nodeClosed(self, node):
|
||||||
del self._nodes[node.name()]
|
del self._nodes[node.name()]
|
||||||
self.widget().removeNode(node)
|
self.widget().removeNode(node)
|
||||||
#QtCore.QObject.disconnect(node, QtCore.SIGNAL('closed'), self.nodeClosed)
|
|
||||||
try:
|
try:
|
||||||
node.sigClosed.disconnect(self.nodeClosed)
|
node.sigClosed.disconnect(self.nodeClosed)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
#QtCore.QObject.disconnect(node, QtCore.SIGNAL('renamed'), self.nodeRenamed)
|
|
||||||
try:
|
try:
|
||||||
node.sigRenamed.disconnect(self.nodeRenamed)
|
node.sigRenamed.disconnect(self.nodeRenamed)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
pass
|
pass
|
||||||
#QtCore.QObject.disconnect(node, QtCore.SIGNAL('outputChanged'), self.nodeOutputChanged)
|
|
||||||
try:
|
try:
|
||||||
node.sigOutputChanged.disconnect(self.nodeOutputChanged)
|
node.sigOutputChanged.disconnect(self.nodeOutputChanged)
|
||||||
except TypeError:
|
except TypeError:
|
||||||
|
@ -90,7 +90,7 @@
|
|||||||
<customwidget>
|
<customwidget>
|
||||||
<class>FlowchartGraphicsView</class>
|
<class>FlowchartGraphicsView</class>
|
||||||
<extends>QGraphicsView</extends>
|
<extends>QGraphicsView</extends>
|
||||||
<header>FlowchartGraphicsView</header>
|
<header>pyqtgraph.flowchart.FlowchartGraphicsView</header>
|
||||||
</customwidget>
|
</customwidget>
|
||||||
</customwidgets>
|
</customwidgets>
|
||||||
<resources/>
|
<resources/>
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui'
|
# Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui'
|
||||||
#
|
#
|
||||||
# Created: Sun Sep 9 14:41:29 2012
|
# Created: Sun Feb 24 19:47:29 2013
|
||||||
# by: PyQt4 UI code generator 4.9.1
|
# by: PyQt4 UI code generator 4.9.3
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
@ -56,4 +56,4 @@ class Ui_Form(object):
|
|||||||
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
|
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
|
||||||
from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget
|
from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget
|
||||||
from FlowchartGraphicsView import FlowchartGraphicsView
|
from pyqtgraph.flowchart.FlowchartGraphicsView import FlowchartGraphicsView
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui'
|
# Form implementation generated from reading ui file './flowchart/FlowchartTemplate.ui'
|
||||||
#
|
#
|
||||||
# Created: Sun Sep 9 14:41:30 2012
|
# Created: Sun Feb 24 19:47:30 2013
|
||||||
# by: pyside-uic 0.2.13 running on PySide 1.1.0
|
# by: pyside-uic 0.2.13 running on PySide 1.1.1
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
@ -51,4 +51,4 @@ class Ui_Form(object):
|
|||||||
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
|
Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
|
||||||
from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget
|
from pyqtgraph.widgets.DataTreeWidget import DataTreeWidget
|
||||||
from FlowchartGraphicsView import FlowchartGraphicsView
|
from pyqtgraph.flowchart.FlowchartGraphicsView import FlowchartGraphicsView
|
||||||
|
@ -152,7 +152,7 @@ class RegionSelectNode(CtrlNode):
|
|||||||
#print " new rgn:", c, region
|
#print " new rgn:", c, region
|
||||||
#self.items[c].setYRange([0., 0.2], relative=True)
|
#self.items[c].setYRange([0., 0.2], relative=True)
|
||||||
|
|
||||||
if self.selected.isConnected():
|
if self['selected'].isConnected():
|
||||||
if data is None:
|
if data is None:
|
||||||
sliced = None
|
sliced = None
|
||||||
elif (hasattr(data, 'implements') and data.implements('MetaArray')):
|
elif (hasattr(data, 'implements') and data.implements('MetaArray')):
|
||||||
@ -219,7 +219,6 @@ class EvalNode(Node):
|
|||||||
text = str(self.text.toPlainText())
|
text = str(self.text.toPlainText())
|
||||||
if text != self.lastText:
|
if text != self.lastText:
|
||||||
self.lastText = text
|
self.lastText = text
|
||||||
print("eval node update")
|
|
||||||
self.update()
|
self.update()
|
||||||
return QtGui.QTextEdit.focusOutEvent(self.text, ev)
|
return QtGui.QTextEdit.focusOutEvent(self.text, ev)
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ class PlotWidgetNode(Node):
|
|||||||
self.items = {}
|
self.items = {}
|
||||||
|
|
||||||
def disconnected(self, localTerm, remoteTerm):
|
def disconnected(self, localTerm, remoteTerm):
|
||||||
if localTerm is self.In and remoteTerm in self.items:
|
if localTerm is self['In'] and remoteTerm in self.items:
|
||||||
self.plot.removeItem(self.items[remoteTerm])
|
self.plot.removeItem(self.items[remoteTerm])
|
||||||
del self.items[remoteTerm]
|
del self.items[remoteTerm]
|
||||||
|
|
||||||
|
@ -85,7 +85,40 @@ class ArrowItem(QtGui.QGraphicsPathItem):
|
|||||||
p.setRenderHint(QtGui.QPainter.Antialiasing)
|
p.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||||
QtGui.QGraphicsPathItem.paint(self, p, *args)
|
QtGui.QGraphicsPathItem.paint(self, p, *args)
|
||||||
|
|
||||||
|
#p.setPen(fn.mkPen('r'))
|
||||||
|
#p.setBrush(fn.mkBrush(None))
|
||||||
|
#p.drawRect(self.boundingRect())
|
||||||
|
|
||||||
def shape(self):
|
def shape(self):
|
||||||
#if not self.opts['pxMode']:
|
#if not self.opts['pxMode']:
|
||||||
#return QtGui.QGraphicsPathItem.shape(self)
|
#return QtGui.QGraphicsPathItem.shape(self)
|
||||||
return self.path
|
return self.path
|
||||||
|
|
||||||
|
## dataBounds and pixelPadding methods are provided to ensure ViewBox can
|
||||||
|
## properly auto-range
|
||||||
|
def dataBounds(self, ax, frac, orthoRange=None):
|
||||||
|
pw = 0
|
||||||
|
pen = self.pen()
|
||||||
|
if not pen.isCosmetic():
|
||||||
|
pw = pen.width() * 0.7072
|
||||||
|
if self.opts['pxMode']:
|
||||||
|
return [0,0]
|
||||||
|
else:
|
||||||
|
br = self.boundingRect()
|
||||||
|
if ax == 0:
|
||||||
|
return [br.left()-pw, br.right()+pw]
|
||||||
|
else:
|
||||||
|
return [br.top()-pw, br.bottom()+pw]
|
||||||
|
|
||||||
|
def pixelPadding(self):
|
||||||
|
pad = 0
|
||||||
|
if self.opts['pxMode']:
|
||||||
|
br = self.boundingRect()
|
||||||
|
pad += (br.width()**2 + br.height()**2) ** 0.5
|
||||||
|
pen = self.pen()
|
||||||
|
if pen.isCosmetic():
|
||||||
|
pad += max(1, pen.width()) * 0.7072
|
||||||
|
return pad
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -782,7 +782,8 @@ class GradientEditorItem(TickSliderItem):
|
|||||||
self.sigGradientChangeFinished.emit(self)
|
self.sigGradientChangeFinished.emit(self)
|
||||||
|
|
||||||
|
|
||||||
class Tick(GraphicsObject):
|
class Tick(QtGui.QGraphicsObject): ## NOTE: Making this a subclass of GraphicsObject instead results in
|
||||||
|
## activating this bug: https://bugreports.qt-project.org/browse/PYSIDE-86
|
||||||
## private class
|
## private class
|
||||||
|
|
||||||
sigMoving = QtCore.Signal(object)
|
sigMoving = QtCore.Signal(object)
|
||||||
@ -802,7 +803,7 @@ class Tick(GraphicsObject):
|
|||||||
self.pg.lineTo(QtCore.QPointF(scale/3**0.5, scale))
|
self.pg.lineTo(QtCore.QPointF(scale/3**0.5, scale))
|
||||||
self.pg.closeSubpath()
|
self.pg.closeSubpath()
|
||||||
|
|
||||||
GraphicsObject.__init__(self)
|
QtGui.QGraphicsObject.__init__(self)
|
||||||
self.setPos(pos[0], pos[1])
|
self.setPos(pos[0], pos[1])
|
||||||
if self.movable:
|
if self.movable:
|
||||||
self.setZValue(1)
|
self.setZValue(1)
|
||||||
|
@ -495,8 +495,8 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
|
|
||||||
if isinstance(size, np.ndarray) or isinstance(size, list):
|
if isinstance(size, np.ndarray) or isinstance(size, list):
|
||||||
sizes = size
|
sizes = size
|
||||||
if kargs['mask'] is not None:
|
if mask is not None:
|
||||||
sizes = sizes[kargs['mask']]
|
sizes = sizes[mask]
|
||||||
if len(sizes) != len(dataSet):
|
if len(sizes) != len(dataSet):
|
||||||
raise Exception("Number of sizes does not match number of points (%d != %d)" % (len(sizes), len(dataSet)))
|
raise Exception("Number of sizes does not match number of points (%d != %d)" % (len(sizes), len(dataSet)))
|
||||||
dataSet['size'] = sizes
|
dataSet['size'] = sizes
|
||||||
@ -508,13 +508,13 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
if update:
|
if update:
|
||||||
self.updateSpots(dataSet)
|
self.updateSpots(dataSet)
|
||||||
|
|
||||||
def setPointData(self, data, dataSet=None):
|
def setPointData(self, data, dataSet=None, mask=None):
|
||||||
if dataSet is None:
|
if dataSet is None:
|
||||||
dataSet = self.data
|
dataSet = self.data
|
||||||
|
|
||||||
if isinstance(data, np.ndarray) or isinstance(data, list):
|
if isinstance(data, np.ndarray) or isinstance(data, list):
|
||||||
if kargs['mask'] is not None:
|
if mask is not None:
|
||||||
data = data[kargs['mask']]
|
data = data[mask]
|
||||||
if len(data) != len(dataSet):
|
if len(data) != len(dataSet):
|
||||||
raise Exception("Length of meta data does not match number of points (%d != %d)" % (len(data), len(dataSet)))
|
raise Exception("Length of meta data does not match number of points (%d != %d)" % (len(data), len(dataSet)))
|
||||||
|
|
||||||
|
@ -336,7 +336,7 @@ class ViewBox(GraphicsWidget):
|
|||||||
print("make qrectf failed:", self.state['targetRange'])
|
print("make qrectf failed:", self.state['targetRange'])
|
||||||
raise
|
raise
|
||||||
|
|
||||||
def setRange(self, rect=None, xRange=None, yRange=None, padding=0.02, update=True, disableAutoRange=True):
|
def setRange(self, rect=None, xRange=None, yRange=None, padding=None, update=True, disableAutoRange=True):
|
||||||
"""
|
"""
|
||||||
Set the visible range of the ViewBox.
|
Set the visible range of the ViewBox.
|
||||||
Must specify at least one of *range*, *xRange*, or *yRange*.
|
Must specify at least one of *range*, *xRange*, or *yRange*.
|
||||||
@ -347,7 +347,8 @@ class ViewBox(GraphicsWidget):
|
|||||||
*xRange* (min,max) The range that should be visible along the x-axis.
|
*xRange* (min,max) The range that should be visible along the x-axis.
|
||||||
*yRange* (min,max) The range that should be visible along the y-axis.
|
*yRange* (min,max) The range that should be visible along the y-axis.
|
||||||
*padding* (float) Expand the view by a fraction of the requested range.
|
*padding* (float) Expand the view by a fraction of the requested range.
|
||||||
By default, this value is 0.02 (2%)
|
By default, this value is set between 0.02 and 0.1 depending on
|
||||||
|
the size of the ViewBox.
|
||||||
============= =====================================================================
|
============= =====================================================================
|
||||||
|
|
||||||
"""
|
"""
|
||||||
@ -367,6 +368,10 @@ class ViewBox(GraphicsWidget):
|
|||||||
|
|
||||||
changed = [False, False]
|
changed = [False, False]
|
||||||
for ax, range in changes.items():
|
for ax, range in changes.items():
|
||||||
|
if padding is None:
|
||||||
|
xpad = self.suggestPadding(ax)
|
||||||
|
else:
|
||||||
|
xpad = padding
|
||||||
mn = min(range)
|
mn = min(range)
|
||||||
mx = max(range)
|
mx = max(range)
|
||||||
if mn == mx: ## If we requested 0 range, try to preserve previous scale. Otherwise just pick an arbitrary scale.
|
if mn == mx: ## If we requested 0 range, try to preserve previous scale. Otherwise just pick an arbitrary scale.
|
||||||
@ -375,11 +380,11 @@ class ViewBox(GraphicsWidget):
|
|||||||
dy = 1
|
dy = 1
|
||||||
mn -= dy*0.5
|
mn -= dy*0.5
|
||||||
mx += dy*0.5
|
mx += dy*0.5
|
||||||
padding = 0.0
|
xpad = 0.0
|
||||||
if any(np.isnan([mn, mx])) or any(np.isinf([mn, mx])):
|
if any(np.isnan([mn, mx])) or any(np.isinf([mn, mx])):
|
||||||
raise Exception("Not setting range [%s, %s]" % (str(mn), str(mx)))
|
raise Exception("Not setting range [%s, %s]" % (str(mn), str(mx)))
|
||||||
|
|
||||||
p = (mx-mn) * padding
|
p = (mx-mn) * xpad
|
||||||
mn -= p
|
mn -= p
|
||||||
mx += p
|
mx += p
|
||||||
|
|
||||||
@ -412,34 +417,53 @@ class ViewBox(GraphicsWidget):
|
|||||||
elif changed[1] and self.state['autoVisibleOnly'][0]:
|
elif changed[1] and self.state['autoVisibleOnly'][0]:
|
||||||
self.updateAutoRange()
|
self.updateAutoRange()
|
||||||
|
|
||||||
def setYRange(self, min, max, padding=0.02, update=True):
|
def setYRange(self, min, max, padding=None, update=True):
|
||||||
"""
|
"""
|
||||||
Set the visible Y range of the view to [*min*, *max*].
|
Set the visible Y range of the view to [*min*, *max*].
|
||||||
The *padding* argument causes the range to be set larger by the fraction specified.
|
The *padding* argument causes the range to be set larger by the fraction specified.
|
||||||
|
(by default, this value is between 0.02 and 0.1 depending on the size of the ViewBox)
|
||||||
"""
|
"""
|
||||||
self.setRange(yRange=[min, max], update=update, padding=padding)
|
self.setRange(yRange=[min, max], update=update, padding=padding)
|
||||||
|
|
||||||
def setXRange(self, min, max, padding=0.02, update=True):
|
def setXRange(self, min, max, padding=None, update=True):
|
||||||
"""
|
"""
|
||||||
Set the visible X range of the view to [*min*, *max*].
|
Set the visible X range of the view to [*min*, *max*].
|
||||||
The *padding* argument causes the range to be set larger by the fraction specified.
|
The *padding* argument causes the range to be set larger by the fraction specified.
|
||||||
|
(by default, this value is between 0.02 and 0.1 depending on the size of the ViewBox)
|
||||||
"""
|
"""
|
||||||
self.setRange(xRange=[min, max], update=update, padding=padding)
|
self.setRange(xRange=[min, max], update=update, padding=padding)
|
||||||
|
|
||||||
def autoRange(self, padding=0.02, item=None):
|
def autoRange(self, padding=None, items=None, item=None):
|
||||||
"""
|
"""
|
||||||
Set the range of the view box to make all children visible.
|
Set the range of the view box to make all children visible.
|
||||||
Note that this is not the same as enableAutoRange, which causes the view to
|
Note that this is not the same as enableAutoRange, which causes the view to
|
||||||
automatically auto-range whenever its contents are changed.
|
automatically auto-range whenever its contents are changed.
|
||||||
|
|
||||||
|
=========== ============================================================
|
||||||
|
Arguments
|
||||||
|
padding The fraction of the total data range to add on to the final
|
||||||
|
visible range. By default, this value is set between 0.02
|
||||||
|
and 0.1 depending on the size of the ViewBox.
|
||||||
|
items If specified, this is a list of items to consider when
|
||||||
|
determining the visible range.
|
||||||
|
=========== ============================================================
|
||||||
"""
|
"""
|
||||||
if item is None:
|
if item is None:
|
||||||
bounds = self.childrenBoundingRect()
|
bounds = self.childrenBoundingRect(items=items)
|
||||||
else:
|
else:
|
||||||
|
print("Warning: ViewBox.autoRange(item=__) is deprecated. Use 'items' argument instead.")
|
||||||
bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect()
|
bounds = self.mapFromItemToView(item, item.boundingRect()).boundingRect()
|
||||||
|
|
||||||
if bounds is not None:
|
if bounds is not None:
|
||||||
self.setRange(bounds, padding=padding)
|
self.setRange(bounds, padding=padding)
|
||||||
|
|
||||||
|
def suggestPadding(self, axis):
|
||||||
|
l = self.width() if axis==0 else self.height()
|
||||||
|
if l > 0:
|
||||||
|
padding = np.clip(1./(l**0.5), 0.02, 0.1)
|
||||||
|
else:
|
||||||
|
padding = 0.02
|
||||||
|
return padding
|
||||||
|
|
||||||
def scaleBy(self, s, center=None):
|
def scaleBy(self, s, center=None):
|
||||||
"""
|
"""
|
||||||
@ -577,12 +601,10 @@ class ViewBox(GraphicsWidget):
|
|||||||
w2 = (targetRect[ax][1]-targetRect[ax][0]) / 2.
|
w2 = (targetRect[ax][1]-targetRect[ax][0]) / 2.
|
||||||
childRange[ax] = [x-w2, x+w2]
|
childRange[ax] = [x-w2, x+w2]
|
||||||
else:
|
else:
|
||||||
l = self.width() if ax==0 else self.height()
|
padding = self.suggestPadding(ax)
|
||||||
if l > 0:
|
wp = (xr[1] - xr[0]) * padding
|
||||||
padding = np.clip(1./(l**0.5), 0.02, 0.1)
|
childRange[ax][0] -= wp
|
||||||
wp = (xr[1] - xr[0]) * padding
|
childRange[ax][1] += wp
|
||||||
childRange[ax][0] -= wp
|
|
||||||
childRange[ax][1] += wp
|
|
||||||
targetRect[ax] = childRange[ax]
|
targetRect[ax] = childRange[ax]
|
||||||
args['xRange' if ax == 0 else 'yRange'] = targetRect[ax]
|
args['xRange' if ax == 0 else 'yRange'] = targetRect[ax]
|
||||||
if len(args) == 0:
|
if len(args) == 0:
|
||||||
@ -995,13 +1017,14 @@ class ViewBox(GraphicsWidget):
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
def childrenBounds(self, frac=None, orthoRange=(None,None)):
|
def childrenBounds(self, frac=None, orthoRange=(None,None), items=None):
|
||||||
"""Return the bounding range of all children.
|
"""Return the bounding range of all children.
|
||||||
[[xmin, xmax], [ymin, ymax]]
|
[[xmin, xmax], [ymin, ymax]]
|
||||||
Values may be None if there are no specific bounds for an axis.
|
Values may be None if there are no specific bounds for an axis.
|
||||||
"""
|
"""
|
||||||
prof = debug.Profiler('updateAutoRange', disabled=True)
|
prof = debug.Profiler('updateAutoRange', disabled=True)
|
||||||
items = self.addedItems
|
if items is None:
|
||||||
|
items = self.addedItems
|
||||||
|
|
||||||
## measure pixel dimensions in view box
|
## measure pixel dimensions in view box
|
||||||
px, py = [v.length() if v is not None else 0 for v in self.childGroup.pixelVectors()]
|
px, py = [v.length() if v is not None else 0 for v in self.childGroup.pixelVectors()]
|
||||||
|
@ -206,6 +206,11 @@ class ImageView(QtGui.QWidget):
|
|||||||
This is only needed to override the default guess. Format is::
|
This is only needed to override the default guess. Format is::
|
||||||
|
|
||||||
{'t':0, 'x':1, 'y':2, 'c':3};
|
{'t':0, 'x':1, 'y':2, 'c':3};
|
||||||
|
|
||||||
|
*pos* Change the position of the displayed image
|
||||||
|
*scale* Change the scale of the displayed image
|
||||||
|
*transform* Set the transform of the dispalyed image. This option overrides *pos*
|
||||||
|
and *scale*.
|
||||||
============== =======================================================================
|
============== =======================================================================
|
||||||
"""
|
"""
|
||||||
prof = debug.Profiler('ImageView.setImage', disabled=True)
|
prof = debug.Profiler('ImageView.setImage', disabled=True)
|
||||||
|
@ -436,7 +436,7 @@ class MeshData(object):
|
|||||||
elif self._faceColorsIndexedByFaces is not None:
|
elif self._faceColorsIndexedByFaces is not None:
|
||||||
names.append('_faceColorsIndexedByFaces')
|
names.append('_faceColorsIndexedByFaces')
|
||||||
|
|
||||||
state = {n:getattr(self, n) for n in names}
|
state = dict([(n,getattr(self, n)) for n in names])
|
||||||
return pickle.dumps(state)
|
return pickle.dumps(state)
|
||||||
|
|
||||||
def restore(self, state):
|
def restore(self, state):
|
||||||
|
23
rebuildUi.py
23
rebuildUi.py
@ -1,23 +0,0 @@
|
|||||||
import os, sys
|
|
||||||
## Search the package tree for all .ui files, compile each to
|
|
||||||
## a .py for pyqt and pyside
|
|
||||||
|
|
||||||
pyqtuic = 'pyuic4'
|
|
||||||
pysideuic = 'pyside-uic'
|
|
||||||
|
|
||||||
for path, sd, files in os.walk('.'):
|
|
||||||
for f in files:
|
|
||||||
base, ext = os.path.splitext(f)
|
|
||||||
if ext != '.ui':
|
|
||||||
continue
|
|
||||||
ui = os.path.join(path, f)
|
|
||||||
|
|
||||||
py = os.path.join(path, base + '_pyqt.py')
|
|
||||||
if not os.path.exists(py) or os.stat(ui).st_mtime > os.stat(py).st_mtime:
|
|
||||||
os.system('%s %s > %s' % (pyqtuic, ui, py))
|
|
||||||
print(py)
|
|
||||||
|
|
||||||
py = os.path.join(path, base + '_pyside.py')
|
|
||||||
if not os.path.exists(py) or os.stat(ui).st_mtime > os.stat(py).st_mtime:
|
|
||||||
os.system('%s %s > %s' % (pysideuic, ui, py))
|
|
||||||
print(py)
|
|
Loading…
Reference in New Issue
Block a user