Developing Custom UI Sections in Python

From Lianjapedia
Jump to: navigation, search

About this tutorial

In this tutorial we will see how to build Custom Sections in Python. The target audience is for intermediate developers who have read through and understood the Getting Started with Lianja tutorial.

The Lianja App Development process

As you should recall from the Getting Started with Lianja tutorial, developing apps in the Lianja App Builder is an iterative process.

Let's just quickly review that process.

  • You visually build a Lianja App using the Lianja App Builder. For non-programmers, the Lianja App Builder providers a wide range of pre-built templates to assist you in building an App quickly and easily.
  • Lianja Apps are made up of Pages. Pages are made up of Sections. Sections are made up of Fields and Gadgets.
  • You can group pages into Page Collections.

If you require to build a more complex App with a custom UI, you do this by building Custom Sections and/or Custom Gadgets in any of the following scripting languages which are integrated into the Lianja App Builder:

  • Lianja/VFP (Visual FoxPro compatible)
  • JavaScript
  • Python
  • PHP

Seeing that the Lianja App Builder has an embedded database built into it, you do not need to install any other software to be able to build multi-user high performance database apps for the desktop, web and mobile devices.

The Lianja embedded database engine is highly compatible with Visual FoxPro. It includes a feature-complete cross platform implementation on the Visual FoxPro scripting and database engine.

Python, JavaScript and PHP are seamlessly integrated on top of this database engine, allowing you to build custom UI sections and custom UI gadgets in Visual FoxPro, JavaScript, Python or PHP and make full use of the power of this high performance database engine with local cursors and complete SQL and noSQL database support.

To facilitate the development of custom UI sections and gadgets, Lianja comes with a cross-platform, UI independent application framework called the Lianja UI Framework.

Lianja UI Framework

The Lianja UI Framework is a feature rich application framework used to build custom UI elements for the desktop, web and mobile devices. The classes, methods and properties in the framework are compatible with those in Visual FoxPro 9.0 but have been extensively extended to make it easier to build UIs for Apps that will run on the desktop, web and mobile devices. In particular, it has complete Layout Manager support, and provides the ability for each UI component to be skinned using CSS attributes (the Stylesheet property).

Pro Tip

We recommend you use Lianja UI Layouts to help you build a responsive UI. These can be used in any of the supported scripting languages.

You use Visual FoxPro, JavaScript, Python or PHP with the Lianja UI Framework to build Custom Sections and Custom Gadgets. All Lianja UI Framework Classes provide integrated data binding to the underlying Lianja embedded database (the Controlsource property).

For details of the classes available in the Lianja UI Framework see the here.

Building a Custom Section

Let's get started and build a simple Custom Section that displays some data from a database in a Grid. Firstly, open or create an App and add a Custom Section to a blank page.

New Custom Section

Editing the Custom Section code

To edit the code for the Custom Section move the mouse cursor over the Section header and click the Keyboard icon.

Edit Custom Section Code

Note that you use this same procedure to edit both Custom Sections and Custom Gadgets but in the case of Gadgets you move the mouse over the gadget header.

The Apps workspace panel will then be displayed and the template code for the Custom Section will be generated and available for you to edit.

Script Editor Template

After you complete the code editing, just click on the Switch to Pages workspace toolbutton. This causes the code you edited to be saved, compiled and reloaded into the custom section on the page. You continue this process iteratively until the custom section UI is complete.

Using the Lianja UI Framework

As stated earlier you build Custom Sections and Gadgets using the Lianja UI Framework. When building a Custom Section you should subclass the Section class. When building a Custom Gadget you should subclass the Gadget class.

Creating a Custom Section

Seeing that we are building a Custom Section in this tutorial, let's take a look at the code for a Custom Section which consists of a tabbed PageFrame containing a Grid with a simple address book style navigation ListBox that populates the Grid with data when the ListBox is clicked.

# Lianja custom Python section "page1_section1"
import Lianja
# Step 1: Define the classes we need
# Note that all Lianja UI Framework classes can be subclassed in Python
class mySection(Lianja.Section):
    def add(self):
        Lianja.showMessage("add() was called")
    def delete(self):
        Lianja.showMessage("delete() was called")
    def first(self):
        Lianja.showMessage("first() was called")
    def previous(self):
        Lianja.showMessage("previous() was called")
    def next(self):
        Lianja.showMessage("next() was called")
    def last(self):
        Lianja.showMessage("last() was called")
    def refresh(self):
    def search(self):
    def watch(self):
        Lianja.showMessage("watch() was called")
    def edit(self):
        Lianja.showMessage("edit() was called")
    def save(self):
        Lianja.showMessage("save() was called")
    def cancel(self):
        Lianja.showMessage("cancel() was called")
# Note how the click() event handler for the ListBox is defined in Python
class myListbox(Lianja.Listbox):
    def click(self):
        ui_grid.clear( )
        # Note how the AddItems method of Grid, ListBox and ComboBox can take 
        # a SQL SELECT statement as an argument
        if ui_listbox.text == "All":
            ui_grid.additems('select * from southwind!example where last_name != " "')
            ui_grid.additems('select * from southwind!example where upper(left(last_name,1)) \
            = "' + ui_listbox.text + '"')
        ui_grid.refresh( )
# Step 2: Create the Section object
# Note that the CreateObject() method needs two args: objectname, classname
oSection = Lianja.createObject("oSection", "mySection")
oSection.backcolor = "lightgreen"
oSection.caption = "This is a custom Python section"
# Step 3: create a PageFrame object and add it to the Section
oSection.addObject("ui_tabs", "Pageframe")
# Step 4: Add a Page to the Pageframe object and set some of its properties
ui_tabs.addobject("ui_tab_customers", "Page")
ui_tab_customers.caption = "Customers"
# Step 5: Add a Container to the Page and set some of its properties
# The AddObject() method takes the objectname as the first arg then the classname as the second.
ui_tab_customers.addobject("ui_cont", "Container") 	
ui_cont.autosize = 1
ui_cont.backcolor = "lightblue"
ui_cont.layout = "horizontal"
ui_cont.margin = 5
ui_cont.spacing = 5
# Step 6: Add a ListBox to the Container and set some of its properties
ui_cont.addobject("ui_listbox", "myListbox")
ui_listbox.fixedwidth = 200
# Step 7: Invoke the AddItems method with a comma separated list of items to add to the ListBox
# Step 8: Add a Grid to the Container
ui_cont.addobject("ui_grid", "Grid")
ui_grid.rowheight = 20
ui_grid.readonly = 1
ui_grid.recordmark = 0
ui_grid.closable = 0
ui_grid.caption = "Sample data"
ui_grid.additems('select * from southwind!example where last_name != " "')
ui_grid.autofit( )
ui_grid.refresh( )
# Step 9: Add a couple more Page objects to the PageFrame
ui_tabs.addobject("ui_tab_orders", "Page")
ui_tab_orders.caption = "Orders"
ui_tabs.addobject("ui_tab_shippers", "Page")
ui_tab_shippers.caption = "Shippers"
# Step 10: Return the section back to the Lianja. We accomplish this by assigning
# it to the global returnvalue variable.
returnvalue = oSection
Custom Section in Pages Workspace

For details of the classes available in the Lianja UI Framework see here.

Global functions available to your Python code

When you develop a Custom Section or Gadget in Python, the Lianja UI Framework makes available several built-in global Python functions to enable you to interact with Lianja and the embedded Lianja database. This provides you with a embedded Python database with full SQL and noSQL data access.

# include the lianja module
import Lianja
  • Lianja.createObject(objectname, classname)
  • Lianja.openDatabase(dbname)
  • Lianja.showMessage(messagetext)
  • Lianja.execute(lianjacommandstring)
  • Lianja.evaluate(lianjaexpression)

Note that you can also use the Python import command to utilize any other Python modules that you have installed on your system in your Lianja application.

Containers, Components and Utility classes

The Lianja UI Framework has a wide range of classes available for you to use in Custom Sections and Custom Gadgets. These classes are categorized as Containers, Components or Utility classes.

Container classes available in the Lianja UI Framework

Container classes are UI classes that can have other UI classes (Containers or Components) added to them to construct a hierarchical tree of visual elements. You add objects to existing objects using the AddObject( ) method of a container. The first argument is the name of the object you want to create and the second is the name of the class that you want to instantiate e.g.

# include the lianja module
import Lianja
# create a new object called "myobj" which is a "Container"
myobj = Lianja.createObject("myobj", "Container")
# add a new object variable called "mygrid" which is a "Grid" 
myobj.addObject("mygrid", "Grid")

Container classes are UI classes that can have other UI classes added to them and include the following.

Component classes available in the Lianja UI Framework

Component classes are UI classes that cannot have other UI classes added to them and include the following.

Utility classes available in the Lianja UI Framework

Object Methods, Properties and Events

All classes in the Lianja UI Framework have Methods and Properties. Methods are procedures that control the behavior of the object and Properties are attributes that control the appearance and functionality of the object. All classes in the framework have a common set of Properties and Methods and others that are specific to the class. e.g.

Some common properties:

  • Left
  • Top
  • Width
  • Height
  • BackColor
  • ForeColor

Some common methods:

  • show
  • hide

Events are actions that are triggered when an object is affected by some external action e.g. clicking a CommandButton or editing a TextBox.

By subclassing the Lianja UI Framework classes you can define your own Event procedures that will be called when an event is triggered. e.g. let's declare a class that subclasses a CommandButton and responds to the click event.

import Lianja
class mybutton(Lianja.Commandbutton):
    def click(self):
        Lianja.showMessage("You clicked the button!")

From v7.2 dynamic binding to event handlers is supported in custom Python code in the same way as in LianjaScript and Javascript: = my_click_function