[PyQt] segfault!...and more
Alberto Berti
alberto at metapensiero.it
Thu Jan 17 19:14:14 GMT 2008
Hi all,
i'm quite new to this list, but i'm working with PyQT4 with great
satisfaction to develop a framework, and an application, to build
database driven applications using the model/view/delegate approach
with SQLAlchemy (http://sqlalchemy.org) instead of the standard SQL
enabled tree of models in QT. I've finished the low-level of
sqlalchemy related storages and i'm completing the AbstractTableModel
subclass that is usable as a QSQLRelationalTableModel replacement,
with semi-automatic wiring of the realtions thanks to SQLAlchemy
metadata introspection. Now it supports 1-1 relations, with 1-n
realtions to be completed for the end of the week:-). I've
encountered a problem during the coding of a demo which i don't know
handle. I know it's related to the fact of a qt component that is
taking ownership of python objects, but nothing more.
Aside from this, does someone know the location of the repositories
for PyQt4 and PyKDE?
There is an updated QT 4.3 doxygen api available online?
Thanks in advance, especially to those that worked to make pyqt4:)
Here is the relevant code (it's long, I hope that someone will find
te time to read it), commented to help your reading:
if __name__ == '__main__':
# A simple displaying combo boxes on 1-to-1 relations
from pypapi.db.interfaces import IIterProcedurale, IElementoAnagrafico, IDatabase
from pypapi.db.model import ElementoAnagrafico, IterProcedurale
from pypapi.db.storage import SAListStore
from zope.schema import getFieldsInOrder
# database initialization
db = getUtility(IDatabase)
db.open('sqlite:///procedimenti.sqlite')
# creation of the low-level stores that handle the join or the
# deletion of enitities instances from the persistence using
# standard list semantics. The 2nd and 3rd SAListStore are built
# using prconfigured lookup sources
iter_proc = SAListStore(db.session.query(IterProcedurale))
enti = SAListStore(IIterProcedurale.get('ente').source(IterProcedurale))
uffici = SAListStore(IIterProcedurale.get('ufficioattribuito').source(IterProcedurale))
# Now i create the three model classes, selecting proper subset of fields
# and generating "QtModel" oriented "views" of these field on the fly
class IterProcModel(TableModel):
# the last 3 fields are not rendered because they are 1-n
# relations, still unsupported
columns = [IColumn(field) for name, field in getFieldsInOrder(IIterProcedurale)][:-3]
class EnteModel(TableModel):
columns = [Column('getCaption', 'Enti')]
class UfficioModel(TableModel):
columns = [Column('getCaption', 'Uffici')]
from PyQt4.QtGui import QApplication, QTableView
# QT App init
app = QApplication([])
# Here the actual model instances are created, using the stores
ip_model = IterProcModel(iter_proc, app)
e_model = EnteModel(enti, app)
u_model = UfficioModel(uffici, app)
# wiring of the relations. This step and the latter over here will
# be automated inside form's code
col_ente = ip_model.getColumnByName('ente')
col_ente.setLookupModel(e_model, 'getCaption')
col_ufficio = ip_model.getColumnByName('ufficioattribuito')
col_ufficio.setLookupModel(u_model, 'getCaption')
from PyQt4.QtGui import QItemEditorCreatorBase, QComboBox, \
QItemEditorFactory, QSpinBox, QLineEdit
# here i define a couple of editor creators. The first and most
# important redefines the standard editing of Int cells to render
# a QComboBox when the cell looks up its value on another table.
# The second is there just to handle the editing o string cells,
# Using the standard behavior. It's there just to allow editing
# because installing just LookupEditorCreator in the default
# factory doesn't work. So i create my own factory and install it.
class LookupEditorCreator(QItemEditorCreatorBase):
def createWidget(self, parent):
# qui parent è in delegato, perciò parent.parent() è la
# tabella
view = parent.parent()
index = view.currentIndex()
item = index.internalPointer()
if isinstance(item, LookupItem):
widget = QComboBox(parent)
widget.setModel(item.column.lookup_model)
else:
widget = QSpinBox(parent)
# piccola fix per permettere valori > 99
widget.setMaximum(10000)
return widget
def valuePropertyName(self):
return 'currentIndex'
class StringEditorCreator(QItemEditorCreatorBase):
def createWidget(self, parent):
return QLineEdit(parent)
#!!! This code works as expected, but a Segmentation Fault is
# raised on application termination, why?
edit_fac = QItemEditorFactory()
creator = LookupEditorCreator()
s_creator = StringEditorCreator()
edit_fac.registerEditor(QVariant.Int, creator)
edit_fac.registerEditor(QVariant.String, s_creator)
QItemEditorFactory.setDefaultFactory(edit_fac)
ip_view = QTableView()
ip_view.setModel(ip_model)
ip_view.show()
app.exec_()
db.close()
More information about the PyQt
mailing list