[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