PySide Qt dataChanged.emit()不工作,但LayoutChanged.emit工作

2024-10-01 09:20:03 发布

您现在位置:Python中文网/ 问答频道 /正文

from PySide6.QtGui import QGuiApplication
from PySide6.QtQml import QQmlApplicationEngine, qmlRegisterType
from PySide6.QtCore import QObject, Signal, Slot, Property, Qt,QUrl, QTimer, QAbstractListModel


class CpuLoadModel(QAbstractListModel):
    def __init__(self):
        QAbstractListModel.__init__(self)

        self.__update_timer = QTimer(self)
        self.__update_timer.setInterval(1000)
        self.__update_timer.timeout.connect(self.__update)
        self.__update_timer.start()

        self.todos = []

    def __update(self):
        self.todos.append(random.randint(0, 99))
        self.layoutChanged.emit()
        print(self.todos)
        self.dataChanged.emit(self.index,self.index,[])

    def data(self, index, role):
        if role == Qt.DisplayRole:
            text = self.todos[index.row()]
            print(f"Text: {index.row()} role : {role}")
            print("--------")
            return text

    def rowCount(self, index):
        return len(self.todos)


if __name__ == '__main__':
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()
    qmlRegisterType(CpuLoadModel, 'PsUtils', 1, 0, 'CpuLoadModel')
    engine.load(QUrl("main.qml"))
    if not engine.rootObjects():
        sys.exit(-1)
    sys.exit(app.exec())

self.dataChange.emit方法根本不起作用,但是self.LayoutChange.emit可以工作,但会出现来自qml的错误

TypeError: Cannot read property 'width' of null

Tags: fromimportselfindexifdefupdatetodos
2条回答
import QtQuick 2.0
import QtQuick.Window 2.0
import QtQuick.Controls 2.0

import PsUtils 1.0

Window {
    id: root
    width: 640
    height: 480
    visible: true
    title: "CPU Load"

    ListView {
        id:listviewId
        anchors.fill: parent
        model: CpuLoadModel { }
        delegate: Rectangle {
            width: listviewId.width
            height: 30;
            color: "white"

            Rectangle {
                id: bar
                width: listviewId.width * display / 100.0
                height: 30
                color: "green"
            }

            Text {
                anchors.verticalCenter: parent.verticalCenter
                x: Math.min(bar.x + bar.width + 5, parent.width-width)
                text: display + "%"
            }
        }
    }
}

基本上,错误是QML中的parent.width,我们最好使用id来引用元素,而不是使用parent.width(使用elementId.width)

layoutChanged信号必须在模型中的某些内容发生更改(例如,它已被重新排序)时发出,而dataChanged信号必须在任何项更改数据但没有任何项用于指示添加了行时发出,在这种情况下,它必须使用beginInsertRows和endInsertRows方法

def __update(self):
    self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
    self.todos.append(random.randint(0, 99))
    self.endInsertRows()

另改为:

def rowCount(self, index=QModelIndex()):
    if index.isValid():
        return 0
    return len(self.todos)

相关问题 更多 >