

.. Welcome!
.. As you can see, these are comments: they start with two dots and a space
.. Sphinx is very sensitive to spaces, empty lines, etc. so it can sometimes be frustrating
.. Two dots and a space are also used for special tagging, inclusion, etc.  Like here, where we are creating an internal link:

.. _intro:

.. So, lets start writing the documentation
.. Title fonts are written like this:

About this module
=================

Overview
--------

Word of warning: this is not your traditional database/object mapper - if you need a lightweight orm for mongo, check out `this project <https://github.com/elsampsa/mongo_map>`_ instead.

This module is about creating graphical user interfaces in Qt that interact with an underlying programming logic and a document database (say, MongoDB) in an automatic fashion.

Both the view, database patterns ("model" or "schema") and field validations are declared in one-shot:

::

  class PersonRow(Row):    
    columns=[
      ColumnSpec(LineEditColumn, key_name="firstname", label_name="First Name"),
      ColumnSpec(LineEditColumn, key_name="surname",   label_name="Surname"),
      ColumnSpec(LineEditColumn, key_name="address",   label_name="Address")
    ]


This declares a column structure in a document database ("schema").  It also declares an autogenerated Qt form that is presented to the user (view).  The Qt form can also validate the input fields with a QValidator.

Relations are declared like this:

::

  class PersonRowExtended(Row):
    columns=[
      ColumnSpec(LineEditColumn, key_name="firstname", label_name="First Name"),
      ColumnSpec(LineEditColumn, key_name="secondname",label_name="Second Name"),
      ColumnSpec(LineEditColumn, key_name="surname",   label_name="Surname"),
      ColumnSpec(LineEditColumn, key_name="address",   label_name="Address"),
      # let's specify a relation to "food_collection"
      ColumnSpec(ListEditColumn, key_name="foods",     label_name="Favorite foods",  collection=food_collection, foreign_label_name="name")
    ]

In the *PersonRowExtended* row class, the last columns corresponds to a list (*ListEditColumn*) where user can choose several foods.  The details of each food are found in the *food_collection* (that can be a simple collection or a MongoDB).
    
A collection is instantiated by passing it the row classes:
    
::
    
  collection=SimpleCollection(
    filename="simple_test.db",
    row_classes=[PersonRow,PersonRowExtended]
    )
    
In this example, the collection can have two different row structures corresponding to *PersonRow* and *PersonRowExtended*.


What it does?
-------------

Once you instantiate a row

::

  person_row =PersonRow()

You'll get for "free" the corresponding QWidget form (at the "widget" member) that you can parent to your Qt program, like this:

::

  person_row.widget # the QtWidget form
  person_row.widget.setParent(some_parent_widget) # let's parent it to someone
  
  
However, normally you don't instantiate the Row classes (and the associated QtWidget forms) yourself, but leave that to "containers", such as the *FormSet* container:

::

  formset=FormSet(collection=collection)

*Formset* gets from "collection" the Row classes (that we just declared - see above), instantiates them and places their widgets correctly in place inside the container's own widget (accessible in *formset.widget*).

**The container uses the database to update the data in the Row's QtWidget forms automatically**, displays the the correct form in question (*PersonRow* or *PersonRowExtended*) and writes the database, according to user's interaction with the QtWidget forms.

In a more traditional db/object mapper, the data is placed in an "intermediate layer", i.e. into an object that gives easy access to the data and may perform type etc. checking on the data.  Here that object is the QtWidget itself!  If you want certain type of constraints to the data, create a custom Column class and there, use a QValidator.  This way your data is always validated.


Try it out
----------

Brave enough to give it a try?

An example tells more than thousand explanatory words, so take a look at the :ref:`tutorial. <tutorial>`

The prerequisites are, that you are quite familiar with Python, Qt and their combination, PyQt.

There is a more complex example available (with a larger schema and several relations using MongoDB) :ref:`here. <example>`
