HomePage: https://bitbucket.org/jbmohler/qtalchemy/

Author: Joel B. Mohler

Download: https://pypi.python.org/packages/source/q/qtalchemy/qtalchemy-0.8.3.tar.gz


The QtAlchemy library is a collection of Qt Model-View classes and helper
functions to aid in rapid development of desktop database applications.  It
aims to provide a strong API for exposing foreign key relationships in elegant
and immediate ways to the user of applications.  Context menus, searches and
combo-boxes and tabbed interfaces are all utilized.  The use of SQLAlchemy
makes it possible that these features are supported on a variety of database
backends with virtually no code changes.

The Command class gives a way to construct menus and toolbars from decorated
python functions.  The power of this becomes more evident when bound to a view
where the command function can then receive the identifier of the selected item
of the view.  This provides a flexible way to link commands to any sqlalchemy
query generated views.

Documentation is available at http://qtalchemy.org .

QtAlchemy is currently being developed with Python 2.7.x, SQLAlchemy 0.8.x and
PySide 1.2.x.  Testing has been done on Python 3.3.2 and 2.7.5.  SQLAlchemy
tested versions include 0.8.2 and 0.9-pre.  Testing includes linux and Windows

As of QtAlchemy version 0.8.x, QtAlchemy uses PySide.  See licensing comments
at the bottom of this file.  To use PyQt4 instead of PySide, you must install
from the source in the bitbucket repository rather than PyPI since you need to
convert the source before running the install script.  Install in the following

    python qtbindings.py --platform=PyQt4
    python setup.py build
    sudo python setup.py install


In the interests of being concise, the example given here does not reference a

The UserAttr property class provides yet another type defined python property.
The purpose of reinventing this was to ensure that we could interact with our
models sufficiently and provide a uniform experience for SQLAlchemy column
properties and UserAttr properties.

    >>> from qtalchemy import UserAttr
    >>> import datetime
    >>> class Person(object):
    ...     name=UserAttr(str,"Name")
    ...     birth_date=UserAttr(datetime.date,"Birth Date")
    ...     age=UserAttr(int,"Age (days)",readonly=True)
    ...     @age.on_get
    ...     def age_getter(self):
    ...         return (datetime.date.today()-self.birth_date).days

With this declaration, we can declare a person and compute their age:

    >>> me = Person()
    >>> me.name = "Joel"
    >>> me.birth_date = datetime.date(1979,1,9)
    >>> me.age  #depends on today! -- #doctest: +SKIP
    >>> me.age-(datetime.date.today()-datetime.date(2011,1,9)).days  # on birthday 1<<5

We can create a dialog showing the name & birth-date.  The main magic happens
in the addBoundForm call which obtains labels from the UserAttr classes and
places the correct edit widgets on screen.

    >>> from PySide import QtCore, QtGui
    >>> from qtalchemy import MapperMixin, LayoutLayout, ButtonBoxButton, LayoutWidget
    >>> class PersonEdit(QtGui.QDialog,MapperMixin):
    ...     def __init__(self,parent,person):
    ...         QtGui.QDialog.__init__(self,parent)
    ...         MapperMixin.__init__(self)
    ...         self.person = person
    ...         vbox = QtGui.QVBoxLayout(self)
    ...         mm = self.mapClass(Person)
    ...         mm.addBoundForm(vbox,["name","birth_date"])
    ...         mm.connect_instance(self.person)
    ...         buttons = LayoutWidget(vbox,QtGui.QDialogButtonBox())
    ...         self.close_button = ButtonBoxButton(buttons,QtGui.QDialogButtonBox.Ok)
    ...         buttons.accepted.connect(self.btnClose)
    ...     def btnClose(self):
    ...         self.submit() # changes descend to model on focus-change; ensure receiving the current focus
    ...         self.close()

And, now, we only need some app code to actually kick this off

    >>> app = QtGui.QApplication([])
    >>> sam = Person()
    >>> sam.name = "Samuel"
    >>> d = PersonEdit(None,sam)
    >>> d.exec_()  # gui interaction -- #doctest: +