Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Using an ObjCInstance for touches
-
Hi,
omz very helpfully shared here how to use ObjCInstance to get additional information about a touch (e.g., to distinguish between a pencil and finger touch event).
I have found that simply calling this function in touch_began, in the Examples/User Interface/Sketch.py app, causes the image_view.image to somehow be corrupted (to None) after around 18 touches.
Original code in Examples/User Interface/Sketch.py:
def touch_began(self, touch): x, y = touch.location self.path = ui.Path() self.path.line_width = penwidth self.path.line_join_style = ui.LINE_JOIN_ROUND self.path.line_cap_style = ui.LINE_CAP_ROUND self.path.move_to(x, y)
One line addition which causes corruption:
def touch_began(self, touch): # Why does this break it after around 18 strokes? ui_touch = ObjCInstance(touch) x, y = touch.location self.path = ui.Path() self.path.line_width = penwidth self.path.line_join_style = ui.LINE_JOIN_ROUND self.path.line_cap_style = ui.LINE_CAP_ROUND self.path.move_to(x, y)
During debugging, I found that this call seemed to be reseting sv.image_view.image to be None. (In my own code, I go on to use ui_touch to look at the pencil attributes, but that's not necessary for the test case: simply calling the function causes the problem)
Weirdly, if I save and restore the image view, it (sometimes....) seems to avoid this problem, or at least change the behaviour. Not sure what to make of that, but thought it was worth mentioning
Weird fix, maybe:
def touch_began(self, touch): print(getframeinfo(currentframe()).lineno, sv.image_view.image) # Debug backup = sv.image_view.image ui_touch = ObjCInstance(touch) sv.image_view.image = backup print(getframeinfo(currentframe()).lineno, sv.image_view.image) # Debug x, y = touch.location self.path = ui.Path() self.path.line_width = penwidth self.path.line_join_style = ui.LINE_JOIN_ROUND self.path.line_cap_style = ui.LINE_CAP_ROUND self.path.move_to(x, y)
I thought this was worth reporting, and appreciate any thoughts folk have about what might be going on. Pythonista is just wonderful, by the way, thank you omz.
Mr W.
-
@mr_w, there is something wonky about ImageView, at least based on some the issues that I have seen here in the forums.
Without really fixing anything, here are a couple of things you could try to start with:
- Put an
on_main_thread
decorator on thetouch_began
call - Use the
ui4.gestures
module instead oftouch_began
(pip install ui4
instash
)
- Put an
-
Thank you @mikael, that was helpful. Certainly as a workaround, then a combination of
on_main_thread
, my debuggingprint()
calls, and the saving/restoring ofsv.image_view.image
all (when used together) seem to solve the instance of corruption. Any two of them without the third is less successful, which is all very odd: I’m guessing there’s a race condition somewhere, or that this is some kind of heisenbug.I’ll run with this workaround for now, thank you once again for your insights and suggestions.