[PySide] Segfault when using QSqlQueryModels
Boris Pohler
boris at pohlers-web.de
Thu May 16 20:40:28 CEST 2013
Hi,
I want to get data out of a sqlite-db and put it into models, which are
provided to a QML-UI. I subclass QtSql.QSqlQueryModel and override the
setQuery-method to set the UserRolenames to get access to more than one
column of the query-result. This works so far, but sometimes the
programm crashes with a segmentation fault. The UI consists of
listviews. If an item is clicked, the corresponding model is updated and
the data is shown within a listview in a new page. I attach the
python-file and one of the QML-Files. What am I missing?
Greetings
Boris Pohler
Python:
#!/usr/bin/python
# -*- coding: utf-8 -*-
import sys
from PySide import QtSql, QtGui, QtDeclarative, QtCore
querys = {
"stufen": 'SELECT DISTINCT stufe FROM kurse\
WHERE stufe!="" ORDER BY stufe',
"schueler_stufe" : 'SELECT schuelerId, vorname, nachname,\
substr(nachname,1,1) as alphabet\
FROM schueler\
WHERE stufe="{0}"\
ORDER BY nachname',
"schueler_kurs" : 'SELECT s.schuelerId, vorname, nachname,
substr(nachname,1,1) as alphabet\
FROM schueler s, kurswirdbesucht kwb\
WHERE s.schuelerId = kwb.schuelerId\
AND kursId={0} ORDER BY nachname',
"noten" : 'SELECT nachname, s.stufe, fach, note\
FROM schueler s, kurse k, kurswirdbesucht kwb\
WHERE kwb.schuelerId = s.schuelerId\
AND k.kursId = kwb.kursId\
AND s.schuelerId = {0} AND note !=-1',
"lehrer" : 'SELECT lehrerId, kuerzel FROM lehrer ORDER BY kuerzel',
"kurse" : 'SELECT kurse.kursId as kursId, stufe, fach\
FROM kurse, lehrerunterrichtet\
WHERE lehrerunterrichtet.lehrerId={0}\
AND kurse.kursId = lehrerunterrichtet.kursId\
ORDER BY stufe, fach'}
class SqlQueryModel(QtSql.QSqlQueryModel):
def __init__(self, parent=None):
super(SqlQueryModel,self).__init__(parent)
def setQuery(self, query):
super(SqlQueryModel,self).setQuery(query)
self.generateRoleNames()
def generateRoleNames(self):
roleNames = super(SqlQueryModel,self).roleNames()
for i in range(self.record().count()):
roleNames[QtCore.Qt.UserRole + i + 1] =
str(self.record().fieldName(i))
self.setRoleNames(roleNames)
def data(self, index, role = QtCore.Qt.DisplayRole):
if role < QtCore.Qt.UserRole:
value = super(SqlQueryModel,self).data(index, role)
else:
columnIdx = role - QtCore.Qt.UserRole - 1;
modelIndex = QtCore.QModelIndex(self.index(index.row(),
columnIdx))
value = super(SqlQueryModel,self).data(modelIndex,
QtCore.Qt.DisplayRole)
return value
class Controller(QtCore.QObject):
def __init__(self, querys):
QtCore.QObject.__init__(self)
self._querys = querys
@QtCore.Slot(QtCore.QObject, str, str)
def update_model(self, model, keyword, value):
model.setQuery(self._querys[keyword].format(value))
if __name__ == "__main__":
app = QtGui.QApplication([])
db = QtSql.QSqlDatabase.addDatabase("QSQLITE")
db.setDatabaseName("noten.db")
db.open()
stufen_model = SqlQueryModel()
schueler_model = SqlQueryModel()
noten_model = SqlQueryModel()
lehrer_model = SqlQueryModel()
kurse_model = SqlQueryModel()
stufen_model.setQuery(querys["stufen"])
schueler_model.setQuery(querys["schueler_stufe"].format('10X'))
noten_model.setQuery(querys["noten"].format('1'))
lehrer_model.setQuery(querys["lehrer"])
kurse_model.setQuery(querys["kurse"].format('1'))
controller = Controller(querys)
view = QtDeclarative.QDeclarativeView()
rc = view.rootContext()
rc.setContextProperty('controller', controller)
rc.setContextProperty('stufenModel', stufen_model)
rc.setContextProperty('schuelerModel', schueler_model)
rc.setContextProperty('notenModel', noten_model)
rc.setContextProperty('lehrerModel', lehrer_model)
rc.setContextProperty('kurseModel', kurse_model)
view.setSource("main.qml")
view.showFullScreen()
sys.exit(app.exec_())
QML
import QtQuick 1.1
import com.nokia.meego 1.1
Page {
id: namenPage
tools: commonTools
orientationLock: PageOrientation.LockPortrait
ListView {
id: listView_namen
clip: true
focus: true
anchors.fill : parent
anchors.margins: 10
model: schuelerModel
delegate: schuelerDelegate
}
Component {
id: schuelerDelegate
Item {
width: parent.width; height: 100
Text { anchors.fill: parent; text: nachname+ ", " + vorname;
color: "white";
font.pointSize: 30;}
MouseArea {
anchors.fill : parent
onClicked : { listView_namen.currentIndex = index;
console.log("Clicked on " + schuelerId);
controller.update_model(notenModel, "noten",
schuelerId);
pageStack.push(notenPage)
}
}
}
}
}
More information about the PySide
mailing list