【问题标题】:PyQt5 Dynamically add rectangles to QML gridPyQt5 将矩形动态添加到 QML 网格
【发布时间】:2017-07-28 12:15:23
【问题描述】:

我在 QML 中构建了一个由 Python 运行的矩形网格。 engine.load('main.qml')

Window {
    id: channels
    Grid {
        columns: 2
        spacing: 9
        Rectangle {
            color: "#333"
            width: 75
            height: 75
        }
        Rectangle {
            color: "#333"
            width: 75
            height: 75
        }
    }
}

但是,我想要超过 50 个矩形,所以我需要能够从 python 动态创建和更新它们。我该怎么做?

【问题讨论】:

  • 您考虑过使用中继器吗?它们相当容易使用,并且可能满足您的需求。

标签: python qt pyqt qml pyqt5


【解决方案1】:

为了提供从 python(或 C++)到 qml 的信息,我们可以阅读这个link。其中推荐使用QAbstractListModel,因为这会通知对qml的更改,除了动态添加之外,我们将使用Repeater

ma​​in.qml:

import QtQuick.Window 2.2
import QtQuick 2.0
import QtQuick.Controls 1.4

Window {
    visible: true
    id: channels

    Grid {
        columns: 3
        spacing: 9
        Repeater{
            model: myModel
            delegate: Rectangle{
                height: model.height
                width: model.height
                color: model.color
            }
        }
    }
}

.py:

class Data(object):
    def __init__(self, width=35, height=35, color=QColor("red")):
        self._width = width
        self._height = height
        self._color = color

    def width(self):
        return self._width

    def height(self):
        return self._height

    def color(self):
        return self._color

class Model(QAbstractListModel):

    WidthRole = Qt.UserRole + 1
    HeightRole = Qt.UserRole + 2
    ColorRole = Qt.UserRole + 3

    _roles = {WidthRole: b"width", HeightRole: b"height", ColorRole: b"color"}

    def __init__(self, parent=None):
        QAbstractListModel.__init__(self, parent)

        self._datas = []

    def addData(self, data):
        self.beginInsertRows(QModelIndex(), self.rowCount(), self.rowCount())
        self._datas.append(data)
        self.endInsertRows()

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

    def data(self, index, role=Qt.DisplayRole):
        try:
            data = self._datas[index.row()]
        except IndexError:
            return QVariant()

        if role == self.WidthRole:
            return data.width()

        if role == self.HeightRole:
            return data.height()

        if role == self.ColorRole:
            return data.color()

        return QVariant()

    def roleNames(self):
        return self._roles

为了进行测试,我们使用以下代码:

ma​​in.py

if __name__ == "__main__":
    import sys
    QCoreApplication.setAttribute(Qt.AA_EnableHighDpiScaling)
    app = QGuiApplication(sys.argv)
    engine = QQmlApplicationEngine()

    model = Model()
    model.addData(Data(44, 33, QColor("red")))
    model.addData(Data(23, 53, QColor("#333")))

    context = engine.rootContext()
    context.setContextProperty('myModel', model)

    engine.load(QUrl.fromLocalFile("main.qml"))

    if len(engine.rootObjects()) == 0:
        sys.exit(-1)

    qsrand(QTime.currentTime().msec())
    timer = QTimer(engine)
    timer.timeout.connect(lambda: model.addData(Data(20 + qrand() % 40, 
                                                     20 + qrand() % 40, 
                                                     QColor(qrand() % 255, qrand() % 255, qrand() % 255))))
    timer.start(1000)

    engine.quit.connect(app.quit)

    sys.exit(app.exec_())

您可以找到here 的完整示例。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-04-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多