[PyQt] Model in qml has incorrect behavoiur

Ilya Volkov nxsofsys at gmail.com
Thu Aug 25 14:41:05 BST 2016


Hi

If QAbstractItemModel registered in qml and created in qml, it is not
possible to
use same model in two or more lists, because item inserting cause multiple
signal
propagation to lists.

I've done example:

Python script:

import sys
from PyQt5.QtCore import QUrl
from PyQt5.QtWidgets import QApplication
from PyQt5.QtQuick import QQuickView
from PyQt5.QtCore import QAbstractItemModel
from PyQt5.QtQml import qmlRegisterType
from PyQt5.QtCore import Qt
from PyQt5.QtCore import pyqtSlot
from PyQt5.QtCore import QModelIndex

class ExampleModel(QAbstractItemModel):

    def __init__(self, parent, **kwargs):
        super().__init__(parent=parent, **kwargs)
        self.row_count = 0

    def rowCount(self, index):
        return self.row_count

    @pyqtSlot(int, name='doInsert')
    def do_insert(self, count):
        self.beginInsertRows(QModelIndex(), self.row_count,
self.row_count+count-1)
        self.row_count += count
        self.endInsertRows()

    def index(self, row, col, index):
        return self.createIndex(row, col)

    def roleNames(self):
        return {Qt.UserRole: b'value'}

    def data(self, index, role=Qt.DisplayRole):
        if index.row() < self.row_count:
            return 'Correct index'
        return 'Wrong index'

if __name__ == '__main__':
    myApp = QApplication(sys.argv)
    qmlRegisterType(ExampleModel, "EXAMPLE.Models", 1, 0, "ExampleModel")
    content = QQuickView()
    content.setSource(QUrl('example.qml'))
    content.show()
    myApp.exec_()
    sys.exit()

example.qml:

import EXAMPLE.Models 1.0
import QtQuick.Controls 1.4
import QtQuick 2.6

Item {
    width: 600
    height: 500

    ExampleModel {
        id: exampleModel
    }
    Column {
        Row{
            ListView {
                width: 200
                height: 300
                model: exampleModel
                delegate: Text {
                    text: value
                }
            }
            ListView {
                width: 200
                height: 300
                model: exampleModel
                delegate: Text {
                    text: value
                }
            }
        }

        Button {
            text: "click me"
            onClicked: exampleModel.doInsert(1)
        }
    }
}


I think there is error in QPyQmlObjectProxy::connectNotify - every
time when ListView connects to QPyQmlObjectProxy it duplicates
connection to proxied model, as result proxied model's signal invokes
connection more than one time.

thanks
-- 
Ilya Volkov
nxsofsys at gmail.com
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://www.riverbankcomputing.com/pipermail/pyqt/attachments/20160825/9c3ab5bd/attachment-0001.html>


More information about the PyQt mailing list