【问题标题】:Get delegate objectName from qml to python从 qml 获取委托 objectName 到 python
【发布时间】:2019-09-25 04:58:16
【问题描述】:

我有一个 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

【问题讨论】:

    标签: python pyqt qml pyqt5


    【解决方案1】:

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

    ma​​in.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_())
    

    ma​​in.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_())
    

    【讨论】:

    • 谢谢@eyllanesc,但如果我不使用 QAbstractListModel,你能提供一些答案吗?
    • @dimatronciu 如果您检查我的代码,有 2 个答案:1)使用 QAbstractListModel 和 2)使用 QStandardItemModel
    猜你喜欢
    • 1970-01-01
    • 2017-01-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-29
    • 1970-01-01
    • 1970-01-01
    • 2012-02-20
    相关资源
    最近更新 更多