Next: Simple Button Using PyRegister Prev: Simple Button using AddCallback Up: Examples Top: Top
PyEval() in UIL to
evaluate a string that invokes a callback.  If the callback were
"pre-defined", then a UIL-writer would not have to write any Python
code to use this technique, other than the string passed to
PyEval() to evaluate.
There are three files required---a .uil file named button2.uil, a .uid file named button2.uid, and a Python script named testbutton2.py.
button2.uil contains the following text:
    module button_test_2
    version = 'V1.0'
    names = case_sensitive
    procedure
    PyEval(string);                     ! declare PyEval
    object main : XmBulletinBoard {     ! bulletin board parent
        arguments {
            XmNwidth = 200;
            XmNheight = 200;
        };
        controls {
            XmPushButton button;        ! main is parent of button
        };
    };
    object button : XmPushButton {      ! button is labelled Push Me
        arguments {
            XmNx = 0;
            XmNy = 0;
            XmNwidth = 100;
            XmNheight = 40;
            XmNlabelString = 'Push Me';
        };
        callbacks {
            XmNactivateCallback = procedure PyEval("MyPrint(g_var)");
        };
    };
    end module;
testbutton2.py (which must have execute permission) contains the following left-justified text:
    #!/usr/local/bin/python
    import os, sys, Mrm, Xt
    def MyPrint(msg):                   # MyPrint is defined in __main__
        print msg
    def main():
        global g_var                    # g_var has global scope in __main__
        g_var = 'a global value'
        print 'g_var =',g_var
        top_level = Xt.Initialize()
        # fetch the hierarchy
        mrm_hier = Mrm.OpenHierarchy('button2.uid')
        main_w = mrm_hier.FetchWidget('main', top_level)
        # manage widgets, realize shell
        main_w.ManageChild()
        top_level.RealizeWidget()
        Xt.MainLoop()
    main()
    testbutton2.py
MyPrint().  MyPrint() is in the scope of the Python
"unnamed" module __main__ because no other module was named for
MyPrint() to be in the scope of.  This is an important point,
because PyEval evaluates its string in this namespace, and so
can find MyPrint().
Then the script declares the function main().  main()
declares the global g_var.  g_var is also in the
__main__ namespace, for the same reason as MyPrint().
g_var is defined in this namespace so that it can be used in
the tag argument of the PyEval call.  The script opens the
hierarchy defined by button.uid, fetches the widget named "main",
which is a bulletin board, and its child, a pushbutton, manages these
widgets and realizes the shell, and enters the Xt Event Loop.
Finally, the script invokes the main() function, which executes
the code and builds the interface.
When the user pushes the pushbutton (labelled "Push Me" in the .uil
file), the PyEval() function is called with the string
"MyPrint(g_var)".  This string is evaluated by Python in the context
of module __main__, and calls MyPrint() passing as the
argument the variable g_var.  MyPrint() simply prints
it's argument's value, which is that of g_var---"a global
value".
Note that if the testbutton2.py script was imported, then
MyPrint() would not be in __main__ namespace.
testbutton2.py could be imported by the statement:
    import testbutton2
MyPrint and g_var would be globals in the
module testbutton2's namespace; and so the .uil file would have to be
coded differently to invoke MyPrint(), as shown below:
    callbacks {
        XmNactivateCallback = procedure PyEval(
            "import testbutton2; testbutton2.MyPrint(testbutton2.g_var)");
    };