diff --git a/GraphicsScene/GraphicsScene.py b/GraphicsScene/GraphicsScene.py
index e6679c2d..9cc2491a 100644
--- a/GraphicsScene/GraphicsScene.py
+++ b/GraphicsScene/GraphicsScene.py
@@ -59,12 +59,12 @@ class GraphicsScene(QtGui.QGraphicsScene):
move in a drag.
"""
-
- _addressCache = weakref.WeakValueDictionary()
sigMouseHover = QtCore.Signal(object) ## emits a list of objects hovered over
sigMouseMoved = QtCore.Signal(object) ## emits position of mouse on every move
sigMouseClicked = QtCore.Signal(object) ## emitted when MouseClickEvent is not accepted by any items under the click.
+ _addressCache = weakref.WeakValueDictionary()
+
ExportDirectory = None
@classmethod
diff --git a/GraphicsScene/exportDialogTemplate.py b/GraphicsScene/exportDialogTemplate.py
index ae90100d..60f18d0d 100644
--- a/GraphicsScene/exportDialogTemplate.py
+++ b/GraphicsScene/exportDialogTemplate.py
@@ -2,7 +2,7 @@
# Form implementation generated from reading ui file 'exportDialogTemplate.ui'
#
-# Created: Sat Mar 10 17:54:53 2012
+# Created: Thu Mar 22 13:13:06 2012
# by: PyQt4 UI code generator 4.8.5
#
# WARNING! All changes made in this file will be lost!
@@ -18,7 +18,7 @@ class Ui_Form(object):
def setupUi(self, Form):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(241, 367)
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
+ Form.setWindowTitle(QtGui.QApplication.translate("Form", "Export", None, QtGui.QApplication.UnicodeUTF8))
self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
diff --git a/GraphicsScene/exportDialogTemplate.ui b/GraphicsScene/exportDialogTemplate.ui
index 0d840253..c81c8831 100644
--- a/GraphicsScene/exportDialogTemplate.ui
+++ b/GraphicsScene/exportDialogTemplate.ui
@@ -11,7 +11,7 @@
- Form
+ Export
diff --git a/exporters/Exporter.py b/exporters/Exporter.py
index 25ae367c..abcddd28 100644
--- a/exporters/Exporter.py
+++ b/exporters/Exporter.py
@@ -75,8 +75,74 @@ class Exporter(object):
else:
return self.item.mapRectToDevice(self.item.boundingRect())
+ def setExportMode(self, export, opts=None):
+ """
+ Call setExportMode(export, opts) on all items that will
+ be painted during the export. This informs the item
+ that it is about to be painted for export, allowing it to
+ alter its appearance temporarily
-
+
+ *export* - bool; must be True before exporting and False afterward
+ *opts* - dict; common parameters are 'antialias' and 'background'
+ """
+ if opts is None:
+ opts = {}
+ for item in self.getPaintItems():
+ if hasattr(item, 'setExportMode'):
+ item.setExportMode(export, opts)
+
+ def getPaintItems(self, root=None):
+ """Return a list of all items that should be painted in the correct order."""
+ if root is None:
+ root = self.item
+ preItems = []
+ postItems = []
+ if isinstance(root, QtGui.QGraphicsScene):
+ childs = [i for i in root.items() if i.parentItem() is None]
+ rootItem = []
+ else:
+ childs = root.childItems()
+ rootItem = [root]
+ childs.sort(lambda a,b: cmp(a.zValue(), b.zValue()))
+ while len(childs) > 0:
+ ch = childs.pop(0)
+ tree = self.getPaintItems(ch)
+ if int(ch.flags() & ch.ItemStacksBehindParent) > 0 or (ch.zValue() < 0 and int(ch.flags() & ch.ItemNegativeZStacksBehindParent) > 0):
+ preItems.extend(tree)
+ else:
+ postItems.extend(tree)
+
+ return preItems + rootItem + postItems
+
+ def render(self, painter, sourcRect, targetRect, item=None)
+
+ #if item is None:
+ #item = self.item
+ #preItems = []
+ #postItems = []
+ #if isinstance(item, QtGui.QGraphicsScene):
+ #childs = [i for i in item.items() if i.parentItem() is None]
+ #rootItem = []
+ #else:
+ #childs = item.childItems()
+ #rootItem = [item]
+ #childs.sort(lambda a,b: cmp(a.zValue(), b.zValue()))
+ #while len(childs) > 0:
+ #ch = childs.pop(0)
+ #if int(ch.flags() & ch.ItemStacksBehindParent) > 0 or (ch.zValue() < 0 and int(ch.flags() & ch.ItemNegativeZStacksBehindParent) > 0):
+ #preItems.extend(tree)
+ #else:
+ #postItems.extend(tree)
+
+ #for ch in preItems:
+ #self.render(painter, sourceRect, targetRect, item=ch)
+ ### paint root here
+ #for ch in postItems:
+ #self.render(painter, sourceRect, targetRect, item=ch)
+
+
+ self.getScene().render(painter, QtCore.QRectF(targetRect), QtCore.QRectF(sourceRect))
#def writePs(self, fileName=None, item=None):
#if fileName is None:
diff --git a/exporters/ImageExporter.py b/exporters/ImageExporter.py
index 138ddabb..fa9b6f6d 100644
--- a/exporters/ImageExporter.py
+++ b/exporters/ImageExporter.py
@@ -57,6 +57,12 @@ class ImageExporter(Exporter):
bg[:,:,3] = color.alpha()
self.png = pg.makeQImage(bg, alpha=True)
painter = QtGui.QPainter(self.png)
- self.getScene().render(painter, QtCore.QRectF(targetRect), sourceRect)
+ try:
+ self.setExportMode(True, {'antialias': self.params['antialias'], 'background': self.params['background']})
+ self.getScene().render(painter, QtCore.QRectF(targetRect), sourceRect)
+ finally:
+ self.setExportMode(False)
self.png.save(fileName)
- painter.end()
\ No newline at end of file
+ painter.end()
+
+
\ No newline at end of file
diff --git a/exporters/PrintExporter.py b/exporters/PrintExporter.py
new file mode 100644
index 00000000..12468e9c
--- /dev/null
+++ b/exporters/PrintExporter.py
@@ -0,0 +1,59 @@
+from Exporter import Exporter
+from pyqtgraph.parametertree import Parameter
+from pyqtgraph.Qt import QtGui, QtCore, QtSvg
+import re
+
+#__all__ = ['PrintExporter']
+__all__ = [] ## Printer is disabled for now--does not work very well.
+
+class PrintExporter(Exporter):
+ Name = "Printer"
+ def __init__(self, item):
+ Exporter.__init__(self, item)
+ tr = self.getTargetRect()
+ self.params = Parameter(name='params', type='group', children=[
+ {'name': 'width', 'type': 'float', 'value': 0.1, 'limits': (0, None), 'suffix': 'm', 'siPrefix': True},
+ {'name': 'height', 'type': 'float', 'value': (0.1 * tr.height()) / tr.width(), 'limits': (0, None), 'suffix': 'm', 'siPrefix': True},
+ ])
+ self.params.param('width').sigValueChanged.connect(self.widthChanged)
+ self.params.param('height').sigValueChanged.connect(self.heightChanged)
+
+ def widthChanged(self):
+ sr = self.getSourceRect()
+ ar = sr.height() / sr.width()
+ self.params.param('height').setValue(self.params['width'] * ar, blockSignal=self.heightChanged)
+
+ def heightChanged(self):
+ sr = self.getSourceRect()
+ ar = sr.width() / sr.height()
+ self.params.param('width').setValue(self.params['height'] * ar, blockSignal=self.widthChanged)
+
+ def parameters(self):
+ return self.params
+
+ def export(self, fileName=None):
+ printer = QtGui.QPrinter(QtGui.QPrinter.HighResolution)
+ dialog = QtGui.QPrintDialog(printer)
+ dialog.setWindowTitle("Print Document")
+ if dialog.exec_() != QtGui.QDialog.Accepted:
+ return;
+
+ #self.svg.setSize(QtCore.QSize(100,100))
+ #self.svg.setResolution(600)
+ res = printer.resolution()
+ rect = printer.pageRect()
+ center = rect.center()
+ h = self.params['height'] * res * 100. / 2.54
+ w = self.params['width'] * res * 100. / 2.54
+ x = center.x() - w/2.
+ y = center.y() - h/2.
+
+ targetRect = QtCore.QRect(x, y, w, h)
+ sourceRect = self.getSourceRect()
+ painter = QtGui.QPainter(printer)
+ try:
+ self.setExportMode(True)
+ self.getScene().render(painter, QtCore.QRectF(targetRect), sourceRect)
+ finally:
+ self.setExportMode(False)
+ painter.end()
diff --git a/exporters/SVGExporter.py b/exporters/SVGExporter.py
index 40489628..9158d00c 100644
--- a/exporters/SVGExporter.py
+++ b/exporters/SVGExporter.py
@@ -42,7 +42,11 @@ class SVGExporter(Exporter):
targetRect = QtCore.QRect(0, 0, self.params['width'], self.params['height'])
sourceRect = self.getSourceRect()
painter = QtGui.QPainter(self.svg)
- self.getScene().render(painter, QtCore.QRectF(targetRect), sourceRect)
+ try:
+ self.setExportMode(True)
+ self.render(painter, QtCore.QRectF(targetRect), sourceRect)
+ finally:
+ self.setExportMode(False)
painter.end()
## Workaround to set pen widths correctly
diff --git a/exporters/__init__.py b/exporters/__init__.py
index a73ef2c2..e6ac379c 100644
--- a/exporters/__init__.py
+++ b/exporters/__init__.py
@@ -1,6 +1,24 @@
-from SVGExporter import *
-from ImageExporter import *
-Exporters = [SVGExporter, ImageExporter]
+Exporters = []
+
+import os, sys
+d = os.path.split(__file__)[0]
+files = []
+for f in os.listdir(d):
+ if os.path.isdir(os.path.join(d, f)):
+ files.append(f)
+ elif f[-3:] == '.py' and f not in ['__init__.py', 'Exporter.py']:
+ files.append(f[:-3])
+
+for modName in files:
+ mod = __import__(modName, globals(), locals(), fromlist=['*'])
+ if hasattr(mod, '__all__'):
+ names = mod.__all__
+ else:
+ names = [n for n in dir(mod) if n[0] != '_']
+ for k in names:
+ if hasattr(mod, k):
+ Exporters.append(getattr(mod, k))
+
def listExporters():
return Exporters[:]
diff --git a/graphicsItems/AxisItem.py b/graphicsItems/AxisItem.py
index 31e43b75..4015f8fe 100644
--- a/graphicsItems/AxisItem.py
+++ b/graphicsItems/AxisItem.py
@@ -261,6 +261,9 @@ class AxisItem(GraphicsWidget):
def drawPicture(self, p):
+ p.setRenderHint(p.Antialiasing, False)
+ p.setRenderHint(p.TextAntialiasing, True)
+
prof = debug.Profiler("AxisItem.paint", disabled=True)
p.setPen(self.pen)
diff --git a/graphicsItems/PlotCurveItem.py b/graphicsItems/PlotCurveItem.py
index fcd03448..12ac044c 100644
--- a/graphicsItems/PlotCurveItem.py
+++ b/graphicsItems/PlotCurveItem.py
@@ -27,6 +27,8 @@ class PlotCurveItem(GraphicsObject):
self.clear()
self.path = None
self.fillPath = None
+ self.exportOpts = False
+ self.antialias = False
if y is not None:
self.updateData(y, x)
@@ -364,6 +366,14 @@ class PlotCurveItem(GraphicsObject):
#pen.setColor(c)
##pen.setCosmetic(True)
+ if self.exportOpts is not False:
+ aa = self.exportOpts['antialias']
+ else:
+ aa = self.antialias
+
+ p.setRenderHint(p.Antialiasing, aa)
+
+
if sp is not None:
p.setPen(sp)
p.drawPath(path)
@@ -410,7 +420,13 @@ class PlotCurveItem(GraphicsObject):
ev.accept()
self.sigClicked.emit(self)
-
+ def setExportMode(self, export, opts):
+ if export:
+ self.exportOpts = opts
+ if 'antialias' not in opts:
+ self.exportOpts['antialias'] = True
+ else:
+ self.exportOpts = False
class ROIPlotItem(PlotCurveItem):
"""Plot curve that monitors an ROI and image for changes to automatically replot."""
diff --git a/graphicsItems/PlotItem/PlotItem.py b/graphicsItems/PlotItem/PlotItem.py
index e6e76cb4..78e213d7 100644
--- a/graphicsItems/PlotItem/PlotItem.py
+++ b/graphicsItems/PlotItem/PlotItem.py
@@ -64,6 +64,20 @@ class PlotItem(GraphicsWidget):
managers = {}
def __init__(self, parent=None, name=None, labels=None, title=None, **kargs):
+ """
+ Create a new PlotItem. All arguments are optional.
+ Any extra keyword arguments are passed to PlotItem.plot().
+
+ Arguments:
+ *title* - Title to display at the top of the item. Html is allowed.
+ *labels* - A dictionary specifying the axis labels to display.
+ {'left': (args), 'bottom': (args), ...}
+ The name of each axis and the corresponding arguments are passed to PlotItem.setLabel()
+ Optionally, PlotItem my also be initialized with the keyword arguments left,
+ right, top, or bottom to achieve the same effect.
+ *name* - Registers a name for this view so that others may link to it
+ """
+
GraphicsWidget.__init__(self, parent)
self.setSizePolicy(QtGui.QSizePolicy.Expanding, QtGui.QSizePolicy.Expanding)
@@ -250,12 +264,16 @@ class PlotItem(GraphicsWidget):
#if name is not None:
#self.registerPlot(name)
-
- if labels is not None:
- for k in labels:
- if isinstance(labels[k], basestring):
- labels[k] = (labels[k],)
- self.setLabel(k, *labels[k])
+ if labels is None:
+ labels = {}
+ for label in self.scales.keys():
+ if label in kargs:
+ labels[label] = kargs[label]
+ del kargs[label]
+ for k in labels:
+ if isinstance(labels[k], basestring):
+ labels[k] = (labels[k],)
+ self.setLabel(k, *labels[k])
if title is not None:
self.setTitle(title)
@@ -263,7 +281,7 @@ class PlotItem(GraphicsWidget):
if len(kargs) > 0:
self.plot(**kargs)
- self.enableAutoRange()
+ #self.enableAutoRange()
def implements(self, interface=None):
return interface in ['ViewBoxWrapper']
@@ -365,6 +383,8 @@ class PlotItem(GraphicsWidget):
#print " Referrers are:", refs
#raise
+
+
def updateGrid(self, *args):
g = self.ctrl.gridGroup.isChecked()
if g:
@@ -1313,18 +1333,24 @@ class PlotItem(GraphicsWidget):
return c
- def saveSvgClicked(self):
- self.writeSvg()
+ #def saveSvgClicked(self):
+ #self.writeSvg()
- def saveSvgCurvesClicked(self):
- self.writeSvgCurves()
+ #def saveSvgCurvesClicked(self):
+ #self.writeSvgCurves()
- def saveImgClicked(self):
- self.writeImage()
+ #def saveImgClicked(self):
+ #self.writeImage()
- def saveCsvClicked(self):
- self.writeCsv()
+ #def saveCsvClicked(self):
+ #self.writeCsv()
+ def setExportMode(self, export, opts):
+ if export:
+ self.autoBtn.hide()
+ else:
+ self.autoBtn.show()
+
#class PlotWidgetManager(QtCore.QObject):
diff --git a/graphicsItems/ViewBox/axisCtrlTemplate.py b/graphicsItems/ViewBox/axisCtrlTemplate.py
index b229bf3d..20e2a8c9 100644
--- a/graphicsItems/ViewBox/axisCtrlTemplate.py
+++ b/graphicsItems/ViewBox/axisCtrlTemplate.py
@@ -2,8 +2,8 @@
# Form implementation generated from reading ui file 'axisCtrlTemplate.ui'
#
-# Created: Fri Jan 20 12:41:24 2012
-# by: PyQt4 UI code generator 4.8.3
+# Created: Thu Mar 22 13:13:14 2012
+# by: PyQt4 UI code generator 4.8.5
#
# WARNING! All changes made in this file will be lost!
@@ -19,41 +19,51 @@ class Ui_Form(object):
Form.setObjectName(_fromUtf8("Form"))
Form.resize(182, 120)
Form.setMaximumSize(QtCore.QSize(200, 16777215))
+ Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
self.gridLayout = QtGui.QGridLayout(Form)
self.gridLayout.setSpacing(0)
self.gridLayout.setObjectName(_fromUtf8("gridLayout"))
self.mouseCheck = QtGui.QCheckBox(Form)
+ self.mouseCheck.setText(QtGui.QApplication.translate("Form", "Mouse Enabled", None, QtGui.QApplication.UnicodeUTF8))
self.mouseCheck.setChecked(True)
self.mouseCheck.setObjectName(_fromUtf8("mouseCheck"))
self.gridLayout.addWidget(self.mouseCheck, 0, 1, 1, 2)
self.manualRadio = QtGui.QRadioButton(Form)
+ self.manualRadio.setText(QtGui.QApplication.translate("Form", "Manual", None, QtGui.QApplication.UnicodeUTF8))
self.manualRadio.setObjectName(_fromUtf8("manualRadio"))
self.gridLayout.addWidget(self.manualRadio, 1, 0, 1, 1)
self.minText = QtGui.QLineEdit(Form)
+ self.minText.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8))
self.minText.setObjectName(_fromUtf8("minText"))
self.gridLayout.addWidget(self.minText, 1, 1, 1, 1)
self.maxText = QtGui.QLineEdit(Form)
+ self.maxText.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8))
self.maxText.setObjectName(_fromUtf8("maxText"))
self.gridLayout.addWidget(self.maxText, 1, 2, 1, 1)
self.autoRadio = QtGui.QRadioButton(Form)
+ self.autoRadio.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8))
self.autoRadio.setChecked(True)
self.autoRadio.setObjectName(_fromUtf8("autoRadio"))
self.gridLayout.addWidget(self.autoRadio, 2, 0, 1, 1)
self.autoPercentSpin = QtGui.QSpinBox(Form)
self.autoPercentSpin.setEnabled(True)
+ self.autoPercentSpin.setSuffix(QtGui.QApplication.translate("Form", "%", None, QtGui.QApplication.UnicodeUTF8))
self.autoPercentSpin.setMinimum(1)
self.autoPercentSpin.setMaximum(100)
self.autoPercentSpin.setSingleStep(1)
- self.autoPercentSpin.setProperty(_fromUtf8("value"), 100)
+ self.autoPercentSpin.setProperty("value", 100)
self.autoPercentSpin.setObjectName(_fromUtf8("autoPercentSpin"))
self.gridLayout.addWidget(self.autoPercentSpin, 2, 1, 1, 2)
self.autoPanCheck = QtGui.QCheckBox(Form)
+ self.autoPanCheck.setText(QtGui.QApplication.translate("Form", "Auto Pan Only", None, QtGui.QApplication.UnicodeUTF8))
self.autoPanCheck.setObjectName(_fromUtf8("autoPanCheck"))
self.gridLayout.addWidget(self.autoPanCheck, 3, 1, 1, 2)
self.linkCombo = QtGui.QComboBox(Form)
+ self.linkCombo.setSizeAdjustPolicy(QtGui.QComboBox.AdjustToContents)
self.linkCombo.setObjectName(_fromUtf8("linkCombo"))
self.gridLayout.addWidget(self.linkCombo, 4, 1, 1, 2)
self.label = QtGui.QLabel(Form)
+ self.label.setText(QtGui.QApplication.translate("Form", "Link Axis:", None, QtGui.QApplication.UnicodeUTF8))
self.label.setObjectName(_fromUtf8("label"))
self.gridLayout.addWidget(self.label, 4, 0, 1, 1)
@@ -61,13 +71,5 @@ class Ui_Form(object):
QtCore.QMetaObject.connectSlotsByName(Form)
def retranslateUi(self, Form):
- Form.setWindowTitle(QtGui.QApplication.translate("Form", "Form", None, QtGui.QApplication.UnicodeUTF8))
- self.mouseCheck.setText(QtGui.QApplication.translate("Form", "Mouse Enabled", None, QtGui.QApplication.UnicodeUTF8))
- self.manualRadio.setText(QtGui.QApplication.translate("Form", "Manual", None, QtGui.QApplication.UnicodeUTF8))
- self.minText.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8))
- self.maxText.setText(QtGui.QApplication.translate("Form", "0", None, QtGui.QApplication.UnicodeUTF8))
- self.autoRadio.setText(QtGui.QApplication.translate("Form", "Auto", None, QtGui.QApplication.UnicodeUTF8))
- self.autoPercentSpin.setSuffix(QtGui.QApplication.translate("Form", "%", None, QtGui.QApplication.UnicodeUTF8))
- self.autoPanCheck.setText(QtGui.QApplication.translate("Form", "Auto Pan Only", None, QtGui.QApplication.UnicodeUTF8))
- self.label.setText(QtGui.QApplication.translate("Form", "Link Axis:", None, QtGui.QApplication.UnicodeUTF8))
+ pass
diff --git a/graphicsItems/ViewBox/axisCtrlTemplate.ui b/graphicsItems/ViewBox/axisCtrlTemplate.ui
index f01a3f80..b463923a 100644
--- a/graphicsItems/ViewBox/axisCtrlTemplate.ui
+++ b/graphicsItems/ViewBox/axisCtrlTemplate.ui
@@ -94,7 +94,11 @@
-
-
+
+
+ QComboBox::AdjustToContents
+
+
-