ทำไมไม่ dataChanged emitted หลังจาก beginInsertRows()และ endInsertRows()ในคลาสย่อยของ QAbstractListModel?

0

คำถาม

ฉันกำลังยุ่งอยู่กับ subclassing QAbstractListModel และฉันไม่คิดว่าฉันเข้าใจว่าต้องเหมาะสมเพิ่มข้อมูลที่คุณครูแต่พอกลับมา นี่เป็นสคริปต์ของฉันและ QML:

import QtQuick
import QtQuick.Controls

ApplicationWindow
{
    id: mainWindow
    visible: true
    title: qsTr("Sample Qt Quick application")
    width: 400
    height: 400
    color: "whitesmoke"

    Component.onCompleted: console.log("Component completed")

    Connections
    {
        target: main.custom_model
        function onDataChanged(topLeft, bottomRight, roles)
        {
            console.log("Custom model data changed")
        }
    }
    
}  // ApplicationWindow

import sys

from random import randint
from pathlib import Path
from PySide6.QtCore import Qt, QObject, QTimer, Property, QAbstractListModel, QModelIndex
from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine


class CustomModel(QAbstractListModel):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._my_items = []
        
        self._role1 = Qt.UserRole + 1
        self._role2 = Qt.UserRole + 2
        
        self._roles = {
            self._role1: b"role1",
            self._role2: b"role2"
        }
        
    def append_item(self, arg1, arg2):
        row_count = self.rowCount()
        self.beginInsertRows(QModelIndex(), row_count, row_count)

        self._my_items.append({
            self._roles[self._role1]: arg1,
            self._roles[self._role2]: arg2
        })

        self.endInsertRows()

    def rowCount(self, parent=QModelIndex()):
        """
        Required for subclasses of QAbstractListModels
        """
        return len(self._my_items)

    def data(self, index, role=Qt.DisplayRole):
        """
        Required for subclasses of QAbstractListModels
        """
        try:
            the_item = self._my_items[index.row()]
        except IndexError:
            return QVariant()

        if role in self._roles:
            key = self._roles[role]
            return the_item[key]

        return QVariant()

    def roleNames(self):
        return self._roles


class MainContextClass(QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self._model = CustomModel()

    def add_an_item(self):
        thing1 = randint(0, 9)
        thing2 = randint(0, 9)
        print("Adding {0} and {1}".format(thing1, thing2))
        self._model.append_item(thing1, thing2)

    @Property(QObject, constant=True)
    def custom_model(self):
        return self._model


def main():
    app = QGuiApplication(sys.argv)
    qml_app_engine = QQmlApplicationEngine()
    qml_context = qml_app_engine.rootContext()

    main_context = MainContextClass(parent=app)
    qml_context.setContextProperty("main", main_context)
    
    this_file_path = Path(__file__)
    main_qml_path = this_file_path.parent / 'example.qml'
    qml_app_engine.load(str(main_qml_path))

    timer = QTimer()
    timer.setInterval(1000)
    timer.setSingleShot(False)
    timer.timeout.connect(main_context.add_an_item)
    timer.start()

    sys.exit(app.exec())

    
if __name__ == '__main__':
    main()

ฉันคาดหวังเป็นองนั้นทุกครั้งที่ตัวจับเวลาครั้งแล้วออกมาเป็นแถวใหม่จะถูกเพิ่มเข้ากับคน listmodel และดังนั้น listmodel น dataChanged สัญญาณควรจะ emitted. คน Connections วัตถุเป็นสัญญาณผู้ดูแลควรแล้วพิมพ์ข้อความไว้ แต่มันดูเหมือนว่ามันไม่เคย executes:

$ python example.py
qml: Component completed
Adding 7 and 0
Adding 8 and 5
Adding 4 and 0
...

ถ้าฉันในข้อบังคับของเพิ่ม self.dataChanged.emit() หลังจาก endInsertRows()ก็เห็นได้ชัดว่าสัญญาณตัวจัดการ executes. แต่ในเอกสารทั้งหมดที่แล้วอย่างเช่นรหัสฉันเห็นเรื่องนี้ไม่เสร็จแล้ว ฉันอยากคุยกับเพื่อนคืนที่เหมาะสมเข้าไป?

pyside6 python python-3.x qml
2021-11-15 04:28:26
1

คำตอบที่ดีที่สุด

2

dataChanged คือ emitted(ในข้อบังคับ)เมื่อตอนที่ข้อมูลของรายการเปลี่ยนแปลงเมื่อฤติกรรมโรคจิต--การแทรกแถวนั้นคุณควรจะฟังให้ rowsAboutToBeInserted หรือ rowsInserted สัญญาณ:

Connections {
    target: main.custom_model

    function onRowsAboutToBeInserted(parent, first, last) {
        console.log("before", parent, first, last);
    }

    function onRowsInserted(parent, first, last) {
        console.log("after", parent, first, last);
        /* print data
        let index = main.custom_model.index(first, 0, parent);
        let data1 = main.custom_model.data(index, Qt.UserRole + 1);
        let data2 = main.custom_model.data(index, Qt.UserRole + 2);
        console.log(data1, data2);*/
    }
}

อีกด้านนึงใน PySide ไม่มี QVariantแทนที่คุณต้องกลับมาเป็นภาษาไพธอนวัตถุ,ในกรณีของโพรโทคอล aimcomment QVariant คุณต้องกลับมา None (หรือไม่มีอะไรนั่นคือคนเดียวกัน):

def data(self, index, role=Qt.DisplayRole):
    """
    Required for subclasses of QAbstractListModels
    """
    try:
        the_item = self._my_items[index.row()]
    except IndexError:
        return

    if role in self._roles:
        key = self._roles[role]
        return the_item[key]
2021-11-15 04:57:20

ในภาษาอื่นๆ

หน้านี้อยู่ในภาษาอื่นๆ

Русский
..................................................................................................................
Italiano
..................................................................................................................
Polski
..................................................................................................................
Română
..................................................................................................................
한국어
..................................................................................................................
हिन्दी
..................................................................................................................
Français
..................................................................................................................
Türk
..................................................................................................................
Česk
..................................................................................................................
Português
..................................................................................................................
中文
..................................................................................................................
Español
..................................................................................................................
Slovenský
..................................................................................................................

ดังอยู่ในนี้หมวดหมู่

ดังคำถามอยู่ในนี้หมวดหมู่