diff --git a/examples/VideoSpeedTest.py b/examples/VideoSpeedTest.py index d7a4e1e0..1341ec0e 100644 --- a/examples/VideoSpeedTest.py +++ b/examples/VideoSpeedTest.py @@ -13,7 +13,6 @@ import initExample ## Add path to library (just for examples; you do not need th from pyqtgraph.Qt import QtGui, QtCore, USE_PYSIDE import numpy as np import pyqtgraph as pg -from pyqtgraph import RawImageWidget import scipy.ndimage as ndi import pyqtgraph.ptime as ptime diff --git a/examples/VideoTemplate.ui b/examples/VideoTemplate.ui index d73b0dc9..9560a19b 100644 --- a/examples/VideoTemplate.ui +++ b/examples/VideoTemplate.ui @@ -22,9 +22,6 @@ RawImageWidget - - true - @@ -32,6 +29,9 @@ GraphicsView + ImageItem + + true + @@ -265,7 +265,7 @@ RawImageWidget QWidget -
pyqtgraph
+
pyqtgraph.widgets.RawImageWidget
1
diff --git a/examples/VideoTemplate_pyqt.py b/examples/VideoTemplate_pyqt.py index f61a5e46..91fc1b1e 100644 --- a/examples/VideoTemplate_pyqt.py +++ b/examples/VideoTemplate_pyqt.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file './VideoTemplate.ui' # -# Created: Tue Jul 9 23:38:17 2013 -# by: PyQt4 UI code generator 4.9.3 +# Created: Sat Nov 16 20:07:09 2013 +# by: PyQt4 UI code generator 4.10 # # WARNING! All changes made in this file will be lost! @@ -12,7 +12,16 @@ from PyQt4 import QtCore, QtGui try: _fromUtf8 = QtCore.QString.fromUtf8 except AttributeError: - _fromUtf8 = lambda s: s + def _fromUtf8(s): + return s + +try: + _encoding = QtGui.QApplication.UnicodeUTF8 + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig, _encoding) +except AttributeError: + def _translate(context, text, disambig): + return QtGui.QApplication.translate(context, text, disambig) class Ui_MainWindow(object): def setupUi(self, MainWindow): @@ -25,10 +34,10 @@ class Ui_MainWindow(object): self.gridLayout = QtGui.QGridLayout() self.gridLayout.setObjectName(_fromUtf8("gridLayout")) self.rawRadio = QtGui.QRadioButton(self.centralwidget) - self.rawRadio.setChecked(True) self.rawRadio.setObjectName(_fromUtf8("rawRadio")) self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1) self.gfxRadio = QtGui.QRadioButton(self.centralwidget) + self.gfxRadio.setChecked(True) self.gfxRadio.setObjectName(_fromUtf8("gfxRadio")) self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1) self.stack = QtGui.QStackedWidget(self.centralwidget) @@ -158,23 +167,23 @@ class Ui_MainWindow(object): QtCore.QMetaObject.connectSlotsByName(MainWindow) def retranslateUi(self, MainWindow): - MainWindow.setWindowTitle(QtGui.QApplication.translate("MainWindow", "MainWindow", None, QtGui.QApplication.UnicodeUTF8)) - self.rawRadio.setText(QtGui.QApplication.translate("MainWindow", "RawImageWidget", None, QtGui.QApplication.UnicodeUTF8)) - self.gfxRadio.setText(QtGui.QApplication.translate("MainWindow", "GraphicsView + ImageItem", None, QtGui.QApplication.UnicodeUTF8)) - self.rawGLRadio.setText(QtGui.QApplication.translate("MainWindow", "RawGLImageWidget", None, QtGui.QApplication.UnicodeUTF8)) - self.label.setText(QtGui.QApplication.translate("MainWindow", "Data type", None, QtGui.QApplication.UnicodeUTF8)) - self.dtypeCombo.setItemText(0, QtGui.QApplication.translate("MainWindow", "uint8", None, QtGui.QApplication.UnicodeUTF8)) - self.dtypeCombo.setItemText(1, QtGui.QApplication.translate("MainWindow", "uint16", None, QtGui.QApplication.UnicodeUTF8)) - self.dtypeCombo.setItemText(2, QtGui.QApplication.translate("MainWindow", "float", None, QtGui.QApplication.UnicodeUTF8)) - self.scaleCheck.setText(QtGui.QApplication.translate("MainWindow", "Scale Data", None, QtGui.QApplication.UnicodeUTF8)) - self.rgbLevelsCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8)) - self.label_2.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8)) - self.label_3.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8)) - self.label_4.setText(QtGui.QApplication.translate("MainWindow", "<--->", None, QtGui.QApplication.UnicodeUTF8)) - self.lutCheck.setText(QtGui.QApplication.translate("MainWindow", "Use Lookup Table", None, QtGui.QApplication.UnicodeUTF8)) - self.alphaCheck.setText(QtGui.QApplication.translate("MainWindow", "alpha", None, QtGui.QApplication.UnicodeUTF8)) - self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8)) - self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8)) + MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow", None)) + self.rawRadio.setText(_translate("MainWindow", "RawImageWidget", None)) + self.gfxRadio.setText(_translate("MainWindow", "GraphicsView + ImageItem", None)) + self.rawGLRadio.setText(_translate("MainWindow", "RawGLImageWidget", None)) + self.label.setText(_translate("MainWindow", "Data type", None)) + self.dtypeCombo.setItemText(0, _translate("MainWindow", "uint8", None)) + self.dtypeCombo.setItemText(1, _translate("MainWindow", "uint16", None)) + self.dtypeCombo.setItemText(2, _translate("MainWindow", "float", None)) + self.scaleCheck.setText(_translate("MainWindow", "Scale Data", None)) + self.rgbLevelsCheck.setText(_translate("MainWindow", "RGB", None)) + self.label_2.setText(_translate("MainWindow", "<--->", None)) + self.label_3.setText(_translate("MainWindow", "<--->", None)) + self.label_4.setText(_translate("MainWindow", "<--->", None)) + self.lutCheck.setText(_translate("MainWindow", "Use Lookup Table", None)) + self.alphaCheck.setText(_translate("MainWindow", "alpha", None)) + self.fpsLabel.setText(_translate("MainWindow", "FPS", None)) + self.rgbCheck.setText(_translate("MainWindow", "RGB", None)) -from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget -from pyqtgraph import GradientWidget, SpinBox, GraphicsView, RawImageWidget +from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget, RawImageWidget +from pyqtgraph import GradientWidget, SpinBox, GraphicsView diff --git a/examples/VideoTemplate_pyside.py b/examples/VideoTemplate_pyside.py index d0db5eff..c1f8bc57 100644 --- a/examples/VideoTemplate_pyside.py +++ b/examples/VideoTemplate_pyside.py @@ -2,8 +2,8 @@ # Form implementation generated from reading ui file './VideoTemplate.ui' # -# Created: Tue Jul 9 23:38:19 2013 -# by: pyside-uic 0.2.13 running on PySide 1.1.2 +# Created: Sat Nov 16 20:07:10 2013 +# by: pyside-uic 0.2.14 running on PySide 1.1.2 # # WARNING! All changes made in this file will be lost! @@ -20,10 +20,10 @@ class Ui_MainWindow(object): self.gridLayout = QtGui.QGridLayout() self.gridLayout.setObjectName("gridLayout") self.rawRadio = QtGui.QRadioButton(self.centralwidget) - self.rawRadio.setChecked(True) self.rawRadio.setObjectName("rawRadio") self.gridLayout.addWidget(self.rawRadio, 3, 0, 1, 1) self.gfxRadio = QtGui.QRadioButton(self.centralwidget) + self.gfxRadio.setChecked(True) self.gfxRadio.setObjectName("gfxRadio") self.gridLayout.addWidget(self.gfxRadio, 2, 0, 1, 1) self.stack = QtGui.QStackedWidget(self.centralwidget) @@ -171,5 +171,5 @@ class Ui_MainWindow(object): self.fpsLabel.setText(QtGui.QApplication.translate("MainWindow", "FPS", None, QtGui.QApplication.UnicodeUTF8)) self.rgbCheck.setText(QtGui.QApplication.translate("MainWindow", "RGB", None, QtGui.QApplication.UnicodeUTF8)) -from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget -from pyqtgraph import GradientWidget, SpinBox, GraphicsView, RawImageWidget +from pyqtgraph.widgets.RawImageWidget import RawImageGLWidget, RawImageWidget +from pyqtgraph import GradientWidget, SpinBox, GraphicsView diff --git a/pyqtgraph/graphicsItems/GraphicsWidget.py b/pyqtgraph/graphicsItems/GraphicsWidget.py index 8f28d208..7650b125 100644 --- a/pyqtgraph/graphicsItems/GraphicsWidget.py +++ b/pyqtgraph/graphicsItems/GraphicsWidget.py @@ -20,16 +20,17 @@ class GraphicsWidget(GraphicsItem, QtGui.QGraphicsWidget): ## done by GraphicsItem init #GraphicsScene.registerObject(self) ## workaround for pyqt bug in graphicsscene.items() -## Removed because this causes segmentation faults. Don't know why. -# def itemChange(self, change, value): -# ret = QtGui.QGraphicsWidget.itemChange(self, change, value) ## segv occurs here -# if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]: -# self._updateView() -# return ret + # Removed due to https://bugreports.qt-project.org/browse/PYSIDE-86 + #def itemChange(self, change, value): + ## BEWARE: Calling QGraphicsWidget.itemChange can lead to crashing! + ##ret = QtGui.QGraphicsWidget.itemChange(self, change, value) ## segv occurs here + ## The default behavior is just to return the value argument, so we'll do that + ## without calling the original method. + #ret = value + #if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]: + #self._updateView() + #return ret - #def getMenu(self): - #pass - def setFixedHeight(self, h): self.setMaximumHeight(h) self.setMinimumHeight(h) diff --git a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py index b8404ddc..5ab118f7 100644 --- a/pyqtgraph/graphicsItems/ViewBox/ViewBox.py +++ b/pyqtgraph/graphicsItems/ViewBox/ViewBox.py @@ -93,6 +93,8 @@ class ViewBox(GraphicsWidget): #self.showGrid = showGrid self._matrixNeedsUpdate = True ## indicates that range has changed, but matrix update was deferred self._autoRangeNeedsUpdate = True ## indicates auto-range needs to be recomputed. + + self._lastScene = None ## stores reference to the last known scene this view was a part of. self.state = { @@ -200,18 +202,40 @@ class ViewBox(GraphicsWidget): def implements(self, interface): return interface == 'ViewBox' - def itemChange(self, change, value): - # Note: Calling QWidget.itemChange causes segv in python 3 + PyQt - ret = QtGui.QGraphicsItem.itemChange(self, change, value) - if change == self.ItemSceneChange: - scene = self.scene() - if scene is not None: - scene.sigPrepareForPaint.disconnect(self.prepareForPaint) - elif change == self.ItemSceneHasChanged: - scene = self.scene() - if scene is not None: - scene.sigPrepareForPaint.connect(self.prepareForPaint) - return ret + # removed due to https://bugreports.qt-project.org/browse/PYSIDE-86 + #def itemChange(self, change, value): + ## Note: Calling QWidget.itemChange causes segv in python 3 + PyQt + ##ret = QtGui.QGraphicsItem.itemChange(self, change, value) + #ret = GraphicsWidget.itemChange(self, change, value) + #if change == self.ItemSceneChange: + #scene = self.scene() + #if scene is not None and hasattr(scene, 'sigPrepareForPaint'): + #scene.sigPrepareForPaint.disconnect(self.prepareForPaint) + #elif change == self.ItemSceneHasChanged: + #scene = self.scene() + #if scene is not None and hasattr(scene, 'sigPrepareForPaint'): + #scene.sigPrepareForPaint.connect(self.prepareForPaint) + #return ret + + def checkSceneChange(self): + # ViewBox needs to receive sigPrepareForPaint from its scene before + # being painted. However, we have no way of being informed when the + # scene has changed in order to make this connection. The usual way + # to do this is via itemChange(), but bugs prevent this approach + # (see above). Instead, we simply check at every paint to see whether + # (the scene has changed. + scene = self.scene() + if scene == self._lastScene: + return + if self._lastScene is not None and hasattr(self.lastScene, 'sigPrepareForPaint'): + self._lastScene.sigPrepareForPaint.disconnect(self.prepareForPaint) + if scene is not None and hasattr(scene, 'sigPrepareForPaint'): + scene.sigPrepareForPaint.connect(self.prepareForPaint) + self.prepareForPaint() + self._lastScene = scene + + + def prepareForPaint(self): #autoRangeEnabled = (self.state['autoRange'][0] is not False) or (self.state['autoRange'][1] is not False) @@ -1446,6 +1470,8 @@ class ViewBox(GraphicsWidget): self._matrixNeedsUpdate = False def paint(self, p, opt, widget): + self.checkSceneChange() + if self.border is not None: bounds = self.shape() p.setPen(self.border)