Python With ZK

From Documentation
Python With ZK

February 11, 2010
ZK 3.6+

Python With ZK

Many people seem to want to use Python with ZK (actually Jython of course but let's just stick to the name Python to avoid confusion). Although there are performance penalties for using Python it certainly makes prototyping a lot quicker. With a small number of users the performance hit may not even be a problem.

The only examples of using Python with ZK seem to be limited to simple <zscript> included in the ZUL files.

Below we show you a possible way of keeping Python code separate from your ZUL files and even do a little bit of MVC and "design by convention" to make things easier.

First a Simple ZUL - testhello.zul


<zscript src="" language="python"></zscript>
<zscript src="" language="python"></zscript>

	<window title="Test Hello Window" border="normal" height="200px"
		apply="${BobController}" width="200px" closable="true"
		Hello World Message:
		<label id="lMessage"/>
		<textbox id="txMessage"/>
		<button id="okButton" label="OK"/>

The important things to notice are the includes for and and the apply="${BobController}" parameter. Both includes are python files. Let us ignore PythonForwardComposer for now and start with BobController :-

A simple controller -

class BobController(PythonForwardComposer):

   def onClick_okButton(self, event):
      message = txMessage.getValue()
      lMessage.setValue(lMessage.getValue() + message)

The apply="${BobController}" on the ZUL tells ZK that instead of the GenericForwardComposer we will use BobController to compose the page. BobController simply extends PythonForwardComposer but overides the onClick event for the okButton. Notice how there is an underscore between onClick and okButton. In the many java examples you will see a "$" sign used but that is a reserved character in python, therefore we use an underscore.

At the risk of stating the obvious, just as with using GenericForwardComposer in Java (ZK Developer's Reference: MVC) it is important that the name of the button in the ZUL (id="okButton") matches exactly (including case) the method defined in BobController. Welcome to "design by convention".

You will also see how in BobController we can use txMessage and lMessage (defined in the ZUL with exactly those names) directly and get and set them as required

Ok, we have seen how a simple python can automatically get at ZUL variables and how a ZUL component will invoke a method in BobController.

Now for the magic :-

Python composer -

from org.zkoss.zk.ui.util import GenericForwardComposer;
class PythonForwardComposer(GenericForwardComposer):
    def __init__(self):
        GenericForwardComposer.__init__(self, "_")
    def doAfterCompose(self, component):
        GenericForwardComposer.doAfterCompose(self, component)
        for method in dir(self):
            if callable(getattr(self, method)):
                if method.startswith("on") and method.count('_') == 1:
                    idx = method.index('_')
                    comp = component.getFellowIfAny(method[idx + 1:])
                    if comp != None:
                        comp.addForward(method[:idx], component, method)
                        component.addEventListener(method, self)

    def onEvent(self, evt):
        if callable(getattr(self,

This bit of magic extends the standard ZK GenericForwardComposer. Importantly it changes the separator from being a dollar to an underscore. It then wires in all of the "events" and on receiving one of those events it fires off the appropriate method in (in this case) BobController.

That's it.

You should not need to change PythonForwardComposer, just simply include it at the start of your ZUL files. Of course you still have to write your own version of BobController and your own ZUL but now you have a template to follow.

Put the 3 files above (testhello.zul, and into the WebContent folder of a ZK project and try it. You should get a screen with the words "Hello World Message" with an input box under it. Enter something in the input box, click OK and the Hello World Message" will change.


Thanks must go to my colleague Jon Ady for help with this (specifically PythonForwardComposer) and to Michele Mazzei who wrote a Java version of the helloworld ZK that this version is based on.

See Also


Copyright © BobZK. This article is licensed under GNU Free Documentation License.