[PyQt] Model in qml has incorrect behavoiur

Phil Thompson phil at riverbankcomputing.com
Sun Sep 11 16:45:33 BST 2016


On 25 Aug 2016, at 2:41 pm, Ilya Volkov <nxsofsys at gmail.com> wrote:
> 
> 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.
> 

Adding Qt::UniqueConnection to the connect() call within connectNotify() seems to fix it.

Thanks,
Phil



More information about the PyQt mailing list