2017-07-28 3 views
0

Ich habe ein Gitter aus Rechtecken in QML erstellt, das von Python ausgeführt wird. engine.load('main.qml')PyQt5 Dynamisch Rechtecke zum QML-Gitter hinzufügen

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

Allerdings würde Ich mag mehr als fünfzig Rechtecken haben, so dass ich muß in der Lage sein, dynamisch zu erstellen und sie von Python zu aktualisieren. Wie kann ich das machen?

+0

Haben Sie in Betracht gezogen, einen Repeater zu verwenden? Sie sind relativ einfach zu bedienen und passen sich Ihren Bedürfnissen an. – Yoann

Antwort

1

Um Informationen von Python (oder C++) zu qml zu liefern, können wir dies link lesen. In es empfiehlt sich QAbstractListModel zu verwenden, da dies die Änderungen an der qml benachrichtigt, zusätzlich dynamisch hinzugefügt werden wir Repeater verwenden.

main.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 

Um einen Test, den wir den folgenden Code verwenden zu machen:

main.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_()) 

Das vollständige Beispiel finden Sie here.

Verwandte Themen