Simple Button using PyEval -- X Python Reference Manual

Next: Simple Button Using PyRegister Prev: Simple Button using AddCallback Up: Examples Top: Top

## 6.3.2. Simple Button using PyEval

This example demonstrates the use of `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;

button2.uid is created by the uil compiler as noted in the first example.

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()

The script is executed by the statement:

        testbutton2.py

When executed, the testbutton2.py script first declares the function `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

In this case, `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)");
        };

Next: Simple Button Using PyRegister Prev: Simple Button using AddCallback Up: Examples Top: Top