Updated image, SVG, and print exporters. Image export works well; SVG and print still need work.
Added ability to run examples with a specific Qt graphics system
This commit is contained in:
parent
a157d9c4fa
commit
8899e8d858
@ -127,6 +127,9 @@ class ExampleLoader(QtGui.QMainWindow):
|
|||||||
elif self.ui.pysideCheck.isChecked():
|
elif self.ui.pysideCheck.isChecked():
|
||||||
extra.append('pyside')
|
extra.append('pyside')
|
||||||
|
|
||||||
|
if self.ui.forceGraphicsCheck.isChecked():
|
||||||
|
extra.append(str(self.ui.forceGraphicsCombo.currentText()))
|
||||||
|
|
||||||
if fn is None:
|
if fn is None:
|
||||||
return
|
return
|
||||||
if sys.platform.startswith('win'):
|
if sys.platform.startswith('win'):
|
||||||
@ -163,22 +166,26 @@ def buildFileList(examples, files=None):
|
|||||||
buildFileList(val, files)
|
buildFileList(val, files)
|
||||||
return files
|
return files
|
||||||
|
|
||||||
def testFile(name, f, exe, lib):
|
def testFile(name, f, exe, lib, graphicsSystem):
|
||||||
global path
|
global path
|
||||||
fn = os.path.join(path,f)
|
fn = os.path.join(path,f)
|
||||||
#print "starting process: ", fn
|
#print "starting process: ", fn
|
||||||
|
os.chdir(path)
|
||||||
sys.stdout.write(name)
|
sys.stdout.write(name)
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
|
|
||||||
|
import1 = "import %s" % lib if lib != '' else ''
|
||||||
|
import2 = os.path.splitext(os.path.split(fn)[1])[0]
|
||||||
|
graphicsSystem = '' if graphicsSystem is None else "pg.QtGui.QApplication.setGraphicsSystem('%s')" % graphicsSystem
|
||||||
code = """
|
code = """
|
||||||
try:
|
try:
|
||||||
|
%s
|
||||||
|
import pyqtgraph as pg
|
||||||
%s
|
%s
|
||||||
import %s
|
import %s
|
||||||
import sys
|
import sys
|
||||||
print("test complete")
|
print("test complete")
|
||||||
sys.stdout.flush()
|
sys.stdout.flush()
|
||||||
import pyqtgraph as pg
|
|
||||||
import time
|
import time
|
||||||
while True: ## run a little event loop
|
while True: ## run a little event loop
|
||||||
pg.QtGui.QApplication.processEvents()
|
pg.QtGui.QApplication.processEvents()
|
||||||
@ -187,7 +194,7 @@ except:
|
|||||||
print("test failed")
|
print("test failed")
|
||||||
raise
|
raise
|
||||||
|
|
||||||
""" % ("import %s" % lib if lib != '' else "", os.path.splitext(os.path.split(fn)[1])[0])
|
""" % (import1, import2, graphicsSystem)
|
||||||
#print code
|
#print code
|
||||||
process = subprocess.Popen(['exec %s -i' % (exe)], shell=True, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
process = subprocess.Popen(['exec %s -i' % (exe)], shell=True, stdin=subprocess.PIPE, stderr=subprocess.PIPE, stdout=subprocess.PIPE)
|
||||||
process.stdin.write(code.encode('UTF-8'))
|
process.stdin.write(code.encode('UTF-8'))
|
||||||
|
@ -57,6 +57,36 @@
|
|||||||
</item>
|
</item>
|
||||||
</layout>
|
</layout>
|
||||||
</item>
|
</item>
|
||||||
|
<item>
|
||||||
|
<layout class="QHBoxLayout" name="horizontalLayout_2">
|
||||||
|
<item>
|
||||||
|
<widget class="QCheckBox" name="forceGraphicsCheck">
|
||||||
|
<property name="text">
|
||||||
|
<string>Force Graphics System:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<widget class="QComboBox" name="forceGraphicsCombo">
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>native</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>raster</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
<item>
|
||||||
|
<property name="text">
|
||||||
|
<string>opengl</string>
|
||||||
|
</property>
|
||||||
|
</item>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
</layout>
|
||||||
|
</item>
|
||||||
<item>
|
<item>
|
||||||
<widget class="QPushButton" name="loadBtn">
|
<widget class="QPushButton" name="loadBtn">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file './examples/exampleLoaderTemplate.ui'
|
# Form implementation generated from reading ui file './examples/exampleLoaderTemplate.ui'
|
||||||
#
|
#
|
||||||
# Created: Fri Oct 26 07:53:55 2012
|
# Created: Mon Dec 24 00:33:38 2012
|
||||||
# by: PyQt4 UI code generator 4.9.1
|
# by: PyQt4 UI code generator 4.9.1
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
@ -44,6 +44,18 @@ class Ui_Form(object):
|
|||||||
self.pysideCheck.setObjectName(_fromUtf8("pysideCheck"))
|
self.pysideCheck.setObjectName(_fromUtf8("pysideCheck"))
|
||||||
self.horizontalLayout.addWidget(self.pysideCheck)
|
self.horizontalLayout.addWidget(self.pysideCheck)
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||||
|
self.horizontalLayout_2 = QtGui.QHBoxLayout()
|
||||||
|
self.horizontalLayout_2.setObjectName(_fromUtf8("horizontalLayout_2"))
|
||||||
|
self.forceGraphicsCheck = QtGui.QCheckBox(self.layoutWidget)
|
||||||
|
self.forceGraphicsCheck.setObjectName(_fromUtf8("forceGraphicsCheck"))
|
||||||
|
self.horizontalLayout_2.addWidget(self.forceGraphicsCheck)
|
||||||
|
self.forceGraphicsCombo = QtGui.QComboBox(self.layoutWidget)
|
||||||
|
self.forceGraphicsCombo.setObjectName(_fromUtf8("forceGraphicsCombo"))
|
||||||
|
self.forceGraphicsCombo.addItem(_fromUtf8(""))
|
||||||
|
self.forceGraphicsCombo.addItem(_fromUtf8(""))
|
||||||
|
self.forceGraphicsCombo.addItem(_fromUtf8(""))
|
||||||
|
self.horizontalLayout_2.addWidget(self.forceGraphicsCombo)
|
||||||
|
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||||
self.loadBtn = QtGui.QPushButton(self.layoutWidget)
|
self.loadBtn = QtGui.QPushButton(self.layoutWidget)
|
||||||
self.loadBtn.setObjectName(_fromUtf8("loadBtn"))
|
self.loadBtn.setObjectName(_fromUtf8("loadBtn"))
|
||||||
self.verticalLayout.addWidget(self.loadBtn)
|
self.verticalLayout.addWidget(self.loadBtn)
|
||||||
@ -62,5 +74,9 @@ 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))
|
||||||
self.pyqtCheck.setText(QtGui.QApplication.translate("Form", "Force PyQt", None, QtGui.QApplication.UnicodeUTF8))
|
self.pyqtCheck.setText(QtGui.QApplication.translate("Form", "Force PyQt", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
self.pysideCheck.setText(QtGui.QApplication.translate("Form", "Force PySide", None, QtGui.QApplication.UnicodeUTF8))
|
self.pysideCheck.setText(QtGui.QApplication.translate("Form", "Force PySide", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.forceGraphicsCheck.setText(QtGui.QApplication.translate("Form", "Force Graphics System:", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.forceGraphicsCombo.setItemText(0, QtGui.QApplication.translate("Form", "native", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.forceGraphicsCombo.setItemText(1, QtGui.QApplication.translate("Form", "raster", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.forceGraphicsCombo.setItemText(2, QtGui.QApplication.translate("Form", "opengl", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load Example", None, QtGui.QApplication.UnicodeUTF8))
|
self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load Example", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
|
|
||||||
# Form implementation generated from reading ui file './examples/exampleLoaderTemplate.ui'
|
# Form implementation generated from reading ui file './examples/exampleLoaderTemplate.ui'
|
||||||
#
|
#
|
||||||
# Created: Fri Oct 26 07:53:57 2012
|
# Created: Mon Dec 24 00:33:39 2012
|
||||||
# by: pyside-uic 0.2.13 running on PySide 1.1.0
|
# by: pyside-uic 0.2.13 running on PySide 1.1.2
|
||||||
#
|
#
|
||||||
# WARNING! All changes made in this file will be lost!
|
# WARNING! All changes made in this file will be lost!
|
||||||
|
|
||||||
@ -39,6 +39,18 @@ class Ui_Form(object):
|
|||||||
self.pysideCheck.setObjectName("pysideCheck")
|
self.pysideCheck.setObjectName("pysideCheck")
|
||||||
self.horizontalLayout.addWidget(self.pysideCheck)
|
self.horizontalLayout.addWidget(self.pysideCheck)
|
||||||
self.verticalLayout.addLayout(self.horizontalLayout)
|
self.verticalLayout.addLayout(self.horizontalLayout)
|
||||||
|
self.horizontalLayout_2 = QtGui.QHBoxLayout()
|
||||||
|
self.horizontalLayout_2.setObjectName("horizontalLayout_2")
|
||||||
|
self.forceGraphicsCheck = QtGui.QCheckBox(self.layoutWidget)
|
||||||
|
self.forceGraphicsCheck.setObjectName("forceGraphicsCheck")
|
||||||
|
self.horizontalLayout_2.addWidget(self.forceGraphicsCheck)
|
||||||
|
self.forceGraphicsCombo = QtGui.QComboBox(self.layoutWidget)
|
||||||
|
self.forceGraphicsCombo.setObjectName("forceGraphicsCombo")
|
||||||
|
self.forceGraphicsCombo.addItem("")
|
||||||
|
self.forceGraphicsCombo.addItem("")
|
||||||
|
self.forceGraphicsCombo.addItem("")
|
||||||
|
self.horizontalLayout_2.addWidget(self.forceGraphicsCombo)
|
||||||
|
self.verticalLayout.addLayout(self.horizontalLayout_2)
|
||||||
self.loadBtn = QtGui.QPushButton(self.layoutWidget)
|
self.loadBtn = QtGui.QPushButton(self.layoutWidget)
|
||||||
self.loadBtn.setObjectName("loadBtn")
|
self.loadBtn.setObjectName("loadBtn")
|
||||||
self.verticalLayout.addWidget(self.loadBtn)
|
self.verticalLayout.addWidget(self.loadBtn)
|
||||||
@ -57,5 +69,9 @@ 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))
|
||||||
self.pyqtCheck.setText(QtGui.QApplication.translate("Form", "Force PyQt", None, QtGui.QApplication.UnicodeUTF8))
|
self.pyqtCheck.setText(QtGui.QApplication.translate("Form", "Force PyQt", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
self.pysideCheck.setText(QtGui.QApplication.translate("Form", "Force PySide", None, QtGui.QApplication.UnicodeUTF8))
|
self.pysideCheck.setText(QtGui.QApplication.translate("Form", "Force PySide", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.forceGraphicsCheck.setText(QtGui.QApplication.translate("Form", "Force Graphics System:", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.forceGraphicsCombo.setItemText(0, QtGui.QApplication.translate("Form", "native", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.forceGraphicsCombo.setItemText(1, QtGui.QApplication.translate("Form", "raster", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
self.forceGraphicsCombo.setItemText(2, QtGui.QApplication.translate("Form", "opengl", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load Example", None, QtGui.QApplication.UnicodeUTF8))
|
self.loadBtn.setText(QtGui.QApplication.translate("Form", "Load Example", None, QtGui.QApplication.UnicodeUTF8))
|
||||||
|
|
||||||
|
@ -3,6 +3,14 @@ import sys, os
|
|||||||
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
|
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(__file__), '..', '..')))
|
||||||
|
|
||||||
if 'pyside' in sys.argv: ## should force example to use PySide instead of PyQt
|
if 'pyside' in sys.argv: ## should force example to use PySide instead of PyQt
|
||||||
import PySide
|
from PySide import QtGui
|
||||||
elif 'pyqt' in sys.argv:
|
elif 'pyqt' in sys.argv:
|
||||||
import PyQt4
|
from PyQt4 import QtGui
|
||||||
|
else:
|
||||||
|
from pyqtgraph.Qt import QtGui
|
||||||
|
|
||||||
|
for gs in ['raster', 'native', 'opengl']:
|
||||||
|
if gs in sys.argv:
|
||||||
|
QtGui.QApplication.setGraphicsSystem(gs)
|
||||||
|
break
|
||||||
|
|
||||||
|
@ -27,12 +27,12 @@ class ImageExporter(Exporter):
|
|||||||
|
|
||||||
def widthChanged(self):
|
def widthChanged(self):
|
||||||
sr = self.getSourceRect()
|
sr = self.getSourceRect()
|
||||||
ar = sr.height() / sr.width()
|
ar = float(sr.height()) / sr.width()
|
||||||
self.params.param('height').setValue(self.params['width'] * ar, blockSignal=self.heightChanged)
|
self.params.param('height').setValue(self.params['width'] * ar, blockSignal=self.heightChanged)
|
||||||
|
|
||||||
def heightChanged(self):
|
def heightChanged(self):
|
||||||
sr = self.getSourceRect()
|
sr = self.getSourceRect()
|
||||||
ar = sr.width() / sr.height()
|
ar = float(sr.width()) / sr.height()
|
||||||
self.params.param('width').setValue(self.params['height'] * ar, blockSignal=self.widthChanged)
|
self.params.param('width').setValue(self.params['height'] * ar, blockSignal=self.widthChanged)
|
||||||
|
|
||||||
def parameters(self):
|
def parameters(self):
|
||||||
@ -51,6 +51,8 @@ class ImageExporter(Exporter):
|
|||||||
|
|
||||||
targetRect = QtCore.QRect(0, 0, self.params['width'], self.params['height'])
|
targetRect = QtCore.QRect(0, 0, self.params['width'], self.params['height'])
|
||||||
sourceRect = self.getSourceRect()
|
sourceRect = self.getSourceRect()
|
||||||
|
|
||||||
|
|
||||||
#self.png = QtGui.QImage(targetRect.size(), QtGui.QImage.Format_ARGB32)
|
#self.png = QtGui.QImage(targetRect.size(), QtGui.QImage.Format_ARGB32)
|
||||||
#self.png.fill(pyqtgraph.mkColor(self.params['background']))
|
#self.png.fill(pyqtgraph.mkColor(self.params['background']))
|
||||||
bg = np.empty((self.params['width'], self.params['height'], 4), dtype=np.ubyte)
|
bg = np.empty((self.params['width'], self.params['height'], 4), dtype=np.ubyte)
|
||||||
@ -60,11 +62,19 @@ class ImageExporter(Exporter):
|
|||||||
bg[:,:,2] = color.red()
|
bg[:,:,2] = color.red()
|
||||||
bg[:,:,3] = color.alpha()
|
bg[:,:,3] = color.alpha()
|
||||||
self.png = pg.makeQImage(bg, alpha=True)
|
self.png = pg.makeQImage(bg, alpha=True)
|
||||||
|
|
||||||
|
## set resolution of image:
|
||||||
|
origTargetRect = self.getTargetRect()
|
||||||
|
resolutionScale = targetRect.width() / origTargetRect.width()
|
||||||
|
#self.png.setDotsPerMeterX(self.png.dotsPerMeterX() * resolutionScale)
|
||||||
|
#self.png.setDotsPerMeterY(self.png.dotsPerMeterY() * resolutionScale)
|
||||||
|
|
||||||
painter = QtGui.QPainter(self.png)
|
painter = QtGui.QPainter(self.png)
|
||||||
|
#dtr = painter.deviceTransform()
|
||||||
try:
|
try:
|
||||||
self.setExportMode(True, {'antialias': self.params['antialias'], 'background': self.params['background']})
|
self.setExportMode(True, {'antialias': self.params['antialias'], 'background': self.params['background'], 'painter': painter, 'resolutionScale': resolutionScale})
|
||||||
painter.setRenderHint(QtGui.QPainter.Antialiasing, self.params['antialias'])
|
painter.setRenderHint(QtGui.QPainter.Antialiasing, self.params['antialias'])
|
||||||
self.getScene().render(painter, QtCore.QRectF(targetRect), sourceRect)
|
self.getScene().render(painter, QtCore.QRectF(targetRect), QtCore.QRectF(sourceRect))
|
||||||
finally:
|
finally:
|
||||||
self.setExportMode(False)
|
self.setExportMode(False)
|
||||||
painter.end()
|
painter.end()
|
||||||
|
@ -3,8 +3,8 @@ from pyqtgraph.parametertree import Parameter
|
|||||||
from pyqtgraph.Qt import QtGui, QtCore, QtSvg
|
from pyqtgraph.Qt import QtGui, QtCore, QtSvg
|
||||||
import re
|
import re
|
||||||
|
|
||||||
#__all__ = ['PrintExporter']
|
__all__ = ['PrintExporter']
|
||||||
__all__ = [] ## Printer is disabled for now--does not work very well.
|
#__all__ = [] ## Printer is disabled for now--does not work very well.
|
||||||
|
|
||||||
class PrintExporter(Exporter):
|
class PrintExporter(Exporter):
|
||||||
Name = "Printer"
|
Name = "Printer"
|
||||||
@ -38,9 +38,15 @@ class PrintExporter(Exporter):
|
|||||||
if dialog.exec_() != QtGui.QDialog.Accepted:
|
if dialog.exec_() != QtGui.QDialog.Accepted:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
#dpi = QtGui.QDesktopWidget().physicalDpiX()
|
||||||
|
|
||||||
#self.svg.setSize(QtCore.QSize(100,100))
|
#self.svg.setSize(QtCore.QSize(100,100))
|
||||||
#self.svg.setResolution(600)
|
#self.svg.setResolution(600)
|
||||||
res = printer.resolution()
|
#res = printer.resolution()
|
||||||
|
sr = self.getSourceRect()
|
||||||
|
#res = sr.width() * .4 / (self.params['width'] * 100 / 2.54)
|
||||||
|
res = QtGui.QDesktopWidget().physicalDpiX()
|
||||||
|
printer.setResolution(res)
|
||||||
rect = printer.pageRect()
|
rect = printer.pageRect()
|
||||||
center = rect.center()
|
center = rect.center()
|
||||||
h = self.params['height'] * res * 100. / 2.54
|
h = self.params['height'] * res * 100. / 2.54
|
||||||
@ -52,8 +58,8 @@ class PrintExporter(Exporter):
|
|||||||
sourceRect = self.getSourceRect()
|
sourceRect = self.getSourceRect()
|
||||||
painter = QtGui.QPainter(printer)
|
painter = QtGui.QPainter(printer)
|
||||||
try:
|
try:
|
||||||
self.setExportMode(True)
|
self.setExportMode(True, {'painter': painter})
|
||||||
self.getScene().render(painter, QtCore.QRectF(targetRect), sourceRect)
|
self.getScene().render(painter, QtCore.QRectF(targetRect), QtCore.QRectF(sourceRect))
|
||||||
finally:
|
finally:
|
||||||
self.setExportMode(False)
|
self.setExportMode(False)
|
||||||
painter.end()
|
painter.end()
|
||||||
|
@ -46,7 +46,7 @@ class SVGExporter(Exporter):
|
|||||||
|
|
||||||
painter = QtGui.QPainter(self.svg)
|
painter = QtGui.QPainter(self.svg)
|
||||||
try:
|
try:
|
||||||
self.setExportMode(True)
|
self.setExportMode(True, {'painter': painter,})
|
||||||
self.render(painter, QtCore.QRectF(targetRect), sourceRect)
|
self.render(painter, QtCore.QRectF(targetRect), sourceRect)
|
||||||
finally:
|
finally:
|
||||||
self.setExportMode(False)
|
self.setExportMode(False)
|
||||||
|
@ -54,3 +54,8 @@ class ArrowItem(QtGui.QGraphicsPathItem):
|
|||||||
def paint(self, p, *args):
|
def paint(self, p, *args):
|
||||||
p.setRenderHint(QtGui.QPainter.Antialiasing)
|
p.setRenderHint(QtGui.QPainter.Antialiasing)
|
||||||
QtGui.QGraphicsPathItem.paint(self, p, *args)
|
QtGui.QGraphicsPathItem.paint(self, p, *args)
|
||||||
|
|
||||||
|
def shape(self):
|
||||||
|
#if not self.opts['pxMode']:
|
||||||
|
#return QtGui.QGraphicsPathItem.shape(self)
|
||||||
|
return self.path
|
@ -28,10 +28,13 @@ class GraphicsItem(object):
|
|||||||
self._viewWidget = None
|
self._viewWidget = None
|
||||||
self._viewBox = None
|
self._viewBox = None
|
||||||
self._connectedView = None
|
self._connectedView = None
|
||||||
|
self._exportOpts = False ## If False, not currently exporting. Otherwise, contains dict of export options.
|
||||||
if register:
|
if register:
|
||||||
GraphicsScene.registerObject(self) ## workaround for pyqt bug in graphicsscene.items()
|
GraphicsScene.registerObject(self) ## workaround for pyqt bug in graphicsscene.items()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def getViewWidget(self):
|
def getViewWidget(self):
|
||||||
"""
|
"""
|
||||||
Return the view widget for this item. If the scene has multiple views, only the first view is returned.
|
Return the view widget for this item. If the scene has multiple views, only the first view is returned.
|
||||||
@ -82,6 +85,9 @@ class GraphicsItem(object):
|
|||||||
Return the transform that converts local item coordinates to device coordinates (usually pixels).
|
Return the transform that converts local item coordinates to device coordinates (usually pixels).
|
||||||
Extends deviceTransform to automatically determine the viewportTransform.
|
Extends deviceTransform to automatically determine the viewportTransform.
|
||||||
"""
|
"""
|
||||||
|
if self._exportOpts is not False and 'painter' in self._exportOpts: ## currently exporting; device transform may be different.
|
||||||
|
return self._exportOpts['painter'].deviceTransform()
|
||||||
|
|
||||||
if viewportTransform is None:
|
if viewportTransform is None:
|
||||||
view = self.getViewWidget()
|
view = self.getViewWidget()
|
||||||
if view is None:
|
if view is None:
|
||||||
@ -476,4 +482,16 @@ class GraphicsItem(object):
|
|||||||
return tree
|
return tree
|
||||||
|
|
||||||
|
|
||||||
|
def setExportMode(self, export, opts):
|
||||||
|
"""
|
||||||
|
This method is called by exporters to inform items that they are being drawn for export
|
||||||
|
with a specific set of options. Items access these via self._exportOptions.
|
||||||
|
When exporting is complete, _exportOptions is set to False.
|
||||||
|
"""
|
||||||
|
if export:
|
||||||
|
self._exportOpts = opts
|
||||||
|
#if 'antialias' not in opts:
|
||||||
|
#self._exportOpts['antialias'] = True
|
||||||
|
else:
|
||||||
|
self._exportOpts = False
|
||||||
|
|
@ -52,7 +52,6 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
self.clear()
|
self.clear()
|
||||||
self.path = None
|
self.path = None
|
||||||
self.fillPath = None
|
self.fillPath = None
|
||||||
self.exportOpts = False
|
|
||||||
|
|
||||||
|
|
||||||
## this is disastrous for performance.
|
## this is disastrous for performance.
|
||||||
@ -404,8 +403,8 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
path = self.path
|
path = self.path
|
||||||
prof.mark('generate path')
|
prof.mark('generate path')
|
||||||
|
|
||||||
if self.exportOpts is not False:
|
if self._exportOpts is not False:
|
||||||
aa = self.exportOpts['antialias']
|
aa = self._exportOpts.get('antialias', True)
|
||||||
else:
|
else:
|
||||||
aa = self.opts['antialias']
|
aa = self.opts['antialias']
|
||||||
|
|
||||||
@ -487,13 +486,6 @@ class PlotCurveItem(GraphicsObject):
|
|||||||
ev.accept()
|
ev.accept()
|
||||||
self.sigClicked.emit(self)
|
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):
|
class ROIPlotItem(PlotCurveItem):
|
||||||
"""Plot curve that monitors an ROI and image for changes to automatically replot."""
|
"""Plot curve that monitors an ROI and image for changes to automatically replot."""
|
||||||
|
@ -239,7 +239,6 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
'useCache': True, ## If useCache is False, symbols are re-drawn on every paint.
|
'useCache': True, ## If useCache is False, symbols are re-drawn on every paint.
|
||||||
'antialias': pg.getConfigOption('antialias'),
|
'antialias': pg.getConfigOption('antialias'),
|
||||||
}
|
}
|
||||||
self.exportOpts = False
|
|
||||||
|
|
||||||
self.setPen(200,200,200, update=False)
|
self.setPen(200,200,200, update=False)
|
||||||
self.setBrush(100,100,150, update=False)
|
self.setBrush(100,100,150, update=False)
|
||||||
@ -546,7 +545,7 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
if invalidate:
|
if invalidate:
|
||||||
self.invalidate()
|
self.invalidate()
|
||||||
|
|
||||||
def getSpotOpts(self, recs):
|
def getSpotOpts(self, recs, scale=1.0):
|
||||||
if recs.ndim == 0:
|
if recs.ndim == 0:
|
||||||
rec = recs
|
rec = recs
|
||||||
symbol = rec['symbol']
|
symbol = rec['symbol']
|
||||||
@ -561,11 +560,12 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
brush = rec['brush']
|
brush = rec['brush']
|
||||||
if brush is None:
|
if brush is None:
|
||||||
brush = self.opts['brush']
|
brush = self.opts['brush']
|
||||||
return (symbol, size, fn.mkPen(pen), fn.mkBrush(brush))
|
return (symbol, size*scale, fn.mkPen(pen), fn.mkBrush(brush))
|
||||||
else:
|
else:
|
||||||
recs = recs.copy()
|
recs = recs.copy()
|
||||||
recs['symbol'][np.equal(recs['symbol'], None)] = self.opts['symbol']
|
recs['symbol'][np.equal(recs['symbol'], None)] = self.opts['symbol']
|
||||||
recs['size'][np.equal(recs['size'], -1)] = self.opts['size']
|
recs['size'][np.equal(recs['size'], -1)] = self.opts['size']
|
||||||
|
recs['size'] *= scale
|
||||||
recs['pen'][np.equal(recs['pen'], None)] = fn.mkPen(self.opts['pen'])
|
recs['pen'][np.equal(recs['pen'], None)] = fn.mkPen(self.opts['pen'])
|
||||||
recs['brush'][np.equal(recs['brush'], None)] = fn.mkBrush(self.opts['brush'])
|
recs['brush'][np.equal(recs['brush'], None)] = fn.mkBrush(self.opts['brush'])
|
||||||
return recs
|
return recs
|
||||||
@ -675,18 +675,20 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
rect = QtCore.QRectF(y, x, h, w)
|
rect = QtCore.QRectF(y, x, h, w)
|
||||||
self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect))
|
self.fragments.append(QtGui.QPainter.PixmapFragment.create(pos, rect))
|
||||||
|
|
||||||
def setExportMode(self, export, opts):
|
def setExportMode(self, *args, **kwds):
|
||||||
if export:
|
GraphicsObject.setExportMode(self, *args, **kwds)
|
||||||
self.exportOpts = opts
|
self.invalidate()
|
||||||
if 'antialias' not in opts:
|
|
||||||
self.exportOpts['antialias'] = True
|
|
||||||
else:
|
|
||||||
self.exportOpts = False
|
|
||||||
|
|
||||||
|
|
||||||
def paint(self, p, *args):
|
def paint(self, p, *args):
|
||||||
#p.setPen(fn.mkPen('r'))
|
#p.setPen(fn.mkPen('r'))
|
||||||
#p.drawRect(self.boundingRect())
|
#p.drawRect(self.boundingRect())
|
||||||
|
if self._exportOpts is not False:
|
||||||
|
aa = self._exportOpts.get('antialias', True)
|
||||||
|
scale = self._exportOpts.get('resolutionScale', 1.0) ## exporting to image; pixel resolution may have changed
|
||||||
|
else:
|
||||||
|
aa = self.opts['antialias']
|
||||||
|
scale = 1.0
|
||||||
|
|
||||||
if self.opts['pxMode'] is True:
|
if self.opts['pxMode'] is True:
|
||||||
atlas = self.fragmentAtlas.getAtlas()
|
atlas = self.fragmentAtlas.getAtlas()
|
||||||
#arr = fn.imageToArray(atlas.toImage(), copy=True)
|
#arr = fn.imageToArray(atlas.toImage(), copy=True)
|
||||||
@ -701,13 +703,9 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
|
|
||||||
p.resetTransform()
|
p.resetTransform()
|
||||||
|
|
||||||
if not USE_PYSIDE and self.opts['useCache'] and self.exportOpts is False:
|
if not USE_PYSIDE and self.opts['useCache'] and self._exportOpts is False:
|
||||||
p.drawPixmapFragments(self.fragments, atlas)
|
p.drawPixmapFragments(self.fragments, atlas)
|
||||||
else:
|
else:
|
||||||
if self.exportOpts is not False:
|
|
||||||
aa = self.exportOpts['antialias']
|
|
||||||
else:
|
|
||||||
aa = self.opts['antialias']
|
|
||||||
p.setRenderHint(p.Antialiasing, aa)
|
p.setRenderHint(p.Antialiasing, aa)
|
||||||
|
|
||||||
for i in range(len(self.data)):
|
for i in range(len(self.data)):
|
||||||
@ -715,23 +713,20 @@ class ScatterPlotItem(GraphicsObject):
|
|||||||
frag = self.fragments[i]
|
frag = self.fragments[i]
|
||||||
p.resetTransform()
|
p.resetTransform()
|
||||||
p.translate(frag.x, frag.y)
|
p.translate(frag.x, frag.y)
|
||||||
drawSymbol(p, *self.getSpotOpts(rec))
|
drawSymbol(p, *self.getSpotOpts(rec, scale))
|
||||||
else:
|
else:
|
||||||
if self.picture is None:
|
if self.picture is None:
|
||||||
self.picture = QtGui.QPicture()
|
self.picture = QtGui.QPicture()
|
||||||
p2 = QtGui.QPainter(self.picture)
|
p2 = QtGui.QPainter(self.picture)
|
||||||
for rec in self.data:
|
for rec in self.data:
|
||||||
|
if scale != 1.0:
|
||||||
|
rec = rec.copy()
|
||||||
|
rec['size'] *= scale
|
||||||
p2.resetTransform()
|
p2.resetTransform()
|
||||||
p2.translate(rec['x'], rec['y'])
|
p2.translate(rec['x'], rec['y'])
|
||||||
drawSymbol(p2, *self.getSpotOpts(rec))
|
drawSymbol(p2, *self.getSpotOpts(rec, scale))
|
||||||
p2.end()
|
p2.end()
|
||||||
|
|
||||||
if self.exportOpts is not False:
|
|
||||||
aa = self.exportOpts['antialias']
|
|
||||||
else:
|
|
||||||
aa = self.opts['antialias']
|
|
||||||
p.setRenderHint(p.Antialiasing, aa)
|
|
||||||
self.picture.play(p)
|
self.picture.play(p)
|
||||||
|
|
||||||
|
|
||||||
|
@ -27,25 +27,27 @@ class TextItem(UIGraphicsItem):
|
|||||||
#*angle* Angle in degrees to rotate text (note that the rotation assigned in this item's
|
#*angle* Angle in degrees to rotate text (note that the rotation assigned in this item's
|
||||||
#transformation will be ignored)
|
#transformation will be ignored)
|
||||||
|
|
||||||
|
self.anchor = pg.Point(anchor)
|
||||||
|
#self.angle = 0
|
||||||
UIGraphicsItem.__init__(self)
|
UIGraphicsItem.__init__(self)
|
||||||
self.textItem = QtGui.QGraphicsTextItem()
|
self.textItem = QtGui.QGraphicsTextItem()
|
||||||
|
self.textItem.setParentItem(self)
|
||||||
self.lastTransform = None
|
self.lastTransform = None
|
||||||
self._bounds = QtCore.QRectF()
|
self._bounds = QtCore.QRectF()
|
||||||
if html is None:
|
if html is None:
|
||||||
self.setText(text, color)
|
self.setText(text, color)
|
||||||
else:
|
else:
|
||||||
self.setHtml(html)
|
self.setHtml(html)
|
||||||
self.anchor = pg.Point(anchor)
|
|
||||||
self.fill = pg.mkBrush(fill)
|
self.fill = pg.mkBrush(fill)
|
||||||
self.border = pg.mkPen(border)
|
self.border = pg.mkPen(border)
|
||||||
self.angle = angle
|
self.rotate(angle)
|
||||||
#self.setFlag(self.ItemIgnoresTransformations) ## This is required to keep the text unscaled inside the viewport
|
self.setFlag(self.ItemIgnoresTransformations) ## This is required to keep the text unscaled inside the viewport
|
||||||
|
|
||||||
def setText(self, text, color=(200,200,200)):
|
def setText(self, text, color=(200,200,200)):
|
||||||
color = pg.mkColor(color)
|
color = pg.mkColor(color)
|
||||||
self.textItem.setDefaultTextColor(color)
|
self.textItem.setDefaultTextColor(color)
|
||||||
self.textItem.setPlainText(text)
|
self.textItem.setPlainText(text)
|
||||||
|
self.updateText()
|
||||||
#html = '<span style="color: #%s; text-align: center;">%s</span>' % (color, text)
|
#html = '<span style="color: #%s; text-align: center;">%s</span>' % (color, text)
|
||||||
#self.setHtml(html)
|
#self.setHtml(html)
|
||||||
|
|
||||||
@ -70,38 +72,41 @@ class TextItem(UIGraphicsItem):
|
|||||||
self.textItem.setFont(*args)
|
self.textItem.setFont(*args)
|
||||||
self.updateText()
|
self.updateText()
|
||||||
|
|
||||||
|
#def setAngle(self, angle):
|
||||||
|
#self.angle = angle
|
||||||
|
#self.updateText()
|
||||||
|
|
||||||
|
|
||||||
def updateText(self):
|
def updateText(self):
|
||||||
self.viewRangeChanged()
|
|
||||||
|
|
||||||
#def getImage(self):
|
## Needed to maintain font size when rendering to image with increased resolution
|
||||||
#if self.img is None:
|
self.textItem.resetTransform()
|
||||||
#br = self.textItem.boundingRect()
|
#self.textItem.rotate(self.angle)
|
||||||
#img = QtGui.QImage(int(br.width()), int(br.height()), QtGui.QImage.Format_ARGB32)
|
if self._exportOpts is not False and 'resolutionScale' in self._exportOpts:
|
||||||
#p = QtGui.QPainter(img)
|
s = self._exportOpts['resolutionScale']
|
||||||
#self.textItem.paint(p, QtGui.QStyleOptionGraphicsItem(), None)
|
self.textItem.scale(s, s)
|
||||||
#p.end()
|
|
||||||
#self.img = img
|
|
||||||
#return self.img
|
|
||||||
|
|
||||||
def textBoundingRect(self):
|
#br = self.textItem.mapRectToParent(self.textItem.boundingRect())
|
||||||
## return the bounds of the text box in device coordinates
|
self.textItem.setPos(0,0)
|
||||||
pos = self.mapToDevice(QtCore.QPointF(0,0))
|
br = self.textItem.boundingRect()
|
||||||
if pos is None:
|
apos = self.textItem.mapToParent(pg.Point(br.width()*self.anchor.x(), br.height()*self.anchor.y()))
|
||||||
return None
|
#print br, apos
|
||||||
tbr = self.textItem.boundingRect()
|
self.textItem.setPos(-apos.x(), -apos.y())
|
||||||
return QtCore.QRectF(pos.x() - tbr.width()*self.anchor.x(), pos.y() - tbr.height()*self.anchor.y(), tbr.width(), tbr.height())
|
|
||||||
|
#def textBoundingRect(self):
|
||||||
|
### return the bounds of the text box in device coordinates
|
||||||
|
#pos = self.mapToDevice(QtCore.QPointF(0,0))
|
||||||
|
#if pos is None:
|
||||||
|
#return None
|
||||||
|
#tbr = self.textItem.boundingRect()
|
||||||
|
#return QtCore.QRectF(pos.x() - tbr.width()*self.anchor.x(), pos.y() - tbr.height()*self.anchor.y(), tbr.width(), tbr.height())
|
||||||
|
|
||||||
|
|
||||||
def viewRangeChanged(self):
|
def viewRangeChanged(self):
|
||||||
br = self.textBoundingRect()
|
self.updateText()
|
||||||
if br is None:
|
|
||||||
return
|
|
||||||
self.prepareGeometryChange()
|
|
||||||
self._bounds = fn.invertQTransform(self.deviceTransform()).mapRect(br)
|
|
||||||
#print self._bounds
|
|
||||||
|
|
||||||
def boundingRect(self):
|
def boundingRect(self):
|
||||||
return self._bounds
|
return self.textItem.mapToParent(self.textItem.boundingRect()).boundingRect()
|
||||||
|
|
||||||
def paint(self, p, *args):
|
def paint(self, p, *args):
|
||||||
tr = p.transform()
|
tr = p.transform()
|
||||||
@ -110,23 +115,9 @@ class TextItem(UIGraphicsItem):
|
|||||||
self.viewRangeChanged()
|
self.viewRangeChanged()
|
||||||
self.lastTransform = tr
|
self.lastTransform = tr
|
||||||
|
|
||||||
|
|
||||||
tbr = self.textBoundingRect()
|
|
||||||
|
|
||||||
#p.setPen(pg.mkPen('r'))
|
|
||||||
#p.drawRect(self.boundingRect())
|
|
||||||
|
|
||||||
p.setPen(self.border)
|
p.setPen(self.border)
|
||||||
p.setBrush(self.fill)
|
p.setBrush(self.fill)
|
||||||
|
p.setRenderHint(p.Antialiasing, True)
|
||||||
|
p.drawPolygon(self.textItem.mapToParent(self.textItem.boundingRect()))
|
||||||
|
|
||||||
|
|
||||||
#p.fillRect(tbr)
|
|
||||||
p.resetTransform()
|
|
||||||
#p.drawRect(tbr)
|
|
||||||
|
|
||||||
|
|
||||||
p.translate(tbr.left(), tbr.top())
|
|
||||||
p.rotate(self.angle)
|
|
||||||
p.drawRect(QtCore.QRectF(0, 0, tbr.width(), tbr.height()))
|
|
||||||
self.textItem.paint(p, QtGui.QStyleOptionGraphicsItem(), None)
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user