PySide2代理模型不可更改的属性警告

问题描述 投票:0回答:1

我的带有PySide2的QML应用程序在运行时发出警告

QQmlExpression:表达式文件:/// E:/kingpin/qml/main.qml:68:17取决于非NOTIFYY属性:控制器:: project_proxy_list_model

使用onTextChanged事件更新代理模型,那么如何管理代理模型的通知信号?

app.py

import os
import sys
from PySide2 import QtCore, QtGui, QtWidgets, QtQml

class ElementListModel(QtGui.QStandardItemModel):
    TitleRole = QtCore.Qt.UserRole + 1000
    UrlRole = QtCore.Qt.UserRole + 1001

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setItemRoleNames(
            {ElementListModel.TitleRole: b"title", ElementListModel.UrlRole: b"url_image"}
        )

    @QtCore.Slot(str, QtCore.QUrl)
    def addItem(self, title, url):
        it = QtGui.QStandardItem()
        it.setData(title, ElementListModel.TitleRole)
        it.setData(url, ElementListModel.UrlRole)
        self.appendRow(it)


class controller(QtCore.QObject):
    def __init__(self):
        QtCore.QObject.__init__(self)

    @QtCore.Property(QtCore.QObject, constant=True)
    def project_proxy_list_model(self):
        return populate_project_list()


project_list_model = ElementListModel()
project_list_filter = QtCore.QSortFilterProxyModel()
project_list_filter.setSourceModel(project_list_model)
project_list_filter.setFilterRole(project_list_model.TitleRole)


def populate_project_list():
    entries = [
        ("one", "file:///E:/qml_model/media/images/one.png"),
        ("two", "file:///E:/qml_model/media/images/two.png"),
        ("three", "file:///E:/qml_model/media/images/three.png"),
        ("four", "file:///E:/qml_model/media/images/four.png"),
    ]
    for title, source in entries:
        project_list_model.addItem(title,source)
    return project_list_filter


controller = controller()
app = QtWidgets.QApplication(sys.argv)
current_dir = os.path.dirname(os.path.realpath(__file__))
engine = QtQml.QQmlApplicationEngine()
engine.addImportPath(current_dir)
engine.rootContext().setContextProperty("controller", controller)
filename = os.path.join(current_dir, "main.qml")
engine.load(QtCore.QUrl.fromLocalFile(filename))

if not engine.rootObjects():
    sys.exit(-1)
engine.quit.connect(app.quit)
sys.exit(app.exec_())

main.qml

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13

ApplicationWindow {
    id: root
    visible: true
    width: 1380
    height: 776
    title: qsTr("test")

    Rectangle{
        id: bufferRectId
        width: 1380
        height: 738
        color: "#22252a"
        anchors.top: parent.top

        TextField{
            id: filterTextFieldId
            font {
                family: "Lato"
                pixelSize: 22
            }
            color: "dodgerblue"
            anchors.top: parent.top
            anchors.left: parent.left
            anchors.topMargin: 38
            anchors.leftMargin: 850
            onTextChanged: controller.project_proxy_list_model.setFilterRegExp(text)
        }

        Rectangle {
            width: 1280
            height: 590
            color: "transparent"
            anchors{
                top: parent.top
                left: parent.left
                topMargin: 110
                leftMargin: 65
        }
            GridView {
                id: thumbViewId
                anchors.fill: parent
                anchors.margins: 20
                cellWidth: 200
                cellHeight: 320
                model: controller.project_proxy_list_model
                delegate: ThumbDelegate {
                    source: model.url_image
                    title: model.title
                }
                focus: true
                clip: true
            }
        }
    }
}

ThumbDelegate.qml

import QtQuick 2.13
import QtQuick.Controls 2.13
import QtQuick.Layouts 1.13
import QtGraphicalEffects 1.13


Rectangle {
    id: root
    width: 180
    height: 270
    color: 'transparent'
    clip: true

    property alias source: thumbImageId.source
    property alias title: label.text

    Image {
        id: thumbImageId
        asynchronous: true
        anchors.fill: parent
    }

    Rectangle {
        id: base
        width: parent.width
        height: 50
        color: '#484848'
        y: root.height
        Behavior on y { NumberAnimation {duration: 500} }
        Label {
            id: label
            anchors.verticalCenter: parent.verticalCenter
            anchors.left: parent.left
            anchors.leftMargin: 10
            font.family: 'SF Pro Display'
            font.pointSize: 22
            color: 'white'
        }

        FastBlur {
            anchors.fill: parent
            source: base
            radius: 64
            transparentBorder: false
    }
    }


    MouseArea{
        anchors.fill: parent
        hoverEnabled: true
        onEntered: base.y = root.height - base.height
        onExited: base.y = root.height
        onClicked: {
            swipeViewAreaId.currentIndex = 2
        }
    }
}
python python-3.x pyside2
1个回答
0
投票

正如我在评论中指出的那样,我没有收到警告消息,而且该代码是有效的,因此我可以假定它是一个旧错误。

但是OP指出了另一个问题:每次进行搜索时,都会向模型中添加新元素,这是由于每次对其进行过滤而导致的,必须获得“ project_proxy_list_model” qproperty,因此函数被调用,并且在OP的逻辑中装入了4个新项目,这是错误的,逻辑是返回模型而不使用其他方法。

import os
import sys
from PySide2 import QtCore, QtGui, QtWidgets, QtQml

class ElementListModel(QtGui.QStandardItemModel):
    TitleRole = QtCore.Qt.UserRole + 1000
    UrlRole = QtCore.Qt.UserRole + 1001

    def __init__(self, parent=None):
        super().__init__(parent)
        self.setItemRoleNames(
            {ElementListModel.TitleRole: b"title", ElementListModel.UrlRole: b"url_image"}
        )

    @QtCore.Slot(str, QtCore.QUrl)
    def addItem(self, title, url):
        it = QtGui.QStandardItem()
        it.setData(title, ElementListModel.TitleRole)
        it.setData(url, ElementListModel.UrlRole)
        self.appendRow(it)


class Controller(QtCore.QObject):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.project_list_model = ElementListModel()
        self.project_list_filter = QtCore.QSortFilterProxyModel()
        self.project_list_filter.setSourceModel(self.project_list_model)
        self.project_list_filter.setFilterRole(self.project_list_model.TitleRole)

        self.populate_project_list()

    @QtCore.Property(QtCore.QObject, constant=True)
    def project_proxy_list_model(self):
        return self.project_list_filter

    def populate_project_list(self):
        entries = [
            ("one", "file:///E:/qml_model/media/images/one.png"),
            ("two", "file:///E:/qml_model/media/images/two.png"),
            ("three", "file:///E:/qml_model/media/images/three.png"),
            ("four", "file:///E:/qml_model/media/images/four.png"),
        ]
        for title, source in entries:
            self.project_list_model.addItem(title, source)

if __name__ == '__main__':

    controller = Controller()
    app = QtWidgets.QApplication(sys.argv)
    current_dir = os.path.dirname(os.path.realpath(__file__))
    engine = QtQml.QQmlApplicationEngine()
    engine.addImportPath(current_dir)
    engine.rootContext().setContextProperty("controller", controller)
    filename = os.path.join(current_dir, "main.qml")
    engine.load(QtCore.QUrl.fromLocalFile(filename))

    if not engine.rootObjects():
        sys.exit(-1)
    engine.quit.connect(app.quit)
    sys.exit(app.exec_())
© www.soinside.com 2019 - 2024. All rights reserved.