How to get current GuiApp instance

Hi,

I’m having difficulties getting the app1/app global variable when running a custom python script.

I’m receiving this error:
NameError: global name ‘app1’ is not defined.

Note the script works when running in Natron’s interactive python shell it works.

I tried a few approaches, but none have worked so far:
I receive a different app instance, which has a subset of the functions app1 has.

import NatronGui
NatronGui.natron.getGuiInstance(0)

Returns a NatronEngine app instance, not gui.

NatronGui.natron.getActiveInstance()

What am I doing wrong? how can I receive the current active gui instance. Just to put it in context, I want to set the frame-rate, frame-range and set the projectPath, using the GuiApp instance.

Thank you,
Asi

from NatronGui import *

app = natron.getGuiInstance(0)

Do you want to set frame-rate, frame-range for the entire project or Read nodes ?

Hi @fabiof17 thanks for the replaying.

Yes, I want to set the frame-rate, frame-range, projectPath, format/resolution, for the entire project.

I tried doing that, but it gives NatronGui.GuiApp instance that only has a partial set of the methods. For example, it doesn’t have the methos projectPath()

from NatronGui import *
app = natron.getGuiInstance(0)
print app, sorted(dir(app))

#Result:
<NatronGui.GuiApp object at 0x7fb0817660e0>
[‘addFormat’, ‘addProjectLayer’, ‘clearSelection’, ‘closeProject’, ‘createModalDialog’, ‘createNode’, ‘createReader’, ‘createWriter’, ‘deselectNode’, ‘getActiveTabWidget’, ‘getActiveViewer’, ‘getAppID’, ‘getChildren’, ‘getDirectoryDialog’, ‘getFilenameDialog’, ‘getNode’, ‘getProjectParam’, ‘getRGBColorDialog’, ‘getSelectedNodes’, ‘getSequenceDialog’, ‘getTabWidget’, ‘getUserPanel’, ‘getViewNames’, ‘getViewer’, ‘loadProject’, ‘moveTab’, ‘newProject’, ‘registerPythonPanel’, ‘render’, ‘renderBlocking’, ‘resetProject’, ‘saveFilenameDialog’, ‘saveProject’, ‘saveProjectAs’, ‘saveSequenceDialog’, ‘saveTempProject’, ‘selectAllNodes’, ‘selectNode’, ‘setSelection’, ‘timelineGetLeftBound’, ‘timelineGetRightBound’, ‘timelineGetTime’, ‘unregisterPythonPanel’, ‘writeToScriptEditor’]

Where the NatronGui.GuiApp instance the I can access from the python interactive shell has more methods. Like the frameRate, frameRange, projectPath... Which I need to query and set so project default values.

print app1, sorted(dir(app1))

#Result:
<NatronGui.GuiApp object at 0x7fb083a99f38>
[‘Info’, ‘LUT’, ‘Layers’, ‘Python’, ‘Settings’, ‘Viewer1’, ‘Views’,‘addFormat’, ‘addProjectLayer’, ‘afterNodeCreated’, ‘afterProjectLoad’, ‘autoPreviews’, ‘beforeNodeRemoval’, ‘beforeProjectClose’, ‘beforeProjectSave’, ‘clearSelection’, ‘closeProject’, ‘comments’, ‘createModalDialog’, ‘createNode’, ‘createReader’, ‘createWriter’, ‘creationDate’, ‘defaultColorSpace16u’, ‘defaultColorSpace32f’, ‘defaultColorSpace8u’, ‘defaultLayers’, ‘deselectNode’, ‘frameRange’, ‘frameRate’, ‘getActiveTabWidget’, ‘getActiveViewer’, ‘getAppID’, ‘getChildren’, ‘getDirectoryDialog’, ‘getFilenameDialog’, ‘getNode’, ‘getProjectParam’, ‘getRGBColorDialog’, ‘getSelectedNodes’, ‘getSequenceDialog’, ‘getTabWidget’, ‘getUserPanel’, ‘getViewNames’, ‘getViewer’, ‘gpuRendering’, ‘lastAuthor’, ‘lastSaveDate’, ‘loadProject’, ‘lockRange’, ‘moveTab’, ‘newFormat’, ‘newProject’, ‘originalAuthor’, ‘outputFormat’, ‘pane1’, ‘pane2’, ‘pane3’, ‘projectName’, ‘projectPath’, ‘projectPaths’, ‘registerPythonPanel’, ‘render’, ‘renderBlocking’, ‘resetProject’, ‘saveFilenameDialog’, ‘saveProject’, ‘saveProjectAs’, ‘saveSequenceDialog’, ‘saveTempProject’, ‘selectAllNodes’, ‘selectNode’, ‘setSelection’, ‘setupForStereo’, ‘softwareVersion’, ‘timelineGetLeftBound’, ‘timelineGetRightBound’, ‘timelineGetTime’, ‘unregisterPythonPanel’, ‘viewsList’, ‘writeToScriptEditor’]

I’m not in front of Natron right now, but i think it really depends on what you want to do.
Why don’t you use NatronGui.GuiApp since it has the methods to set project path ?

unfortunately the it doesn’t have projectPath

from NatronGui import *
app = natron.getGuiInstance(0)
app.projectPath.getValue() # will error out on attribute not found

app1.projectPath.getValue() # will work.

I just don’t understand why the instances, of the same NatronGui.GuiApp class, have different number of methods.

Because this method should never be called, since Natron pre-declares all opened projects with the following variables: app1 for the first opened project, app2 for the second, and so on…

So back to my original question,

Could someone please share, Since the natron.getGuiInstance() doesn’t returns a workable instance. how can I access (getValue&setValue) on pathProject, framerate, framerange methods in a python script (vs python interactive shell)?

many thanks,
Asi

I think you might want to check Natron Document - Start-up scripts. I believe what you need is to create a callback and executed it from Preference->Python->After project created

From what I understand, app works and only works after project is created. initGui.py actually does not recognize app at all because project is not done initialized while running initGui.py. You can however write functions in initGui,py using app, but you can only execute it after project is created, which I am not a fan of it, it makes harder to setup studio-wise default. I feel Nuke’s init.py and menu.py is much more manageable, but it’s might just because I am used to it.

Back to your problem, the way I setup auto loaded script studio-wise now is to have Natron on all machine include a PyPlugs folder on server where I stored a initGui.py, in that initGui.py, I can defined my callback function. for example,

#initGui.py

def afterProjCreated(app):
    #Setting Frame range
    app.getProjectParam('frameRange').set(1001,1020)

    #Setting Frame rate
    app.getProjectParam('frameRate').set(24)

Then, in Natron Preference->Python->After project created, I simply put my callback name afterProjCreated on it.

Hope this solve your problem.

Best,

Han

Thank you @mnhan32 your solution solve the setting a new project parameters.

But I still would love to know how I can get/set the project paramaters (frameRange, frameRate, projectPath) - these are needed to hook natron into a production pipeline/farm.

So anyone have an ideal how to access (getValue&setValue) on pathProject , framerate , framerange methods in a python script (vs python interactive shell)?

How can I do this, vie a python script, without getting app1 unknown variable error?:

app1.frameRate.getValue()

Ideally this would work, but it doesn’t…

from NatronGui import *
app = natron.getGuiInstance(0)
app.projectPath.getValue()
##will error out on attribute not found, since app instance has only a partial set of methods. which is a very strange.

Thank you

Ok, I figured it out, just wanted to share if it helps anyone else.

def set_project():
import NatronGui
app = NatronGui.natron.getGuiInstance(0)

#projectPath
param = app.getProjectParam(‘projectPath’)
param.setValue(‘/whatever/project/path’)

#frameRange
param = app.getProjectParam(‘frameRange’)
param.set(1001, 1100)

#FPS
param = app.getProjectParam(‘frameRate’)
param.setValue(24.0)

format/Resolution
app.addFormat(‘{} {}x{} 1.0’.format(‘format_name’, 2048, 858))
param = app.getProjectParam(‘outputFormat’)
index = param.getOptions().index(‘format_name’)
param.set(index)

Where do you plan to run this script?
If you plan to run the script in script editor, your script would work only if you never start new Natron instance from within a existing Natron instance byFile -> New Project, or File -> Open Project.
Natron appID increase if you open a project within an existing Natron. If an artist open an project A, and within project A, he open project B by File -> Open Project. Now you have two Natron windows, project A and B. He then run your script in project B, the script will actually change project setting in project A, because your script always target first GUI instance, index 0. Sadly, I could not find a way to figure out current appID for script running from script editor. If you don’t mind having user change setting as an menu command in Natron, you can define function in initGui.py and use NatronGui.natron.addMenuCommand(). For example, add a folder path to Pyplug, within that folder create an initGui.py.

#initGui.py
import NatronGui
def setProj():
    app.getProjectParam('frameRange').set(1001,1002)
    app.getProjectParam('frameRate').set(24)
NatronGui.natron.addMenuCommand('MenuName/CommandName','setProj')                                                                 

The command will show on menu, and it will work on current instance regardless.

I’ll write the tool for you (or at least a part) so you’ll see how to do it.
Until then, grab this archive and unzip it to your .natron folder.

Init_Natron.zip (13.8 KB)

I did some tools (as a training), so you can see how it works.
They’ll be located in a ‘Tools’ menu in the top menu bar.

Plus, if you didn’t grab the PyPlugs yet, get them here :

Unpack them in your .natron folder too.

Then run Natron, and see what happens in the console.

Hi to revive an old topic (and ask if my answer seems correct).
Here’s what I suggest to get the active guiapp (and not app).

myNoGUIAppID = natron.getActiveInstance().getAppID()
myapp = natron.getGuiInstance(myNoGUIAppID)

ActiveInstance is sometimes a bit “late” (moving nodes is not enough to activate). But it seems very usable.

If this method is correct it could be advertised in the docs as I found several scripts on the web assuming the app is always 0. Thus these scripts break as soon as you have several natron windows opened.