source: orange/Orange/OrangeCanvas/canvas/items/utils.py @ 11203:7dc5309b3942

Revision 11203:7dc5309b3942, 2.9 KB checked in by Ales Erjavec <ales.erjavec@…>, 17 months ago (diff)

Check for None in toGraphicsObjectIfPossible, fix event filter return values.

Line 
1import numpy
2
3import sip
4
5from PyQt4.QtGui import QColor, QRadialGradient
6from PyQt4.QtCore import QObject, QSignalMapper
7from PyQt4.QtCore import pyqtSignal as Signal
8
9
10def saturated(color, factor=150):
11    """Return a saturated color.
12    """
13    h = color.hsvHueF()
14    s = color.hsvSaturationF()
15    v = color.valueF()
16    a = color.alphaF()
17    s = factor * s / 100.0
18    s = max(min(1.0, s), 0.0)
19    return QColor.fromHsvF(h, s, v, a).convertTo(color.spec())
20
21
22def sample_path(path, num=10):
23    """Sample `num` equidistant points from the `path` (`QPainterPath`).
24    """
25    space = numpy.linspace(0.0, 1.0, num, endpoint=True)
26    return [path.pointAtPercent(float(p)) for p in space]
27
28
29def radial_gradient(color, color_light=50):
30    """
31    radial_gradient(QColor, QColor)
32    radial_gradient(QColor, int)
33
34    Return a radial gradient. `color_light` can be a QColor or an int.
35    In the later case the light color is derived from `color` using
36    `saturated(color, color_light)`.
37
38    """
39    if not isinstance(color_light, QColor):
40        color_light = saturated(color, color_light)
41    gradient = QRadialGradient(0.5, 0.5, 0.5)
42    gradient.setColorAt(0.0, color_light)
43    gradient.setColorAt(0.5, color_light)
44    gradient.setColorAt(1.0, color)
45    gradient.setCoordinateMode(QRadialGradient.ObjectBoundingMode)
46    return gradient
47
48
49def toGraphicsObjectIfPossible(item):
50    """Return the item as a QGraphicsObject if possible.
51
52    This function is intended as a workaround for a problem with older
53    versions of PyQt (< 4.9), where methods returning 'QGraphicsItem *'
54    lose the type of the QGraphicsObject subclasses and instead return
55    generic QGraphicsItem wrappers.
56
57    """
58    if item is None:
59        return None
60
61    obj = item.toGraphicsObject()
62    return item if obj is None else obj
63
64
65def typed_signal_mapper(pyType):
66    """Create a TypedSignalMapper class supporting signal
67    mapping for `pyType` (the default QSigalMapper only supports
68    int, string, QObject and QWidget (but not for instance QGraphicsItem).
69
70    """
71
72    def unwrap(obj):
73        return sip.unwrapinstance(sip.cast(obj, QObject))
74
75    class TypedSignalMapper(QSignalMapper):
76        pyMapped = Signal(pyType)
77
78        def __init__(self, parent=None):
79            QSignalMapper.__init__(self, parent)
80            self.__mapping = {}
81
82        def setPyMapping(self, sender, mapped):
83            sender_id = unwrap(sender)
84            self.__mapping[sender_id] = mapped
85            sender.destroyed.connect(self.removePyMappings)
86
87        def removePyMappings(self, sender):
88            sender_id = unwrap(sender)
89            del self.__mapping[sender_id]
90            sender.destroyed.disconnect(self.removePyMappings)
91
92        def pyMap(self, sender=None):
93            if sender is None:
94                sender = self.sender()
95
96            sender_id = unwrap(sender)
97            mapped = self.__mapping[sender_id]
98            self.pyMapped.emit(mapped)
99
100    return TypedSignalMapper
Note: See TracBrowser for help on using the repository browser.