An event is just calling a function - you want an event to be generated every time the user does something, such as clicking a button, dragging a scale, or pressing a key...

The Button has an event automatically linked to it - whenever you press it, a function gets called. The other widgets don't.

Built-in Events

appJar currently has four basic types of event you can register:

Change & Submit Events

These do similar things, so probably shouldn't both exist, but have evolved from a single .set XXX Function() which is now deprecated.

from appJar import gui

def songChanged(rb):

def reset(btn):
    # set back to the default, but don't call the change function
    app.setRadioButton("song", "Killer Queen", callFunction=False)

app.addRadioButton("song", "Killer Queen")
app.addRadioButton("song", "Paradise City")
app.setRadioButtonChangeFunction("song", songChanged)
app.addButton("Reset", reset)

WARNING - it's possible to generate a RuntimeError. If you've got two widgets changing the same variable, say a Scale and a SpinBox, and you want a change in one widget to cause an update in the other, you might inadvertently end up stuck in a recursive loop, until the stack overflows.

In this case, make sure you set the optional parameter callFunction = False when you call the set XXX Function() of a widget.

Over Events

Set functions to call whenever the mouse enters (goes over) or leaves the specified widget.

    from appJar import gui

    def enter(wdgt): 
        print("IN", wdgt)
    def leave(wdgt):
        print("OUT", wdgt)

    app.addLabel("l1", "Testing...")
    app.setLabelOverFunction("l1", [enter, leave])

Drag Events

Set functions to call when the mouse button is clicked and dragged on a Label, then released.

Registering Other Events

It's possible to register any of the other tkinter event types with appJar widgets.
Just get the widget, then call the tkinter bind() function, passing in the event name and function to call.
NB. The function you register must receive a single parameter, the event object.

# either grab the widget when it's created, and bind the event
ent = app.addEntry("e1")
ent.bind("<FocusOut>", function_name, add="+")

# or do the above in one line
app.addEntry("e1").bind("<FocusOut>", function_name, add="+")

# or, if doing later on, get the widget from appJar and bind the event
ent = app.getEntryWidget("e1")
ent.bind("<FocusOut>", function_name, add="+")

# or do the above in one line
app.getEntryWidget("e1").bind("<FocusOut>", function_name, add="+")

Binding Keys

We also sometimes want keys to trigger events.
The classic example is the <Enter> key, we often want to be able to hit the <Enter> key to submit a form...

You may also want to bind other keys to events:

from appJar import gui
def keyPress(key):
    if key == "<Up>":
    elif key == "<Down>":
    elif key == "<F1>":

app = gui("Button Demo")
app.addLabel("title", "Press the arrow keys to change the font")
app.bindKey("<Up>", keyPress)
app.bindKey("<Down>", keyPress)
app.bindKey("<F1>", keyPress)

NB. You must use the full tkinter event format for events with these bindings, including the angle brackets <>.
This is different to how menu shortcuts are defined.

Starting the GUI

If you want to call a function once the GUI starts, you can register it with the following call:

Stopping the GUI

Usually the user just presses the close icon to close and stop the GUI.
However, you might want to let them do it in other ways - maybe by pressing a button...

app.addButton('QUIT', app.stop)

Confirming the user wants to quit/running clean up scripts on exit

You may want to add in a confirmation that the user really wants to stop the GUI.
Or, you may want to do some tidying up when the user stops the GUI, such as save a file.

If so, you can set a stopFunction to call, whenever the user tries to stop the GUI.

So, if you're just doing some tidying up, return True at the end of the function.
If you want to stop the user closing the GUI, return False
And, if you want to check if the user really wanted to stop the GUI:

def checkStop():
    return app.yesNoBox("Confirm Exit", "Are you sure you want to exit the application?")


Stopping Quickly

If you have a LOT of widgets (maybe a Table with hundreds of rows), stopping the GUI can take a while...
In which case, you should enable fastStop on the GUI.