PySide2/QML填充Gridview model/deleg并设置其动画

2024-05-19 23:25:58 发布

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

我是QML的新手,正在寻求以下几点的帮助

  • 如何根据TextField输入(如Regex)通过PySide2过滤Gridview模型中的QAbstractListModel数据(Title)。

  • 如何在鼠标悬停时设置Gridview代理的动画(如下图所示)。

enter image description here

这是测试代码

在qmlHoverView.py在

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

class inventoryModel(QtCore.QAbstractListModel):
    def __init__(self, entries, parent=None):
        super(inventoryModel, self).__init__(parent)
        self.titleRole = QtCore.Qt.UserRole + 1000
        self.thumbnailRole = QtCore.Qt.UserRole + 1001
        self._entries = entries

    def rowCount(self, parent=QtCore.QModelIndex()):
        if parent.isValid(): return 0
        return len(self._entries)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if 0 <= index.row() < self.rowCount() and index.isValid():
            item = self._entries[index.row()]
            if role == self.titleRole:
                return item["title"]
            elif role == self.thumbnailRole:
                return item["thumbnail"]

    def roleNames(self):
        roles = dict()
        roles[self.titleRole] = b"title"
        roles[self.thumbnailRole] = b"thumbnail"
        return roles

    def appendRow(self, n, t):
        self.beginInsertRows(QtCore.QModelIndex(), self.rowCount(), self.rowCount())
        self._entries.append(dict(name=n, type=t))
        self.endInsertRows()



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


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)
    entries = [
        {"title": "Zero", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/zero.png"},
        {"title": "One", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/one.png"},
        {"title": "Two", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/two.png"},
        {"title": "Three", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/three.png"},
        {"title": "Four", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/four.png"},
        {"title": "Five", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/five.png"},
        {"title": "Six", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/six.png"},
        {"title": "Seven", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/seven.png"},
        {"title": "Eight", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/eight.png"},
        {"title": "Nine", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/nine.png"},
    ]
    assetModel = inventoryModel(entries)
    foo = Foo()
    engine = QtQml.QQmlApplicationEngine()
    engine.rootContext().setContextProperty("foo", foo)
    engine.rootContext().setContextProperty("assetModel", assetModel)
    engine.load(QtCore.QUrl.fromLocalFile('E:/Tech/QML/projects/Test_005/main.qml'))
    if not engine.rootObjects():
        sys.exit(-1)
    engine.quit.connect(app.quit)
    sys.exit(app.exec_())

在主.qml在

^{pr2}$

在拇指代表.qml在

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

Component {
    Rectangle {
        width: 256
        height: 256
        color: 'green'

        Image {
            id: thumbImageId
            source: thumbnail
            asynchronous: true
        }

        Rectangle {
            width: parent.width
            height: 50
            anchors.bottom: parent.bottom
            color: 'grey'

            Label {
                anchors.verticalCenter: parent.verticalCenter
                anchors.left: parent.left
                anchors.leftMargin: 10
                text: title
                font.family: 'SF Pro Display'
                font.pixelSize: 22
                color: 'white'
            }
        }
    }
}

以上代码输出

enter image description here


Tags: testimportselfpngtitledefqmltech
1条回答
网友
1楼 · 发布于 2024-05-19 23:25:58

你问了不同的问题,这次我会回答所有问题,但下次你必须按照SO指南中的指示为每个问题创建一个帖子。在


在您的案例中,需要3个要素:

  • 将图像加载到GridView中:建议实现一个模型,在这种情况下,基于具有自定义角色的QStandardItemModel实现它,并与委托建立连接。

  • 过滤器:为此,您可以使用DelegateModel或QSortFilterProxyModel,在本例中使用第二个选项,因为它通过regex和角色实现筛选。

  • 悬停动画:第一件事是检测鼠标何时进入或退出项目,为此使用MouseArea触发进入和退出信号。然后我们使用一个行为来设置“y”属性更改时的动画。然后只需在信号触发时设置相应的最终值。我已经删除了“锚固件.底部: 父级.底部“因为定位点不允许修改属性。

另一方面,如果为代理创建qml,则不必使用组件,因为组件本身就是组件,另一方面,必须启用“clip”属性,以便项目的绘制不在其自身区域之外。在

考虑到上述情况,解决方案是:

├── images
│   └── android.png
├── main.py
└── qml
    ├── main.qml
    └── ThumbDelegate.qml

主.py

^{pr2}$

主.qml

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

ApplicationWindow {
    id: mainWindowId
    visible: true
    width: 1280
    height: 720
    title: qsTr("Image Hover Effect")

    Rectangle {
        anchors.fill: parent

        ColumnLayout {
            anchors.fill: parent
            spacing: 0
            TextField{
                id: filterTextFieldId
                Layout.fillWidth: true
                Layout.preferredHeight: 40
                font {
                    family: "SF Pro Display"
                    pixelSize: 22
                }
                color: "dodgerblue"
                onTextChanged: proxy_filter.setFilterRegExp(text)
            }

            Rectangle {
                Layout.fillWidth: true
                Layout.fillHeight: true
                color: "gold"
                GridView {
                    clip: true
                    id: thumbViewId
                    anchors.fill: parent
                    anchors.margins: 25

                    cellWidth: 260
                    cellHeight: 260

                    model: proxy_filter
                    delegate: ThumbDelegate {
                        source: model.thumbnail
                        title: model.title
                    }
                    focus: true
                }
            }
        }
    }
}

拇指代表.qml

^{4}$

更新:

既然您已经更新了您的问题,只需修改python代码,qml代码必须与我在回答的前一部分中建议的代码相同。在

*.py

import os
import sys

from PySide2 import QtCore, QtGui, QtWidgets, QtQml


class InventoryModel(QtCore.QAbstractListModel):
    TitleRole = QtCore.Qt.UserRole + 1000
    ThumbnailRole = QtCore.Qt.UserRole + 1001

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

    def rowCount(self, parent=QtCore.QModelIndex()):
        return 0 if parent.isValid() else len(self._entries)

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if 0 <= index.row() < self.rowCount() and index.isValid():
            item = self._entries[index.row()]
            if role == InventoryModel.TitleRole:
                return item["title"]
            elif role == InventoryModel.ThumbnailRole:
                return item["thumbnail"]

    def roleNames(self):
        roles = dict()
        roles[InventoryModel.TitleRole] = b"title"
        roles[InventoryModel.ThumbnailRole] = b"thumbnail"
        return roles

    def appendRow(self, n, t):
        self.beginInsertRows(QtCore.QModelIndex(), self.rowCount(), self.rowCount())
        self._entries.append(dict(title=n, thumbnail=t))
        self.endInsertRows()


if __name__ == "__main__":
    app = QtWidgets.QApplication(sys.argv)

    current_dir = os.path.dirname(os.path.realpath(__file__))

    entries = [
        {"title": "Zero", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/zero.png"},
        {"title": "One", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/one.png"},
        {"title": "Two", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/two.png"},
        {"title": "Three", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/three.png"},
        {"title": "Four", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/four.png"},
        {"title": "Five", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/five.png"},
        {"title": "Six", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/six.png"},
        {"title": "Seven", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/seven.png"},
        {"title": "Eight", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/eight.png"},
        {"title": "Nine", "thumbnail": "file:///E:/Tech/QML/projects/Test_005/nine.png"},
    ]

    assetModel = InventoryModel(entries)
    engine = QtQml.QQmlApplicationEngine()

    proxy_filter = QtCore.QSortFilterProxyModel()
    proxy_filter.setSourceModel(assetModel)
    proxy_filter.setFilterRole(InventoryModel.TitleRole)

    engine.rootContext().setContextProperty("proxy_filter", proxy_filter)
    engine.load(QtCore.QUrl.fromLocalFile('E:/Tech/QML/projects/Test_005/main.qml'))

    if not engine.rootObjects():
        sys.exit(-1)

    engine.quit.connect(app.quit)
    sys.exit(app.exec_())

相关问题 更多 >