[ui.utils] makeProperty: generate and store reset calllback on instance

* change 'destroyCallback' function to 'resetOnDestroy' boolean parameter
* create a dedicated lambda to reset value to None when object is destroyed and attach it to the target instance
* only way to keep a reference to this function that can be used for destroyed signal (dis)connection with instance accessible
This commit is contained in:
Yann Lanthony 2018-12-13 15:51:45 +01:00
parent b2e1743a6f
commit 1f2baf43c3
2 changed files with 19 additions and 10 deletions

View file

@ -495,8 +495,8 @@ class UIGraph(QObject):
selectedNodeChanged = Signal() selectedNodeChanged = Signal()
# Currently selected node # Currently selected node
selectedNode = makeProperty(QObject, "_selectedNode", selectedNodeChanged, clearNodeSelection) selectedNode = makeProperty(QObject, "_selectedNode", selectedNodeChanged, resetOnDestroy=True)
hoveredNodeChanged = Signal() hoveredNodeChanged = Signal()
# Currently hovered node # Currently hovered node
hoveredNode = makeProperty(QObject, "_hoveredNode", hoveredNodeChanged, clearNodeHover) hoveredNode = makeProperty(QObject, "_hoveredNode", hoveredNodeChanged, resetOnDestroy=True)

View file

@ -194,7 +194,7 @@ class QmlInstantEngine(QQmlApplicationEngine):
self.load(self._sourceFile) self.load(self._sourceFile)
def makeProperty(T, attributeName, notify=None, destroyCallback=None): def makeProperty(T, attributeName, notify=None, resetOnDestroy=False):
""" """
Shortcut function to create a Qt Property with generic getter and setter. Shortcut function to create a Qt Property with generic getter and setter.
@ -205,8 +205,9 @@ def makeProperty(T, attributeName, notify=None, destroyCallback=None):
T (type): the type of the property T (type): the type of the property
attributeName (str): the name of underlying instance attribute to get/set attributeName (str): the name of underlying instance attribute to get/set
notify (Signal): the notify signal; if None, property will be constant notify (Signal): the notify signal; if None, property will be constant
destroyCallback (function): (optional) Function to call when value gets destroyed. resetOnDestroy (bool): Only applicable for QObject-type properties.
Only applicable for QObject-type properties. Whether to reset property to None when current value gets destroyed.
Examples: Examples:
class Foo(QObject): class Foo(QObject):
@ -225,11 +226,19 @@ def makeProperty(T, attributeName, notify=None, destroyCallback=None):
currentValue = getattr(instance, attributeName) currentValue = getattr(instance, attributeName)
if currentValue == value: if currentValue == value:
return return
if destroyCallback and currentValue and shiboken2.isValid(currentValue):
currentValue.destroyed.disconnect(destroyCallback) resetCallbackName = '__reset__' + attributeName
if resetOnDestroy and not hasattr(instance, resetCallbackName):
# store reset callback on instance, only way to keep a reference to this function
# that can be used for destroyed signal (dis)connection
setattr(instance, resetCallbackName, lambda self=instance, *args: setter(self, None))
resetCallback = getattr(instance, resetCallbackName, None)
if resetCallback and currentValue and shiboken2.isValid(currentValue):
currentValue.destroyed.disconnect(resetCallback)
setattr(instance, attributeName, value) setattr(instance, attributeName, value)
if destroyCallback and value: if resetCallback and value:
value.destroyed.connect(destroyCallback) value.destroyed.connect(resetCallback)
getattr(instance, signalName(notify)).emit() getattr(instance, signalName(notify)).emit()
def getter(instance): def getter(instance):
@ -241,7 +250,7 @@ def makeProperty(T, attributeName, notify=None, destroyCallback=None):
# string representation contains trailing '()', remove it # string representation contains trailing '()', remove it
return str(signalInstance)[:-2] return str(signalInstance)[:-2]
if destroyCallback and not issubclass(T, QObject): if resetOnDestroy and not issubclass(T, QObject):
raise RuntimeError("destroyCallback can only be used with QObject-type properties.") raise RuntimeError("destroyCallback can only be used with QObject-type properties.")
if notify: if notify:
return Property(T, getter, setter, notify=notify) return Property(T, getter, setter, notify=notify)