2017-07-28 28 views
0

私はPythonから実行されるQMLで長方形のグリッドを構築しました。 engine.load('main.qml')PyQt5 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からそれらを更新できるようにする必要があります。どうやってやるの?

+0

リピーターを使用したことはありますか?彼らはかなり使いやすく、あなたのニーズに合うかもしれません。 – Yoann

答えて

1

python(またはC++)からqmlに情報を提供する場合は、linkを読むことができます。 QAbstractListModelを使用することをお勧めします。これはqmlへの変更を通知し、さらに動的に追加するためにRepeaterを使用します。

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 

我々は、次のコードを使用してテストをするために:

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

完全な例はhereです。

関連する問題