Trying to open window and "click" print button

I have this project script that I want to trigger when a tag comes true. It should open the window, pause for 2 seconds while the table populates, then ‘virtually’ click a print screen button that runs a print script. I get this error :

“nameerror: global name ‘event’ is not defined”

window = system.nav.openWindow(‘DAILY TIMES 1’)
system.nav.centerWindow(window)
def clickButton():
import system
button = event.source.parent.getcomponent(‘print’)
button.doClick()
system.gui.messageBox(“Button has been clicked!”)

system.util.invokeLater(clickButton,2000)

I am relatively new to scripting so I’m sure it is something I don’t completely understand.

Thanks!!
Rhett

The ‘event’ variable doesn’t exist in your clickButton script because clickButton is running later. The event routine that created clickButton has ended, and the event ‘environment’ is gone. To make this work, you must get a copy of the event variable into your function. The typical way is to use a default parameter, like so:window = system.nav.openWindow('DAILY TIMES 1') system.nav.centerWindow(window) def clickButton(ev=event): import system button = ev.source.parent.getcomponent('print') button.doClick() system.gui.messageBox("Button has been clicked!") system.util.invokeLater(clickButton,2000)Note the copy of ‘event’ into ‘ev’. invokeLater doesn’t allow the caller to pass arguments, so the function gets only the default arguments from its definition. Including ‘event’ as a default argument gets around the invokeLater limitation. That’s also why ‘clickButton’ has to be defining in the event routine itself, not in a project or shared script. ‘event’ doesn’t exist anywhere else.
Although you could name the parameter ‘event’ inside the function too, I find that using a slightly different name helps me debug my own code later. It reminds me that ‘ev’ is a copy of ‘event’, and exists outside the original event.

pturmel’s explanation is incorrect. It is not necessary to pass the “event” variable as an argument into a function in order to access it. Functions can access variables defined outside their scope just fine (unless you are using a version of Ignition older than 7.5, which uses Python 2.1).

Where is the code located? Is it in a function in a project script library Python module? If so is the function being called in a Client Tag Change script? Information about where and how the code is being invoked is needed before I can tell you how to solve the problem.

If I were to guess I would guess that your code is in a function in a project Python module and it is being called in a Client Tag Change script. If this is the case then you cannot use an “event” variable to access the button. Instead you could use the window object that you already have like this: window.rootContainer.getComponent(“print”)

I would likely go a different route.

In the window that is being opened, I would add a Custom property, somthing like externalTrigger.

Then, in the internalFrameActivated event script:

[code]externalTrigger=system.gui.getParentWindow(event).getComponentForPath(‘Root Container’).ExternalTrigger

def clickButton():
button=system.gui.getParentWindow(event).getComponentForPath(‘Root Container.Button’)
button.doClick()

if externalTrigger==1:
system.gui.getParentWindow(event).getComponentForPath(‘Root Container’).ExternalTrigger=0
system.util.invokeLater(clickButton,2000)[/code]

This keeps everything on the same window, and gives you the choice on whether to click the button or not from an external source.

From any external source, the code is shortened to:

window = system.nav.openWindow('Main Window (2)', {'ExternalTrigger' : 1}) system.nav.centerWindow(window)

Ah, I did miss that the ‘print’ button is not in the same window as the original button. I would use the following code instead:window = system.nav.openWindow('DAILY TIMES 1') system.nav.centerWindow(window) def clickButton(w=window): import system button = w.rootContainer.getcomponent('print') button.doClick() system.gui.messageBox("Button has been clicked!") system.util.invokeLater(clickButton,2000)Nick’s assertion that you can get the ‘event’ variable without passing it is incorrect. You can get the source object inside the event from other routines, but the details that accompany it (shift keys, mouse coordinates, etc.) are only available in the originating event, or in a copied ‘event’ variable.
In this case, the ‘event’ variable doesn’t have anything of value for the delayed script. But the originating event does already have the window object in a variable. If you don’t use the variable passing technique, the target window must be looked up by name in two places, making your script prone to errors when renaming/duplicating windows, replicating objects, etc.
I also wouldn’t recommend Jordan’s approach, as the internalFrameActivated event he suggests will also trigger for other window events. With the code above, one click on the original button can only generate one click on the ‘print’ button.

nmudge, you are correct, the function is in a project script library. And yes I will call it from a tag change script. Let me try the suggestion here and see what I get back.

[quote=“nmudge”]
If I were to guess I would guess that your code is in a function in a project Python module and it is being called in a Client Tag Change script. If this is the case then you cannot use an “event” variable to access the button. Instead you could use the window object that you already have like this: window.rootContainer.getComponent(“print”)[/quote]

Why is this?