QGIS3でpythonプラグインを作ってみた その2 QButtonと選択レイヤ取得について

# QGIS3でpythonプラグインを作る その2

## 目標
[前回](https://qiita.com/ozo360/items/399d3257bf4c24bf27e4)作った素のプラグインにボタンを追加して、クリックしたらアクティブレイヤの地物数を表示する機能を実装する。
押さえたいところは

- 選択レイヤをどうやって取得するか
- ボタンのシグナルをどう受け付けるのか

## 下準備
- 新規QGISプロジェクトを作成
- 新規シェープファイルレイヤを作成（ジオメトリタイプをポイントにしておきます）
- レイヤに地物を５つ追加して保存

## レイヤを取得する
Pythonコンソールからテストしてみます。

QgisInterfaceの[API](https://qgis.org/api/classQgisInterface.html)を参照してみるとactiveLayer()は残っていますね。

```
>>> act_layer = iface.activeLayer()
```
エラーなく通りました。
続いて地物数を取得してみます。

```
>>> act_layer.featureCount()
5
```

基本的すぎて変更がありませんね。
コードにするとこんな感じでしょうか

```python
act_layer = iface.activeLayer()
if act_layer is not None and act_layer.type() == QgsMapLayer.VectorLayer:
  cnt = act_layer.featureCount()
```


ちなみに私が頻繁に使っていたlegendInterface()が無くなってしまいました。:confounded:
これについては追々調べていきますがレイヤ一覧は以下で取得できるようです。

```
layers = list(QgsProject.instance().mapLayers().values())
```

## ボタンを追加する
QtCreatorをインストールしていないのでコードに記述します。

```
self.btn1 = QtWidgets.QPushButton("Button", self)
self.btn1.move(30, 50)
```
ボタンのクリックイベントへの接続はこれまで下のように記述していましたが

```
self.connect(self.btn1, QtCore.SIGNAL("clicked()"), self.buttonClicked)
```
PyQt5ではこんな感じに書けばよくなったんですね。

```
btn1.clicked.connect(self.buttonClicked)
```

## ソースに反映する
QActionとQMessageBoxはPtQt4.QtGuiからPyQt5.QtWidgetsに変更になってます。

```python:test_plugin.py
from qgis.core import *
from PyQt5.QtWidgets import QAction, QMessageBox
...
        # Create the dialog (after translation) and keep reference
        self.dlg = TestPluginDialog(self.iface.mainWindow())
        self.dlg.btn1.clicked.connect(self.buttonClicked)
...
    def buttonClicked(self):
        act_layer = self.iface.activeLayer()
        if act_layer is not None and act_layer.type() == QgsMapLayer.VectorLayer:
            cnt = act_layer.featureCount()
            QMessageBox.information(self.dlg,
                                    'count', str(cnt))
```

```python:test_plugin_dialog.py
    def __init__(self, parent=None):
        """Constructor."""
        super(TestPluginDialog, self).__init__(parent)
        self.setupUi(self)
        self.initUI()

    def initUI(self):
        self.btn1 = QtWidgets.QPushButton("Button", self)
        self.btn1.move(30, 50)
```

## 動作確認
QGISメニューの[プラグイン]-[プラグインの管理とインストール]を開く。
インストール済みタブから「Test Plugin」のチェックを外してから付け直す。
PluginReloaderプラグインを入れるとアイコンクリックでリロードできるのですが現時点では3.0に対応していないようです。

ツールバーからプラグインを立ち上げてからレイヤを選択してボタンをクリックすると「5」とメッセージボックスが表示されました。
![test_plugin_1.png](https://qiita-image-store.s3.amazonaws.com/0/240181/abe0cc41-dbf7-4fc0-07e4-14da3326bfcb.png)

***目的達成です。***

~~ただ、ダイアログがQGISウィンドウの裏側に隠れてしまいますね。
これは今後修正していきましょう。~~
ダイヤログのインスタンスを作っているところで引数に親を渡せば解決しましたので上記のソースを修正しました。
self.dlg = TestPluginDialog(***self.iface.mainWindow()***)


## まとめ
アクティブレイヤの取得は

```
iface.activeLayer()
```

シグナルとのコネクトは

```
オブジェクト名.シグナル名.connect(関数名)
```
## 追記
Plugin Reloaderの0.7.3(現時点の最新バージョン）を入れてみましたが特に問題なく動作するようです。
まだ「プラグインの管理とインストール」からはインストールできませんので、[こちら](https://plugins.qgis.org/plugins/plugin_reloader/)からダウンロードしてプラグインフォルダに配置すればインストール済みプラグインに表示されるようになります。

## 関連記事
[QGIS3でpythonプラグインを作ってみた その1 ベース作成](https://qiita.com/ozo360/items/399d3257bf4c24bf27e4)
[QGIS3でpythonプラグインを作ってみた その2 QButtonと選択レイヤ取得について](https://qiita.com/ozo360/items/1b8ea895be8ec6d1f5f7)
[QGIS3でpythonプラグインを作ってみた その3  QComboBoxとレイヤ取得について](https://qiita.com/ozo360/items/2c20e304b63b59f07a54)
[QGIS3でpythonプラグインを作ってみた その4  地物の追加編集削除について](https://qiita.com/ozo360/items/68733fea075c1a037367)
[QGIS3でpythonプラグインを作ってみた その5 地図をクリックして地物を選択する](https://qiita.com/ozo360/items/7ab448c57eac5140f2fe)

# 本記事のライセンス

<a rel="license" href="http://creativecommons.org/licenses/by/4.0/">![クリエイティブ・コモンズ・ライセンス](https://i.creativecommons.org/l/by/4.0/88x31.png)</a>
この記事は <a rel="license" href="http://creativecommons.org/licenses/by/4.0/">クリエイティブ・コモンズ 表示 4.0 国際 ライセンス</a>の下に提供されています。