Remove use of GraphicsScene._addressCache in translateGraphicsItem
Use QGraphicsItem.toQGrapicsObject on the item instead. This probably is not even needed since PyQt 4.9
This commit is contained in:
parent
a76d9daec2
commit
02b7532706
@ -1,5 +1,7 @@
|
|||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
import weakref
|
import weakref
|
||||||
|
import warnings
|
||||||
|
|
||||||
from ..Qt import QtCore, QtGui
|
from ..Qt import QtCore, QtGui
|
||||||
from ..Point import Point
|
from ..Point import Point
|
||||||
from .. import functions as fn
|
from .. import functions as fn
|
||||||
@ -88,15 +90,11 @@ class GraphicsScene(QtGui.QGraphicsScene):
|
|||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def registerObject(cls, obj):
|
def registerObject(cls, obj):
|
||||||
"""
|
warnings.warn(
|
||||||
Workaround for PyQt bug in qgraphicsscene.items()
|
"'registerObject' is deprecated and does nothing.",
|
||||||
All subclasses of QGraphicsObject must register themselves with this function.
|
DeprecationWarning, stacklevel=2
|
||||||
(otherwise, mouse interaction with those objects will likely fail)
|
)
|
||||||
"""
|
|
||||||
if HAVE_SIP and isinstance(obj, sip.wrapper):
|
|
||||||
cls._addressCache[sip.unwrapinstance(sip.cast(obj, QtGui.QGraphicsItem))] = obj
|
|
||||||
|
|
||||||
|
|
||||||
def __init__(self, clickRadius=2, moveDistance=5, parent=None):
|
def __init__(self, clickRadius=2, moveDistance=5, parent=None):
|
||||||
QtGui.QGraphicsScene.__init__(self, parent)
|
QtGui.QGraphicsScene.__init__(self, parent)
|
||||||
self.setClickRadius(clickRadius)
|
self.setClickRadius(clickRadius)
|
||||||
@ -368,46 +366,15 @@ class GraphicsScene(QtGui.QGraphicsScene):
|
|||||||
return ev.isAccepted()
|
return ev.isAccepted()
|
||||||
|
|
||||||
def items(self, *args):
|
def items(self, *args):
|
||||||
#print 'args:', args
|
|
||||||
items = QtGui.QGraphicsScene.items(self, *args)
|
items = QtGui.QGraphicsScene.items(self, *args)
|
||||||
## PyQt bug: items() returns a list of QGraphicsItem instances. If the item is subclassed from QGraphicsObject,
|
return self.translateGraphicsItems(items)
|
||||||
## then the object returned will be different than the actual item that was originally added to the scene
|
|
||||||
items2 = list(map(self.translateGraphicsItem, items))
|
|
||||||
#if HAVE_SIP and isinstance(self, sip.wrapper):
|
|
||||||
#items2 = []
|
|
||||||
#for i in items:
|
|
||||||
#addr = sip.unwrapinstance(sip.cast(i, QtGui.QGraphicsItem))
|
|
||||||
#i2 = GraphicsScene._addressCache.get(addr, i)
|
|
||||||
##print i, "==>", i2
|
|
||||||
#items2.append(i2)
|
|
||||||
#print 'items:', items
|
|
||||||
return items2
|
|
||||||
|
|
||||||
def selectedItems(self, *args):
|
def selectedItems(self, *args):
|
||||||
items = QtGui.QGraphicsScene.selectedItems(self, *args)
|
items = QtGui.QGraphicsScene.selectedItems(self, *args)
|
||||||
## PyQt bug: items() returns a list of QGraphicsItem instances. If the item is subclassed from QGraphicsObject,
|
return self.translateGraphicsItems(items)
|
||||||
## then the object returned will be different than the actual item that was originally added to the scene
|
|
||||||
#if HAVE_SIP and isinstance(self, sip.wrapper):
|
|
||||||
#items2 = []
|
|
||||||
#for i in items:
|
|
||||||
#addr = sip.unwrapinstance(sip.cast(i, QtGui.QGraphicsItem))
|
|
||||||
#i2 = GraphicsScene._addressCache.get(addr, i)
|
|
||||||
##print i, "==>", i2
|
|
||||||
#items2.append(i2)
|
|
||||||
items2 = list(map(self.translateGraphicsItem, items))
|
|
||||||
|
|
||||||
#print 'items:', items
|
|
||||||
return items2
|
|
||||||
|
|
||||||
def itemAt(self, *args):
|
def itemAt(self, *args):
|
||||||
item = QtGui.QGraphicsScene.itemAt(self, *args)
|
item = QtGui.QGraphicsScene.itemAt(self, *args)
|
||||||
|
|
||||||
## PyQt bug: items() returns a list of QGraphicsItem instances. If the item is subclassed from QGraphicsObject,
|
|
||||||
## then the object returned will be different than the actual item that was originally added to the scene
|
|
||||||
#if HAVE_SIP and isinstance(self, sip.wrapper):
|
|
||||||
#addr = sip.unwrapinstance(sip.cast(item, QtGui.QGraphicsItem))
|
|
||||||
#item = GraphicsScene._addressCache.get(addr, item)
|
|
||||||
#return item
|
|
||||||
return self.translateGraphicsItem(item)
|
return self.translateGraphicsItem(item)
|
||||||
|
|
||||||
def itemsNearEvent(self, event, selMode=QtCore.Qt.IntersectsItemShape, sortOrder=QtCore.Qt.DescendingOrder, hoverable=False):
|
def itemsNearEvent(self, event, selMode=QtCore.Qt.IntersectsItemShape, sortOrder=QtCore.Qt.DescendingOrder, hoverable=False):
|
||||||
@ -554,10 +521,14 @@ class GraphicsScene(QtGui.QGraphicsScene):
|
|||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
def translateGraphicsItem(item):
|
def translateGraphicsItem(item):
|
||||||
## for fixing pyqt bugs where the wrong item is returned
|
# This function is intended as a workaround for a problem with older
|
||||||
|
# versions of PyQt (< 4.9?), where methods returning 'QGraphicsItem *'
|
||||||
|
# lose the type of the QGraphicsObject subclasses and instead return
|
||||||
|
# generic QGraphicsItem wrappers.
|
||||||
if HAVE_SIP and isinstance(item, sip.wrapper):
|
if HAVE_SIP and isinstance(item, sip.wrapper):
|
||||||
addr = sip.unwrapinstance(sip.cast(item, QtGui.QGraphicsItem))
|
obj = item.toGraphicsObject()
|
||||||
item = GraphicsScene._addressCache.get(addr, item)
|
if obj is not None:
|
||||||
|
item = obj
|
||||||
return item
|
return item
|
||||||
|
|
||||||
@staticmethod
|
@staticmethod
|
||||||
|
@ -19,8 +19,8 @@ class GraphicsItem(object):
|
|||||||
The GraphicsView system places a lot of emphasis on the notion that the graphics within the scene should be device independent--you should be able to take the same graphics and display them on screens of different resolutions, printers, export to SVG, etc. This is nice in principle, but causes me a lot of headache in practice. It means that I have to circumvent all the device-independent expectations any time I want to operate in pixel coordinates rather than arbitrary scene coordinates. A lot of the code in GraphicsItem is devoted to this task--keeping track of view widgets and device transforms, computing the size and shape of a pixel in local item coordinates, etc. Note that in item coordinates, a pixel does not have to be square or even rectangular, so just asking how to increase a bounding rect by 2px can be a rather complex task.
|
The GraphicsView system places a lot of emphasis on the notion that the graphics within the scene should be device independent--you should be able to take the same graphics and display them on screens of different resolutions, printers, export to SVG, etc. This is nice in principle, but causes me a lot of headache in practice. It means that I have to circumvent all the device-independent expectations any time I want to operate in pixel coordinates rather than arbitrary scene coordinates. A lot of the code in GraphicsItem is devoted to this task--keeping track of view widgets and device transforms, computing the size and shape of a pixel in local item coordinates, etc. Note that in item coordinates, a pixel does not have to be square or even rectangular, so just asking how to increase a bounding rect by 2px can be a rather complex task.
|
||||||
"""
|
"""
|
||||||
_pixelVectorGlobalCache = LRUCache(100, 70)
|
_pixelVectorGlobalCache = LRUCache(100, 70)
|
||||||
|
|
||||||
def __init__(self, register=True):
|
def __init__(self, register=None):
|
||||||
if not hasattr(self, '_qtBaseClass'):
|
if not hasattr(self, '_qtBaseClass'):
|
||||||
for b in self.__class__.__bases__:
|
for b in self.__class__.__bases__:
|
||||||
if issubclass(b, QtGui.QGraphicsItem):
|
if issubclass(b, QtGui.QGraphicsItem):
|
||||||
@ -28,15 +28,18 @@ class GraphicsItem(object):
|
|||||||
break
|
break
|
||||||
if not hasattr(self, '_qtBaseClass'):
|
if not hasattr(self, '_qtBaseClass'):
|
||||||
raise Exception('Could not determine Qt base class for GraphicsItem: %s' % str(self))
|
raise Exception('Could not determine Qt base class for GraphicsItem: %s' % str(self))
|
||||||
|
|
||||||
self._pixelVectorCache = [None, None]
|
self._pixelVectorCache = [None, None]
|
||||||
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.
|
self._exportOpts = False ## If False, not currently exporting. Otherwise, contains dict of export options.
|
||||||
if register:
|
if register is not None and register:
|
||||||
GraphicsScene.registerObject(self) ## workaround for pyqt bug in graphicsscene.items()
|
warnings.warn(
|
||||||
|
"'register' argument is deprecated and does nothing",
|
||||||
|
DeprecationWarning, stacklevel=2
|
||||||
|
)
|
||||||
|
|
||||||
def getViewWidget(self):
|
def getViewWidget(self):
|
||||||
"""
|
"""
|
||||||
Return the view widget for this item.
|
Return the view widget for this item.
|
||||||
|
Loading…
Reference in New Issue
Block a user