Merge branch 'fabioz-crash' into develop

This commit is contained in:
Luke Campagnola 2014-03-03 13:49:05 -05:00
commit 0045863165
4 changed files with 51 additions and 7 deletions

View File

@ -64,6 +64,7 @@ pyqtgraph-0.9.9 [unreleased]
- Fixed MeshData exception caused when vertexes have no matching faces - Fixed MeshData exception caused when vertexes have no matching faces
- Fixed GLViewWidget exception handler - Fixed GLViewWidget exception handler
- Fixed unicode support in Dock - Fixed unicode support in Dock
- Fixed PySide crash caused by emitting signal from GraphicsObject.itemChange
pyqtgraph-0.9.8 2013-11-24 pyqtgraph-0.9.8 2013-11-24

View File

@ -27,6 +27,7 @@ Contributors
* Mattias Põldaru * Mattias Põldaru
* Thomas S. * Thomas S.
* Mikhail Terekhov * Mikhail Terekhov
* fabioz
Requirements Requirements
------------ ------------

View File

@ -21,7 +21,14 @@ class GraphicsObject(GraphicsItem, QtGui.QGraphicsObject):
ret = QtGui.QGraphicsObject.itemChange(self, change, value) ret = QtGui.QGraphicsObject.itemChange(self, change, value)
if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]: if change in [self.ItemParentHasChanged, self.ItemSceneHasChanged]:
self.parentChanged() self.parentChanged()
if self.__inform_view_on_changes and change in [self.ItemPositionHasChanged, self.ItemTransformHasChanged]: try:
inform_view_on_change = self.__inform_view_on_changes
except AttributeError:
# It's possible that the attribute was already collected when the itemChange happened
# (if it was triggered during the gc of the object).
pass
else:
if inform_view_on_change and change in [self.ItemPositionHasChanged, self.ItemTransformHasChanged]:
self.informViewBoundsChanged() self.informViewBoundsChanged()
## workaround for pyqt bug: ## workaround for pyqt bug:

View File

@ -13,20 +13,54 @@ from ... import getConfigOption
__all__ = ['ViewBox'] __all__ = ['ViewBox']
class WeakList(object):
def __init__(self):
self._items = []
def append(self, obj):
#Add backwards to iterate backwards (to make iterating more efficient on removal).
self._items.insert(0, weakref.ref(obj))
def __iter__(self):
i = len(self._items)-1
while i >= 0:
ref = self._items[i]
d = ref()
if d is None:
del self._items[i]
else:
yield d
i -= 1
class ChildGroup(ItemGroup): class ChildGroup(ItemGroup):
sigItemsChanged = QtCore.Signal()
def __init__(self, parent): def __init__(self, parent):
ItemGroup.__init__(self, parent) ItemGroup.__init__(self, parent)
# Used as callback to inform ViewBox when items are added/removed from
# the group.
# Note 1: We would prefer to override itemChange directly on the
# ViewBox, but this causes crashes on PySide.
# Note 2: We might also like to use a signal rather than this callback
# mechanism, but this causes a different PySide crash.
self.itemsChangedListeners = WeakList()
# excempt from telling view when transform changes # excempt from telling view when transform changes
self._GraphicsObject__inform_view_on_change = False self._GraphicsObject__inform_view_on_change = False
def itemChange(self, change, value): def itemChange(self, change, value):
ret = ItemGroup.itemChange(self, change, value) ret = ItemGroup.itemChange(self, change, value)
if change == self.ItemChildAddedChange or change == self.ItemChildRemovedChange: if change == self.ItemChildAddedChange or change == self.ItemChildRemovedChange:
self.sigItemsChanged.emit() try:
itemsChangedListeners = self.itemsChangedListeners
except AttributeError:
# It's possible that the attribute was already collected when the itemChange happened
# (if it was triggered during the gc of the object).
pass
else:
for listener in itemsChangedListeners:
listener.itemsChanged()
return ret return ret
@ -140,7 +174,7 @@ class ViewBox(GraphicsWidget):
## this is a workaround for a Qt + OpenGL bug that causes improper clipping ## this is a workaround for a Qt + OpenGL bug that causes improper clipping
## https://bugreports.qt.nokia.com/browse/QTBUG-23723 ## https://bugreports.qt.nokia.com/browse/QTBUG-23723
self.childGroup = ChildGroup(self) self.childGroup = ChildGroup(self)
self.childGroup.sigItemsChanged.connect(self.itemsChanged) self.childGroup.itemsChangedListeners.append(self)
self.background = QtGui.QGraphicsRectItem(self.rect()) self.background = QtGui.QGraphicsRectItem(self.rect())
self.background.setParentItem(self) self.background.setParentItem(self)
@ -1187,6 +1221,7 @@ class ViewBox(GraphicsWidget):
y = tr.y() if mask[1] == 1 else None y = tr.y() if mask[1] == 1 else None
self._resetTarget() self._resetTarget()
if x is not None or y is not None:
self.translateBy(x=x, y=y) self.translateBy(x=x, y=y)
self.sigRangeChangedManually.emit(self.state['mouseEnabled']) self.sigRangeChangedManually.emit(self.state['mouseEnabled'])
elif ev.button() & QtCore.Qt.RightButton: elif ev.button() & QtCore.Qt.RightButton: