In my startup_scipt.py module I check for a file path. If it exists I open that file. If it doesn’t I want to save the file at that path. Like this:
if os.path.exists(os.getenv('OPEN_FILE_PATH')):
print('Opening file')
else:
print('Creating a new file')
bpy.ops.wm.save_mainfile(filepath='path/to/file.blend')
The startup_script.py loads fine, but for some reason the save_mainfile code doesn’t execute. I’ve also tried save_as_mainfile. Is the code running too early? If so is there a way to defer execution? This is a problem with Maya and Houdini so I usually have to defer the code execution until the main UI is built (evalDeferred and hdefereval respectively)
It seems to error out, but I can’t fully read the error (not totally sure how to create a console output when launching Blender from Popen). I’m using this as a hacky solution (it only prints after I close Blender which isn’t ideal):
print(app_session.stdout.readline()) # read the first line
for i in range(10): # repeat several times to show that it works
# print('stdin = {}'.format(app_session.stdin, i)) # write input
app_session.stdin.flush() # not necessary in this case
print('stdout = {}'.format(app_session.stdout.readline())) # read output
print(app_session.stderr.readline()) # read error
print(app_session.communicate(b"n\n")[0])
This is the only output that looks like something is going wrong, but I’m very new to Blender: stdout = b"Warning: property 'release_confirm' not found in keymap item 'OperatorProperties'\r\n"
This has kind of turned into a multi-part question:
Do I need to defer evaluation when saving at startup? If so, how?
How can I see console output when launching Blender from subprocess.Popen
With your example it’s working, so this is a nice backup if an eval defer isn’t possible. I was wondering if there was a way I could do the saving from my custom startup script though? That’s how I’m doing it with every other software, so I want to try and maintain consistency across platforms.
I’m doing this now as a sort of compromise. The startup_script module handles the saving and the launcher.py manages the execution order. I’d like the startup_script to manage both the saving and execution order (via eval defer), but if this is how it has to be done then I guess that’s fine.
I don’t think there is something like a deferred evaluation hook in Blender (although there are various event handlers that might play that role). But the main question would then still be deferred until which moment? Because I still don’t understand what you did before that caused the save call to (maybe) get executed too early.
There is no need to defer execution of save_as_mainfile, It should work immediately.
To print output while Blender is running instead of at the end, the problem in your code may be using both stdout.readline() and stderr.readline(). I think it will block waiting for output from stderr while stdout is actually getting output.
The easiest solution could be passing stderr=subprocess.STDOUT to Popen and only using stdout.readline().
The release_confirm warning is harmless and unrelated to the issue.
Sorry for the confusion @PaulMelis. I put the save call inside the startup_script.py NOT as a python expression in the subprocess.Popen cmd args. Like this:
Hmmm, you’re saving from the creation function of a Panel, which I assume is also registered at some point? I guess that at that point in the blender startup saving to a file might not actually work.
Or maybe the operator context isn’t set up correctly