我的带有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
}
}
}
正如我在评论中指出的那样,我没有收到警告消息,而且该代码是有效的,因此我可以假定它是一个旧错误。
但是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_())