[OSGeoJapan-discuss] QGISの属性データに初期値を設定する方法

Minoru Akagi akaginch @ gmail.com
2016年 7月 29日 (金) 00:27:38 PDT


喜多さん

> 難しいでしょうか?

ちょっと難しくなりますが、地物フォーム内の年度、地区番号フィールドの値が変更されるたびにID番号フィールドの値を自動設定するという方法であればPython初期化コードでもできます(よりよい方法があるかもしれませんが)。サンプルスクリプト[1]をGistにアップロードしましたが、実際に使用するのはPythonにある程度慣れてからの方がいいかと思います。

> 自分でも勉強したいのですが、
> QGISのPythonコードのわかりやすい事例などがあるWebページなどはありますか?

Pythonの学習については公式の日本語チュートリアル[2]・リファレンス[3]等が整備されていますのでそれらを用いれば十分可能かと思います。QGISの中でPythonを使うにはQGISの基礎となっているQtライブラリやQGISのライブラリについて知る必要があります。まずはPyQGIS
Developer Cookbook[4]を一通り読んでみるのがいいかもしません。サンプルコードも結構含まれていますよ。

[1] https://gist.github.com/minorua/86c22f5298b00c6c7a61e9b2e9b7f46b
[2] http://docs.python.jp/2/tutorial/index.html
[3] http://docs.python.jp/2/reference/index.html
[4] http://docs.qgis.org/2.8/ja/docs/pyqgis_developer_cookbook/index.html

赤木 実

2016年7月28日 21:53 喜多耕一 <kou35tochas @ gmail.com>:
> 赤木さん
>
> 喜多です。
> 詳しい返信有り難うございます。
> 確かに、教えていただいたコードで、新規追加時のみ初期値を設定することができました。
>
> もしよろしければ、もう少しご教授頂きたいのですが、
> 今回はフォームを開くときに初期値を設定できましたが、
> フォームを閉じるときに値を設定することはできるのでしょうか?
> これができれば、初めに質問した2つ目の質問で、
> 「ID番号」フィールドを非表示にして、
> 「年度」フィールドと「地区番号」フィールドに値を入力し、
> フォームを閉じるときに「ID番号」がNULLなら、
> 年度+地区番号をID番号フィールドに入れるということができる気がします。
> 難しいでしょうか?
>
>
> Pythonのコードがわからなく、質問ばかりで申し訳ありません。
>
> 自分でも勉強したいのですが、
> QGISのPythonコードのわかりやすい事例などがあるWebページなどはありますか?
>
> おいそがしいところ申し訳ありません。
> よろしくお願いします。
>
>
> 北海道 喜多耕一
>
>
>
>
>
>
> 2016年7月28日 18:11 Minoru Akagi <akaginch @ gmail.com>:
>
>> QGIS
>> 2.16では属性フォームのクラス(QgsAttributeForm)にフォームのモードを得るメソッド(mode)が追加されており[1]、追加か編集かを判別できるはずなのですが試したところ期待する値が得られません。本体の修正が必要なのだろうと思います。
>> 当座の手法として次のコードはいかがでしょうか。地物の属性値が全てNULLの場合のみ初期値を設定しています。スタンドアロン版のQGIS
>> 2.16 (64ビット)で動作確認しました。
>>
>> -----------------------------------------------------------------
>> # -*- coding: utf-8 -*-
>> from PyQt4.QtGui import QLineEdit
>> from qgis.gui import QgsAttributeForm
>>
>> def my_form_open(dialog, layer, feature):
>>     # if dialog.mode() == QgsAttributeForm.AddFeatureMode:
>>     attrset = set(feature.attributes())
>>     attrset.discard(None)
>>     if not attrset:
>>         dialog.findChild(QLineEdit, u"type").setText(u"3")
>>         dialog.findChild(QLineEdit, u"name").setText(u"カボチャ")
>> -----------------------------------------------------------------
>>
>> [1]
>> https://qgis.org/api/classQgsAttributeForm.html#ad219d225b812c355d303dc21e6c253f3
>>
>>
>> 赤木 実
>>
>>
>>
>> 2016年7月28日 16:30 喜多耕一 <kou35tochas @ gmail.com>:
>> > 赤木さん
>> >
>> > 喜多です。
>> > ありがとうございます。
>> >
>> > 地物編集時に上書きされてしまうなら、ちょっとの使えません。
>> >
>> > 地物追加時のみに有効になるコードは、あるんですか?
>> >
>> > もし、可能であれば教えていただけると非常に助かります。
>> > よろしくお願いします。
>> >
>> > 北海道 喜多耕一
>> >
>> >
>> > 2016/07/28 14:28 "Minoru Akagi" <akaginch @ gmail.com>:
>> >
>> >> 喜多さん
>> >>
>> >> さきほどのコードはQGIS 2.14で動作確認したもので使用するQGISのバージョンによって動作しない場合があります。
>> >> 次はスタンドアロン版のQGIS 2.16 (64ビット)で動作確認したものです。
>> >>
>> >>
>> >>
>> >> --------------------------------------------------------------------------------
>> >> # -*- coding: utf-8 -*-
>> >> from PyQt4.QtGui import QLineEdit
>> >>
>> >> def my_form_open(dialog, layer, feature):
>> >>     dialog.findChild(QLineEdit, u"type").setText(u"3")
>> >>     dialog.findChild(QLineEdit, u"name").setText(u"カボチャ")
>> >>
>> >>
>> >> --------------------------------------------------------------------------------
>> >>
>> >> # また既存の地物のフォームを開く場合に値がデフォルト値で上書きされてしまうのでその辺り改良の余地があります。
>> >> # 地物追加の場合にのみデフォルト値を設定するようにするべきですがここではコードをお示しできません。あしからず
>> >>
>> >> 赤木 実
>> >>
>> >>
>> >> 2016年7月28日 12:04 喜多耕一 <kou35tochas @ gmail.com>:
>> >> > 赤木さん
>> >> >
>> >> > 喜多です。
>> >> > ありがとうございます。
>> >> >
>> >> > いま、出先なので帰ったらやってみます。
>> >> >
>> >> > データの連結は、やっぱりフィールド計算機などで行わないとダメですか。
>> >> > データ追加時にできると、捗るんですけどねえ。
>> >> >
>> >> > 北海道 喜多耕一
>> >> >
>> >> >
>> >> > 2016/07/28 11:23 "Minoru Akagi" <akaginch @ gmail.com>:
>> >> >
>> >> >> 喜多さん
>> >> >>
>> >> >> 少し長い回答になりますがご容赦下さい。
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> 地物を追加した時に表示される属性入力フォームにデフォルト値を設定するには「Python初期化関数」を使います。デフォルト値の設定ぐらい簡単にできればいいのですが、今のところはPythonコードを書く必要があります。Pythonの知識がある方が望ましいですが難しいコードではないので下記のサンプルを見ながらコードを書いてみて下さい。
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> まずベクタレイヤのプロパティダイアログを開き、フィールドオプションの「Python初期化関数」コンボボックスで"このダイアログでコードを入力"を選択します。フィールド一覧の下にコードが現れますので内容を編集します。
>> >> >>
>> >> >> 初期状態では次のようなコードになっています。
>> >> >>
>> >> >> def my_form_open(dialog, layer, feature):
>> >> >>     geom = feature.geometry()
>> >> >>     control = dialog.findChild(QWidget, "MyLineEdit")
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> 簡単に説明すると、ここではmy_form_openという関数が定義されており、geomという名前に地物のジオメトリオブジェクト、controlという名前にMyLineEditというフィールド名のウィジェット(QLineEditクラス)のオブジェクトを代入するコードになっています。
>> >> 訂正: フィールド名→オブジェクト名
>> >> >> 関数の引数は順にQgsAttributeForm, QgsVectorLayer,
>> >> >> QgsFeatureの各クラスのオブジェクトとなります。
>> >> >>
>> >> >> 初期値を設定するにはコードを次のように書き換えます。
>> >> >>
>> >> >> def my_form_open(dialog, layer, feature):
>> >> >>     dialog.findChild(QWidget, u"type").setText(u"3")
>> >> >>     dialog.findChild(QWidget, u"name").setText(u"カボチャ")
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> ここでtypeとnameはフィールド名、3とカボチャは各フィールドに対するデフォルト値です。インデントはタブかスペースのどちらかに統一して下さい。初期コードのインデントにはタブが使われています。
>> >> >>
>> >> >>
>> >> >>
>> >> >>
>> >> >> そして、ダイアログ上部から2行目の「関数名」のテキストボックスに初期化関数の名前(ここではmy_form_open)を入力してダイアログのOKボタンを押せば初期値設定が有効となります。この設定はプロジェクトファイルに保存されますので配布されたプロジェクトを使用する場合にも初期値設定は有効です。
>> >> >>
>> >> >> 以上が先の質問への回答となります。あとの質問については仮想フィールドを使うかフィールド計算機を使うことになるでしょうか?
>> >> >>
>> >> >>
>> >> >> 赤木 実
>> >> >>
>> >> >>
>> >> >> 2016年7月27日 20:12 喜多耕一 <kou35tochas @ gmail.com>:
>> >> >> > 垂水さん
>> >> >> >
>> >> >> > 北海道の喜多です。
>> >> >> >
>> >> >> > ありがとうございます。
>> >> >> > 内容が専門的すぎて(汗)、ちょっと私にはわかりませんが、
>> >> >> > できればQGISのデフォルトな機能でできればいいなと思っています。
>> >> >> > むずかしいですかね・・・。
>> >> >> >
>> >> >> > 何故かと言うと、職場のいろんな事務所のいろんな人に、そういう設定を行った
>> >> >> > プロジェクトファイルを配布して、みんなで共通の機能を簡単に使いたいと考えています。
>> >> >> > 殆どの方は初心者以前の方なので、できるだけ簡単に、データ作成ができればと思っています。
>> >> >> >
>> >> >> > なにかいい方法があれば、よろしくお願いします。
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> > 北海道 喜多耕一
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> >
>> >> >> > 2016年7月27日 18:27 垂水 秀雄 <tarumi @ kk-kernel.co.jp>:
>> >> >> >
>> >> >> >> カーネル垂水です
>> >> >> >>
>> >> >> >> QGISで地物を追加時に、属性データに特定の値を初期値として設定したいのですが、できますでしょうか?
>> >> >> >>
>> >> >> >> レイヤプロパティのフィールドで、Python初期化関数などで、コードを書いてできそうな気もしますが、全くやり方はわかりません。
>> >> >> >>
>> >> >> >>
>> >> >> >> 試していませんが、
>> >> >> >>
>> >> >> >> qgsvectorlayer.sipを見ると以下のシグナルがあるので
>> >> >> >>
>> >> >> >> void featureAdded( QgsFeatureId fid );
>> >> >> >>
>> >> >> >> これをconnectして、呼ばれたら
>> >> >> >>
>> >> >> >> QgsFeatureIdをキーに追加されたQgsFeatureを取得して、
>> >> >> >> QgsFeatureのsetAttributeで値をセットすればPythonのプラグインでできそうな気がします。
>> >> >> >>
>> >> >> >>
>> >> >> >> On 2016/07/27 17:48, 喜多耕一 wrote:
>> >> >> >>
>> >> >> >> 皆様
>> >> >> >>
>> >> >> >> いつもお世話になっています。
>> >> >> >> 北海道の喜多です。
>> >> >> >>
>> >> >> >> QGISで地物を追加時に、属性データに特定の値を初期値として設定したいのですが、できますでしょうか?
>> >> >> >>
>> >> >> >> レイヤプロパティのフィールドで、Python初期化関数などで、コードを書いてできそうな気もしますが、全くやり方はわかりません。
>> >> >> >>
>> >> >> >> あと、入力した属性データの値を使って、データを入力したいというのもあります。
>> >> >> >> 例えば、年度と地区番号を入力したら、年度+地区番号のIDコードを自動入力したいです。
>> >> >> >>
>> >> >> >> わかる方がいらっしゃいましたら、教えて下さい。
>> >> >> >> よろしくお願いします。
>> >> >> >>
>> >> >> >> 北海道 喜多耕一
>
>


OSGeoJapan-discuss メーリングリストの案内