-
Notifications
You must be signed in to change notification settings - Fork 80
silx.gui.plot: add X inversion action to PlotWindow and ImageToolbar #4425
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
self.STATE[True, "icon"] = icons.getQIcon("plot-yup") | ||
self.STATE[True, "state"] = "Y-axis is oriented upward" | ||
self.STATE[True, "action"] = "Orient Y-axis upward" | ||
class _AxisOriginToolButton(PlotToolButton): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I completely refactored YAxisOriginToolButton
to have a base class to abstract the common behaviour.
The only change between the XAxisOriginToolButton
and the YAxisOriginToolButton
is the axis to act on (abstracted by getAxis
) and the icons/labels (abstracted by getState
).
Note that self.STATE
was converted to TypedDict, which should be fine given these were introducted in Python 3.8.
Note also that STATE
is no longer lazy-loaded. Is this a problem ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring sounds good.
The state info is still lazy-loaded, however it's no longer cached.
It shouldn't be an issue: icons are already cached.
Sorry, went a bit too fast. I still have CI woes to solve. |
0b3058d
to
fe8bd76
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Looks good!
Main concern is about circular references induced by using lambda: self.method
.
src/silx/gui/plot/PlotToolButtons.py
Outdated
upwardAction.triggered.connect(self.setYAxisUpward) | ||
upwardAction.setIconVisibleInMenu(True) | ||
disableInversionAction = self._createAction(False) | ||
disableInversionAction.triggered.connect(lambda: self.setAxisInverted(False)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This creates a mixed python/qt circular reference (lambda -> self -> menu -> disableInversionAction -> signal -> lambda) which may delay proper deletion, so best to avoid.
WeakMethod can be used here:
disableInversionAction.triggered.connect(lambda: self.setAxisInverted(False)) | |
inversionTriggered = WeakMethod(self.setAxisInverted) | |
disableInversionAction.triggered.connect(lambda: inversionTriggered(False)) |
or wrapper methods since signal.connect(self.slot)
is handled correctly.
Illustration of the problem:
>>> import weakref
>>> from silx import sx
>>> class A(sx.qt.QObject):
... def __init__(self):
... super().__init__()
... self.objectNameChanged.connect(self.changed)
... def changed(self, name):
... print(name)
...
>>> a = A()
>>> r = weakref.ref(a, lambda ref: print('dead', ref))
>>> del a
dead <weakref at 0x7f48eff53ef0; dead>
>>> class A(sx.qt.QObject):
... def __init__(self):
... super().__init__()
... self.objectNameChanged.connect(lambda n: self.changed(n))
... def changed(self, name):
... print(name)
...
>>> a = A()
>>> r = weakref.ref(a, lambda ref: print('dead', ref))
>>> del a
>>>
>>> r()
<__main__.A object at 0x7f48fe72eb80>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In the end, I used wrapper functions (108c45f) instead of weakref.
It seems to have fixed the elusive segfault in the CI !
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good!
IMO we should prevent using lambda
functions, functools.partial
or anything keeping references to self
in signals even if that requires some boilerplate methods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep. It looks to be recipes for disaster 😞
self.STATE[True, "icon"] = icons.getQIcon("plot-yup") | ||
self.STATE[True, "state"] = "Y-axis is oriented upward" | ||
self.STATE[True, "action"] = "Orient Y-axis upward" | ||
class _AxisOriginToolButton(PlotToolButton): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Refactoring sounds good.
The state info is still lazy-loaded, however it's no longer cached.
It shouldn't be an issue: icons are already cached.
8b5a3b7
to
1ff7887
Compare
Looks like my suggestions breaks the CI 😅 , I'll have a look |
1ff7887
to
18d0155
Compare
Missed a renaming from |
Maaan, there is a segfault in the CI that I cannot reproduce locally 😮💨 |
Co-authored-by: Thomas VINCENT <[email protected]>
18d0155
to
108c45f
Compare
Checklist:
<Module or Topic>: <Action> <Summary>
(see contributing guidelines)Fix #4253
Screencast.from.2025-09-23.10-43-25.webm