QAbstractListModel data override never trigger
-
Hi everybody,
I created a subclass of QAbstractListModel. I put a breakpoint into the data method but never fired. I made the same things in that book. The example in the book works as expected but my program doesn't work.
My Model# This Python file uses the following encoding: utf-8 import sys from os.path import abspath, dirname, join from PySide2.QtGui import QGuiApplication from PySide2.QtQml import QQmlApplicationEngine, qmlRegisterType from PySide2.QtCore import QUrl, QTimer, QAbstractListModel from PySide2.QtCore import QObject, Signal, Slot, Property, Qt from .models import * class ConversationModel(QAbstractListModel): def __init__(self): QAbstractListModel.__init__(self) try: database.connect(reuse_if_open=True) self._result = None self._count = 0 self.__update_timer = QTimer(self) self.__update_timer.setInterval(1000) self.__update_timer.timeout.connect(self.__load) self.__update_timer.start() except: print("con error") def __load(self): self._result = Conversation.select(Conversation, Contact).join(Contact) self._count = self._result.count() self.dataChanged.emit(self.index(0, 0), self.index(int(self._count - 1), 0)) def rowCount(self, parent): return int(self._count) def data(self, index, role): print("tst") if (role == Qt.DisplayRole and index.row() >= 0 and index.column() == 0): return dict(message=self._result[index.row()].message) else: return None
My qml file:
import QtQuick 2.12 import QtQuick.Layouts 1.12 import QtQuick.Controls 2.12 import "../Bases" import MModels 1.0 BasePage{ Item{ width:parent.width height:500 ConversationModel{ id:mmodel } Label{ text:"Burada mesajlar" } ListView { id: conView Layout.fillWidth: true Layout.fillHeight: true verticalLayoutDirection: ListView.TopToBottom model:mmodel delegate: Label{ text: message } } } Component { id: nameDelegate Label { text: "test " + model.message; font.pixelSize: 24 } } Component.onCompleted: { //mmodel.load() } }
-
Hi,
Thing is, your code, while close to the example is a bit different: you have imports (both in qml and python) in there that you don't show nor the main part where you setup the application.
-
Hi,
Thing is, your code, while close to the example is a bit different: you have imports (both in qml and python) in there that you don't show nor the main part where you setup the application.
@SGaist
Hi SGaist,
The problem was reduced. In my code when I set the count zero, first rowCount return zero and then any dataChanged.emit never call the data method. When I call __load in constructor of ConversationModel, It works normally. Actually my expectation is that when rowCount return value changes ListView would refresh itself with the delegate. So I looked at the documentation of QAbstractListModel but I haven't found any size changed signal. I think I have to create manually.
Thanks. -
@SGaist
Hi SGaist,
The problem was reduced. In my code when I set the count zero, first rowCount return zero and then any dataChanged.emit never call the data method. When I call __load in constructor of ConversationModel, It works normally. Actually my expectation is that when rowCount return value changes ListView would refresh itself with the delegate. So I looked at the documentation of QAbstractListModel but I haven't found any size changed signal. I think I have to create manually.
Thanks.@CKurdu
I know nothing about QML, only aboutQAbstractListModel
. If you are re-loading the whole data such thatrowCount()
changes, I'm thinkingdataChanged
is not enough, as that expects data inside existing rows to have changed, but not extra rows inserted/removed.I'm thinking you should be using https://doc.qt.io/qt-5/qabstractitemmodel.html#modelReset
Note that if a model is reset it should be considered that all information previously retrieved from it is invalid. This includes but is not limited to the
rowCount()
...Or possibly https://doc.qt.io/qt-5/qabstractitemmodel.html#beginInsertRows etc. if you want to do it by signalling as rows inserted/removed.