Find console view and retrieve text in Pythonista3.4
shinyformica last edited by shinyformica
I had code from python2/pythonista3.3 which was able to find the console view in the view hierarchy, and then pull the text out of it:
def findConsoleView(): app = objc_util.UIApplication.sharedApplication() if not app: return "" mainwindow = app.keyWindow() if not mainwindow: return "" mainview = mainwindow.rootViewController().view() if not mainview: return "" visit = list(mainview.subviews()) while visit: v = visit.pop() if bytes(v._get_objc_classname()) == b"OMTextView": if v.superview() and \ bytes(v.superview()._get_objc_classname()) != \ b"OMTextEditorView": return str(v.text()) visit += list(v.subviews()) return ""
Sadly, this no longer works, as I think the console view no longer fits the criteria I was using to find it.
Anyone have a working version of this idea?
I'm going to plug away at searching the view hierarchy and see if I can find where the console is hiding now.
( @omz for possible future updates: it would be nice if there was a
console.text()function in the
shinyformica last edited by
Hrm...upon further investigation, I take it back: the above code appears to work in Pythonista3.4.
I still don't love it. It feels very fragile just "guessing" which OMTextView happens to be right like this. I really wish there was a better way...but I don't see a good way to more directly determine which view is the console view.
Anyway, the right solution is for there to be a
console.text()function. So I will repeat my plea to @omz to please consider adding that to the features in the
cvp last edited by cvp
...... fragile .....
You could add this security check that in the subviews of the superview of the OMTextView, you find a label with
>which is just before the console input line
from objc_util import * def findConsoleView(): app = UIApplication.sharedApplication() if not app: return "" mainwindow = app.keyWindow() if not mainwindow: return "" mainview = mainwindow.rootViewController().view() if not mainview: return "" visit = list(mainview.subviews()) while visit: v = visit.pop() if bytes(v._get_objc_classname()) == b"OMTextView": if v.superview() and \ bytes(v.superview()._get_objc_classname()) != \ b"OMTextEditorView": # check this the right view su = v.superview() ok = False for ssu in su.subviews(): for ssu in ssu.subviews(): if 'UILabel' in str(ssu._get_objc_classname()): if str(ssu.text()) == '>': print('>'*50) ok = True break if ok: break if ok: return str(v.text()) visit += list(v.subviews()) return "" print('test') print(findConsoleView())
Anyway, as you said, your code works even in Pythonista 3.4 and we don't receive a lot of updates per year (sorry @omz 😉) thus not a big risk, even if you have to test it each time.
Edit: and you could always create a findConsoleView.py and use it so
import console from findConsoleView import * console.text = findConsoleView print('hello') t = console.text() print(t)
shinyformica last edited by
@cvp searching for the prompt label is a good extra check, I like it...well, I like it a little bit more.
Monkey-patching the console module isn't really necessary...being able to call
console.textisn't the part that bothered me, it's just my hope for what @omz might eventually add to the
Anyway, thanks @cvp, as always!