QGIS API: 属性の取得

ベクタデータの属性を取得するのは結構ややこしいです。

以下の例は、全データの属性データを取得してQTableWidgetに追加する例です。
QTableWidgetはメンバとしてattributeTableとして宣言しています。

  # provider = layer.getDataProvider()  旧仕様
  # イマドキの場合
  provider = layer.dataProvider()
  
  fields = provider.fields()
  self.attributeTable.setColumnCount(len(fields)+1)
  self.attributeTable.setHorizontalHeaderItem(0, QTableWidgetItem("id"))
  
  
  for (i, field) in fields.iteritems():
  # v2.x系の場合
  for field in fields.toList():
      self.attributeTable.setHorizontalHeaderItem(i+1, QTableWidgetItem(field.name()))

  # allAttrs = provider.allAttributesList() ← v0.9
  allAttrs = provider.attributeIndexes()

  # 以下はv1.xの場合
  # v2.xの場合はQGIS API 属性値をテーブルに表示するときの対策を参照してください
  provider.select(allAttrs, QgsRect(), False)
  feat = QgsFeature()

  self.attributeTable.setRowCount(layer.featureCount())
  n = 0
  # while provider.getNextFeature(feat): ← v0.9
  while provider.nextFeature(feat):
    attrMap = feat.attributeMap()

    for (i, attr) in attrMap.iteritems():
      # self.attributeTable.setItem(n, 0, QTableWidgetItem(str(feat.featureId()))) ← v0.9
      self.attributeTable.setItem(n, 0, QTableWidgetItem(str(feat.id())))
      strA = attr.toString()
      self.attributeTable.setItem(n, i+1, QTableWidgetItem(strA))
    n += 1

まず、ベクタレイヤーからQgsVectorDataProvider型オブジェクトを取得し、
フィールド数を調べてテーブルウィジェットの列数を決定し、ヘッダ名をセットしています。
先頭には”id”というフィールドを別に追加しています。
これが無いと正しくセットされないようです。

次に、全属性データを対象として、全データを選択状態にしています。
provider.select()の第3引数をFalseにすると、
図形データは検索対象にしません。

次に、全データ数を調べてテーブルウィジェットの行数を設定後、
データを走査して各データから属性を取得し、文字列→QTableWidgetItemに変換後
テーブルのセルにセットしています。

なお、この例では順番に属性フィールドをテーブルに追加していますが、
属性フィールドの間にgeometry_columnが挟まっている場合、表示は問題ありませんが、
編集するときはこのままではうまくいきません。
詳しくはQGIS API 属性値をテーブルに表示するときの対策を参照してください。


実行結果

実行結果

アーカイブ