2017-07-28 55 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 
     } 
    } 
} 

不過,我想有五十多個矩形,所以我需要能夠動態地創建和蟒蛇更新它們。我怎樣才能做到這一點?

+0

你有沒有考慮過使用Repeater?它們相當容易使用,並且可能適合您的需求。 – 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