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.
Untitled
-
Hi, I'm trying to build and package a script and its .pyui file into a standalone .ipa file in Xcode. I have Apple developer provisioning profile and have successfully been using the Pythonista v1.5 template to create standalone apps where any UI code is done in the main script file.
I want to create a standalone app from UI built with the UI Editor. I am able to build and export my target .ipa and install it on a jailbroken device. I have my Python script named Script.py and my UI file named Script.pyui. No matter how I define a path for the the pyui file, the call to ui.load_view() consistently fails and I see the following error message on my device:
"Error (line nn): UI file could not be loaded" The nn will be the actual line number that the ui.load_view() call is in my script.
I presume this error message is coming from the ui module itself. Any suggestions on how to get around this problem to load the UI from a file in a standalone app? The script and UI file load and run fine within PYthonista itself.
I have tried the following, without luck for a file actually named Script.pyui and called from the script called Script.py:
ui.load_view()
ui.load_view("Script")
ui.load_view(".\Script")
ui.load_view("Script.pyui")
ui.load_view(".\Script.pyui")
Since I never saw any note or documentation to suggest this is not officially supported -- to package and run UI code from a loaded UI file in a standalone app, I figure there must be a way to do this but it is just not documented anywhere.
Can anyone tell me how to accomplish this?
-
Put the .pyui file in the /Pythonista/Textures folder, then use ui.load_view("../APPNAME.app/Textures/Script.pyui")
Just replace APPNAME.app with your app file name, listed under "Targets" or "Products" or something in XCode.
-
I just tried and get the same error, and that is for both / slashes or \ slashes to separate paths.
-
What about:
import os print(os.path.join(os.path.dirname(__file__), 'Script')) print(os.path.realpath(os.path.abspath(os.path.join(os.path.dirname(__file__), 'Script')))) # or import sys print(os.path.join(os.path.dirname(sys.argv[0]), 'Script'))
-
I find myself having the same problem.
-
@Shambhala, is there something special about the Textures directory that would make this work? Why doesn't other qualified paths to the pyui file work?
Interestingly,
ui.load_view("../APPNAME.app/Textures/Script.pyui") does NOT work, I get the same error message.
But,
ui.load_view("..\APPNAME.app\Textures\Script.pyui") DOES work but because this is Windows style path separator I would not thing it should work and the one that uses Unix style path separator does NOT work. Very strange behaviour.
-
You may want do pop up an alert or something containing
os.abspath('.')
, and `os.listdir('.'), so that you can figure out what relative path you are starting in. Or, maybe do an os.walk to print the entire directory structure, to find where you are starting, and where the pyui is located. The pyui needs to be in the current folder, or you need to specify an absolute or relative path to that folder from the current folder.
An alternative.... Someone here posted a script that appended the pyui file into the py, so that everything is in one file. That could also work? -
@JonB PackUI doesn't work in Xcode.
-
@ltddev I can't even add files to the Textures folder.
-
I right-clicked the "Textures" folder in XCode, then clicked "Open in finder...", then copied the files I wanted into it.
-
Do any of these help?
import os # replacing / with \\ print(os.path.join(os.path.dirname(__file__), 'Script').replace('/', '\\')) print(os.path.realpath(os.path.abspath(os.path.join(os.path.dirname(__file__), 'Script'))).replace('/', '\\')) # or import sys print(os.path.join(os.path.dirname(sys.argv[0]), 'Script').replace('/', '\\'))
-
@ccc I get EOL while scanning string literal
-
Sorry... I fixed the script above. Please try again with this new formulation (double backslashes).
-
-
Here is a verbose version of
ui.load_view()
that might help.It takes the real, absolute path of this script and adds 'ui' to it.<br>
It prints out what that new filepath is and if that file exists or not.<br>
It tries to ui.load_view() it and if it fails it repeats the process with all / converted to \.def ui_load_view_verbose(pyui_filepath = None): pyui_filepath = pyui_filepath or os.path.realpath(os.path.abspath(__file__)) + 'ui' fmt = 'Attempting to load_view({}) -- File {}found.' print(fmt.format(pyui_filepath, '' if os.path.isfile(pyui_filepath) else 'not ')) try: return ui.load_view(pyui_filepath) except ValueError as e: print(e) return None if '\\' in pyui_filepath else ui_load_view_verbose(pyui_filepath.replace('/', '\\')) # replace your current call to ui.load_view() with the following: v = ui_load_view_verbose() # with no parameters!! if not v: print('Bummer! ui_load_view_verbose() did not work.') sys.exit()
If this fails, please send us the printed output.
-
One problem with using
__file__
is ifos.chdir
has been called.__file__
only has the relative path from the time you import it. If you chdir after import, you can't find it again.
I struggled with this problem when making a plugin for my javascript editor script... The calling script had imported the module, then changed directory. In retrospect, I probably could have done something in init, but here's what I ended up with. So possibly using inspect to locate things might be another route.origPath= os.path.dirname(inspect.stack()[-1][1]) fullScriptPath= os.path.join(origPath,os.path.splitext(__file__)[0])
-
Does
sys.argv[0]
suffer from the same problem as__file__
? -
-
Try this.. Which will display all files ending with pyui...
def findpyui(): import os startingpath = os.path.expanduser('~') # other things to try.... #startingpath = '.' #starting path = '..' # i.e in pythonista, start above documents, to see into library,etc print startingpath for root, dirs, files in os.walk(startingpath): for name in files: if name.endswith('pyui'): print os.path.join(os.path.abspath(root),name) findpyui()
-
The solution above worked. Thanks.