[prev in list] [next in list] [prev in thread] [next in thread] 

List:       pykde
Subject:    [PyQt] Model in qml has incorrect behavoiur
From:       Ilya Volkov <nxsofsys () gmail ! com>
Date:       2016-08-25 13:41:05
Message-ID: CAHdH1=dHGh6nk0hJeBotLH3Stvn9VgZR8ZcZShqBuBSnJOiwTQ () mail ! gmail ! com
[Download RAW message or body]

[Attachment #2 (multipart/alternative)]


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@gmail.com

[Attachment #5 (text/html)]

<div dir="ltr"><div>Hi</div><div><br></div><div>If QAbstractItemModel registered in \
qml and created in qml, it is not possible to</div><div>use same model in two or more \
lists, because item inserting cause multiple signal</div><div>propagation to \
lists.</div><div><br></div><div>I&#39;ve done \
example:</div><div><br></div><div>Python script:</div><div><br></div><div><div>import \
sys</div><div>from PyQt5.QtCore import QUrl</div><div>from PyQt5.QtWidgets import \
QApplication</div><div>from PyQt5.QtQuick import QQuickView</div><div>from \
PyQt5.QtCore import QAbstractItemModel</div><div>from PyQt5.QtQml import \
qmlRegisterType</div><div>from PyQt5.QtCore import Qt</div><div>from PyQt5.QtCore \
import pyqtSlot</div><div>from PyQt5.QtCore import \
QModelIndex</div><div><br></div><div>class \
ExampleModel(QAbstractItemModel):</div><div><br></div><div>      def __init__(self, \
parent, **kwargs):</div><div>            super().__init__(parent=parent, \
**kwargs)</div><div>            self.row_count = 0</div><div><br></div><div>      def \
rowCount(self, index):</div><div>            return \
self.row_count</div><div><br></div><div>      @pyqtSlot(int, \
name=&#39;doInsert&#39;)</div><div>      def do_insert(self, count):</div><div>       \
self.beginInsertRows(QModelIndex(), self.row_count, \
self.row_count+count-1)</div><div>            self.row_count += count</div><div>      \
self.endInsertRows()</div><div><br></div><div>      def index(self, row, col, \
index):</div><div>            return self.createIndex(row, \
col)</div><div><br></div><div>      def roleNames(self):</div><div>            return \
{Qt.UserRole: b&#39;value&#39;}</div><div><br></div><div>      def data(self, index, \
role=Qt.DisplayRole):</div><div>            if index.row() &lt; \
self.row_count:</div><div>                  return &#39;Correct index&#39;</div><div> \
return &#39;Wrong index&#39;</div><div><br></div><div>if __name__ == \
&#39;__main__&#39;:<br></div><div>      myApp = QApplication(sys.argv)<br></div><div> \
qmlRegisterType(ExampleModel, &quot;EXAMPLE.Models&quot;, 1, 0, \
&quot;ExampleModel&quot;)<br></div><div>      content = QQuickView()<br></div><div>   \
content.setSource(QUrl(&#39;example.qml&#39;))</div><div>      \
content.show()<br></div><div>      myApp.exec_()<br></div><div>      \
sys.exit()</div></div><div><br></div><div>example.qml:</div><div><br></div><div><div>import \
EXAMPLE.Models 1.0</div><div>import QtQuick.Controls 1.4</div><div>import QtQuick \
2.6</div><div><br></div><div>Item {</div><div>      width: 600</div><div>      \
height: 500</div><div><br></div><div>      ExampleModel {</div><div>            id: \
exampleModel</div><div>      }</div><div>      Column {</div><div>            \
Row{</div><div>                  ListView {</div><div>                        width: \
200</div><div>                        height: 300</div><div>                        \
model: exampleModel</div><div>                        delegate: Text {</div><div>     \
text: value</div><div>                        }</div><div>                  \
}</div><div>                  ListView {</div><div>                        width: \
200</div><div>                        height: 300</div><div>                        \
model: exampleModel</div><div>                        delegate: Text {</div><div>     \
text: value</div><div>                        }</div><div>                  \
}</div><div>            }</div><div><br></div><div>            Button {</div><div>    \
text: &quot;click me&quot;</div><div>                  onClicked: \
exampleModel.doInsert(1)</div><div>            }</div><div>      \
}</div><div>}</div></div><div><br></div><div><br></div><div>I think there is error in \
QPyQmlObjectProxy::connectNotify - every</div><div>time when ListView connects to \
QPyQmlObjectProxy it duplicates</div><div>connection to proxied model, as result \
proxied model&#39;s signal invokes</div><div>connection more than one \
time.</div><div><br></div><div>thanks</div>-- <br><div class="gmail_signature" \
data-smartmail="gmail_signature">Ilya Volkov<br><a href="mailto:nxsofsys@gmail.com" \
target="_blank">nxsofsys@gmail.com</a></div> </div>


[Attachment #6 (text/plain)]

_______________________________________________
PyQt mailing list    PyQt@riverbankcomputing.com
https://www.riverbankcomputing.com/mailman/listinfo/pyqt

[prev in list] [next in list] [prev in thread] [next in thread] 

Configure | About | News | Add a list | Sponsored by KoreLogic