从QML获取委托objectName到python pyqt5

时间:2019-05-07 13:48:59

标签: python pyqt qml pyqt5

我有一个ListView,在其中我有委托Rectangle,在Rectangle中我有Image对象。所以我想将Image objectName放入python PyQt5文件中,并为每个图像设置不同的源!

ListView { 
    model: 12 /*that mean that i have 12 images!*/
    delegate: Rectangle {
        Image {
            objectName: "img"
            source: "file:///C:/LocalDir/Project/img/11.png"
        }
    }
}



def set_property():
    self.context = QQuickWidget()
    self.context.setSource(QUrl().fromLocalFile("QML-code.qml"))
    self.rootObj = context.rootObject()
    img = self.rootObj.findChild("img") 

    if img:
        img.setProperty("source", path)
    # and so on...but i don't know how to get img delegate

1 个答案:

答案 0 :(得分:0)

您走错了路,可以在不通知GUI的情况下删除和创建代表,因此单独访问它们不是正确的选择。视图中的策略是通过模型传递信息,在这种情况下,由于要在python中获取图像路径的信息,建议基于QAbstractListModel创建模型:

main.py

from PyQt5 import QtCore, QtGui, QtWidgets, QtQuickWidgets


class ImageModel(QtCore.QAbstractListModel):

    PathRole = QtCore.Qt.UserRole + 1

    def __init__(self, parent=None):
        super(ImageModel, self).__init__(parent)

        self._paths = []

    def addPath(self, path):
        self.beginInsertRows(
            QtCore.QModelIndex(), self.rowCount(), self.rowCount()
        )
        self._paths.append(path)
        self.endInsertRows()

    def rowCount(self, parent=QtCore.QModelIndex()):
        return len(self._paths)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if role == ImageModel.PathRole and 0 <= index.row() < self.rowCount():
            return self._paths[index.row()]
        return QtCore.QVariant()

    def roleNames(self):
        return {ImageModel.PathRole: b"path"}


if __name__ == "__main__":
    import os
    import sys

    app = QtWidgets.QApplication(sys.argv)
    model = ImageModel()
    w = QtQuickWidgets.QQuickWidget(
        resizeMode=QtQuickWidgets.QQuickWidget.SizeViewToRootObject
    )
    w.rootContext().setContextProperty("pathmodel", model)
    filename = os.path.join(
        os.path.dirname(os.path.realpath(__file__)), "main.qml"
    )
    w.setSource(QtCore.QUrl.fromLocalFile(filename))

    pictures_path = QtCore.QStandardPaths.writableLocation(
        QtCore.QStandardPaths.PicturesLocation
    )
    formats = (
        "*{}".format(fmt.data().decode())
        for fmt in QtGui.QImageReader.supportedImageFormats()
    )
    for finfo in QtCore.QDir(pictures_path).entryInfoList(formats):
        model.addPath(finfo.absoluteFilePath())
    w.show()
    sys.exit(app.exec_())

main.qml

import QtQuick 2.12

Rectangle{
    width: 640
    height: 480

    ListView { 
        anchors.fill: parent
        model: pathmodel
        delegate: Rectangle {
            width: 100
            height: 100
            Image {
                anchors.fill: parent
                source: Qt.resolvedUrl(model.path)
            }
        }
    }
}

或更简单地使用QStandardItemModel:

from PyQt5 import QtCore, QtGui, QtWidgets, QtQuickWidgets

PathRole = QtCore.Qt.UserRole + 1

if __name__ == "__main__":
    import os
    import sys

    app = QtWidgets.QApplication(sys.argv)
    model = QtGui.QStandardItemModel()
    model.setItemRoleNames({PathRole: b"path"})
    w = QtQuickWidgets.QQuickWidget(
        resizeMode=QtQuickWidgets.QQuickWidget.SizeViewToRootObject
    )
    w.rootContext().setContextProperty("pathmodel", model)
    filename = os.path.join(
        os.path.dirname(os.path.realpath(__file__)), "main.qml"
    )
    w.setSource(QtCore.QUrl.fromLocalFile(filename))

    pictures_path = QtCore.QStandardPaths.writableLocation(
        QtCore.QStandardPaths.PicturesLocation
    )
    formats = (
        "*{}".format(fmt.data().decode())
        for fmt in QtGui.QImageReader.supportedImageFormats()
    )
    for finfo in QtCore.QDir(pictures_path).entryInfoList(formats):
        it = QtGui.QStandardItem()
        it.setData(finfo.absoluteFilePath(), PathRole)
        model.appendRow(it)
    w.show()
    sys.exit(app.exec_())