Nominate our 2022 Qt Champions!

How to binding QAbstractTableModel and QML TableView ?

  • Hi All ,

    I would like create sample qt application that can extract data from python object to QML tableview .

    So i search from google and than implement QAbstractTableModel my self .

    Unfortunately , it don't work .

    Please check source code first , bottom is my source code show what i doing .

    Program most time report Segmentation fault : 11

    In some time it can successful execute but empty result .

    If i change setContextProperty timing from before load to after load QML . Program is fire . data , role names , rowCount ..etc. All thing has been invoked , just but no result to display .

    If i don't using QML , just create QTableView is coding , everything is fire now .

    But unfortunately again , i must use QML .

    Any people can let me know what i wrong ??

    My Source code here , DummyList is my implementation of QAbstractTableModel

    import sys
    import collections
    from PyQt5 import Qt
    class DummyList(Qt.QAbstractTableModel):
        __DEFAULT__ = Qt.QVariant()
        def __init__(self,*args,**kwargs):
            self.__roles = {}
            self.__data = []
                    ("hello_would", "HELOOWOULD",),
                    ("foobar" , "ECHO",),
                    ("zebra"  , "FOO",),
                    ("ummmm"  , "BAR",)
        def append_data(self,value,header_update=False):
            last_index = self.rowCount()
            value = collections.OrderedDict(value)
            if header_update:
                for key in value.keys():
                    if key not in self.__roles.values():
                        self.__roles[ Qt.Qt.UserRole + len(self.__roles) ] = key
        def headerData(self,section,orientation,role):
            if role == Qt.Qt.DisplayRole:
                column = self.__roles.get(Qt.Qt.UserRole + section,Qt.QVariant())
                column = self.__roles.get(role,Qt.QVariant())
            return column
        def columnCount(self,parent=Qt.QModelIndex()):
            return len(self.__data[0])
        def rowCount(self,parent=Qt.QModelIndex()):
            return len(self.__data)
        def roleNames(self):
                Model only invoked while binding to QML view .
            default_roles = super(DummyList,self).roleNames()
            default_roles.update({ key:Qt.QByteArray(value.encode()) for key,value in self.__roles.items()})
            return default_roles
        def data(self,index,role):
            row = index.row()
            if index.isValid():
                if role >= Qt.Qt.UserRole:
                    Only fire on binding to QML
                    column = self.__roles[role]
                elif role == Qt.Qt.DisplayRole:
                    column = self.__roles[Qt.Qt.UserRole + index.column()]
                    return DummyList.__DEFAULT__
                col_data = self.__data[row][column]
                return Qt.QVariant(col_data)
                return DummyList.__DEFAULT__
    class MyWindow(Qt.QWidget):
        def __init__(self, *args):
            Qt.QWidget.__init__(self, *args)
            tablemodel = DummyList(self)
            tableview = Qt.QTableView()
            layout = Qt.QVBoxLayout(self)
    def main(*args,**kwargs):
        # We instantiate a QApplication passing the arguments of the script to it:
        main_app = Qt.QApplication(list(args))
            Load tableview in QML , it will Segmentation fault: 11
            or display empty table
        qml_app_engine = Qt.QQmlApplicationEngine(
        qml_app_engine.rootContext().setContextProperty("tableModel",DummyList())#If set property here , raise segementation most time
        #qml_app_engine.rootContext().setContextProperty("tableModel",DummyList())#Nothing to show , but data method has been invoked
        new_root = qml_app_engine.rootObjects()[0]
        Load with custom create widget , everything is fine
        #w = MyWindow()
        # Now we can start it.
        return_code = main_app.exec_()
        #del app.global_["qml_viewer"]
        return return_code
    if __name__ == "__main__":

    QML Source code :

    import QtQuick 2.4
    import QtQuick.Controls 1.3
    import QtQuick.Window 2.2
    import QtQuick.Dialogs 1.2
    ApplicationWindow {
        //property var tableModel
        title: qsTr("Hello World")
        width: 640
        height: 480
        TableView {
            model: tableModel
            anchors.fill: parent
            Component.onCompleted: console.log(tableModel)
            TableViewColumn {
                role: "hello_would"
                title: "Hello Would"
            TableViewColumn {
                role: "foobar"
                title: "Foobar"
            TableViewColumn {
                role: "zebra"
                title: "Zebra"
            TableViewColumn {
                role: "ummmm"
                title: "Ummmm"

Log in to reply