dockwidget = QDockWidget() dockwidget.setTitleBarWidget(QWidget())
消去前
消去後
dockwidget = QDockWidget() dockwidget.setTitleBarWidget(QWidget())
消去前
消去後
ローカル変数に格納したWidgeのインスタンスはスコープを外れるとなくなる
これはQGISのプラグイン開発時にふと違和感を感じたPythonの仕様?
関数initGuiの中でQDockWidgetのインスタンスをローカル変数「mainpanel」にセットして
画面に追加すると正しく表示されない
しかしクラスのメンバー変数にセットすると正しく表示される
本来はaddDockWidgetした時点でインスタンスは他で保たれるであろうから表示されないことはない気がするが・・・
正しく表示されない例
def initGui(self): mainpanel = MainPanelDockWidget() self.iface.addDockWidget(Qt.RightDockWidgetArea, mainpanel) self.dockwidget.show()
正しく表示される例
def initGui(self): self.dockwidget = MainPanelDockWidget() self.iface.addDockWidget(Qt.RightDockWidgetArea, self.dockwidget) self.dockwidget.show()
QDocWidget上にSplitterを配置
QWidgetを左右に配置
2つのQWidgetを選択して「ツールバー」の「水平にスプリッタの中に並べる」を選択
以上で2つのQWidgetがSplitterに配置される
Splitterが親のQDockWidget一杯に表示されるようにdockWidgetContentsを選択して「ツールバー」の「水平に並べる」ボタンをクリック
以上
QDockWidgetにQWidgetが追加されないため、uiファイルを直接編集してQWidgetを追加。
編集前
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>DockWidget</class> <widget class="QDockWidget" name="DockWidget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> </property> <property name="allowedAreas"> <set>Qt::AllDockWidgetAreas</set> </property> <property name="windowTitle"> <string>DockWidget</string> </property> </widget> <resources/> <connections/> </ui>
編集後
<?xml version="1.0" encoding="UTF-8"?> <ui version="4.0"> <class>DockWidget</class> <widget class="QDockWidget" name="DockWidget"> <property name="geometry"> <rect> <x>0</x> <y>0</y> <width>400</width> <height>300</height> </rect> </property> <property name="allowedAreas"> <set>Qt::AllDockWidgetAreas</set> </property> <property name="windowTitle"> <string>DockWidget</string> </property> <widget class="QWidget" name="dockWidgetContents"> </widget> </widget> <resources/> <connections/> </ui>
Qtデザイナで再度uiファイルを開くと正しくQWidgetが追加されている
Qtデザイナを起動してメニュー「ファイル」-「ファイルを新規作成」を選択し以下に従ってデザイナ画面を起動
本来DockWidget配下にQWidgetが表示され、その上に部品を配置することができる。
しかしDockWidget配下にQWidgetがどうしても追加されない。
OS | Windows10 64bit |
QGIS | QGIS3.4.4(OSGEO4W 32bit) |
Eclipse | 2018-12 64bit |
Java | Oracle JRE 10 |
PyDev | 7.1.0.201902031515 |
OSGEO4W版のインストーラーを起動しC:\OSGEO4Wにインストール
QGISを起動
以下よりEclipseをダウンロード
https://www.eclipse.org/downloads/download.php?file=/oomph/epp/2018-12/R/eclipse-inst-win64.exe
ダウンロードしたeclipse-inst-win64を実行
起動すると以下のメッセージ表示
Eclipseのサイトより「Oracle JRE 10」をダウンロード
https://download.eclipse.org/oomph/jre/index-handler.php?vm=1_1_7_0_64_0&pn=Eclipse%20Installer&pu=http://wiki.eclipse.org/Eclipse_Installer&pi=http://download.eclipse.org/oomph/jre/128×128.png
ダウンロードした「jre-10.0.2_windows-x64_bin」を実行
インストールボタンをクリック
再度「eclipse-inst-win64」を実行
eclipse インストーラーが起動されたら「eclipse IDE for java developers」を選択
証明書の確認
Eclipseを起動してHelpメニューの「Install New Software」
「Work With」の「Add」ボタンをクリック
NameにPyDev、Locationに「http://pydev.org/updates」を指定しAddボタンをクリック
PyDevをチェックしてNEXTボタンをクリック
Detaileボタンを押してPydevのインストール先を確認してから「Install Anyway」を実行
Eclipseを起動して「Window」→「Preferences」を選択
左のTreeでPyDev-Interpreters-Python Interpreterを選択
QGISが使用するPython.exeを指定するためにQGISを起動してPYTHONHOMEの値を確認
「Browse for pythonpypy exe」ボタンを押してNAMEには任意の名称(ここではpython37)、値には先ほど調べたPython.exeのフルパスを指定。
Librariesは自動でいくつかの参照先が指定されるが手動で不足分を指定
先ほどインストール先を確認したPyDevも指定
Packagesには警告らしき表示があるが無視
Forced Builtinsのタブを表示して「New」ボタンを押してqgisとPyQt5をそれぞれ登録
Environmentoタブを表示して以下の環境変数を設定
「Apply」ボタンを押して「Apply and Close」ボタンを押して設定を反映
設定内容が即反映されないので「Apply」ボタンを押したら暫く待つこと。
※設定が終了する前に画面を閉じると正しく設定が終了しない
メニュ「Run」-「External Tools Configurations」を指定して外部TOOLとしてQGISを設定
プロジェクトを作成
Eclipseの「New」メニューから-「Project」-「PyDev Project」を選択
以下に従ってプロジェクトの内容を設定しFinishボタンを押す
確認のためにQGISのPlugin Builder3でプラグインを作成して「C:\Users\ユーザー名\AppData\Roaming\QGIS\QGIS3\profiles\default\python\plugins\」に配置
init.pyに以下を記述
import os,sys sys.path.append("C:\\Users\\kernel\\.p2\\pool\\plugins\\org.python.pydev.core_7.1.0.201902031515\\pysrc") import pydevd pydevd.settrace()
sys.pathに追加しているのはPyDev
この記述はEclipseを使用しないときはエラーとなる
これを記述するとclassFactory関数でブレークする
ここからの操作は若干確信がないが、とりあえず正しく動作したので良しとして説明
プラグイン「Remote Debug」と「Plugin Reloader」を有効にするためにプラグインの設定で実験的プラグインも表示する
デバッグボタンを押す
「start pydev Server」ボタンをクリック
「外部TOOL QGISを起動」
Xcodeのバージョンが10.1になったのであらためてiOSアプリの作成からAdHocでインストールするまでをおさらい!
最初にXcodeでSingle View Appを作成
最近はXcodeが勝手に証明書関連を設定してくれるが、なぜかうまくいかなかったので手動で設定する
Apple DeveloperにログインしてProductionの証明書を確認
証明書はXcodeのPreferencesをクリックしてして表示される画面の左下+ボタンで作成可能
App IDを作成
DeviceにAdHocでインストールしてするデバイスを追加
AdHocで使用するProvisioning Profilesを作成
以上でçの作成は終了
XcodeのPreferencesからAppleIDの画面を表示して「Download Manual Profiles」ボタンを押してAdHoc用のProvisioning Profilesをダウンロード(していると思う・・・)
xcodeを開いてSigningのチェックを外しProvisioning Profilesに作成したAdHocを指定する
これからAdHoc用のコンパイルを開始するが、その前にProductメニューのDestinationをGeneric iOS Deviceに設定。この設定をしないとProductメニューのArciveが有効にならない。
ProductメニューのArciveを実行
「Distribute App」ボタンをクリック
AdHocを選択
optionを指定
証明書とProvisioning Profilesを指定
Exportボタンを押してipaファイルの出力先を指定。
iPhoneにインストール
iTunesを起動してiPhoneを接続
iPaをiTunesの左パネルの自分のデバイス上にドラッグしてインストール
ちなみにiTunes 12.7.3.64では正しくインストールできたが、12.8.2.3ではドラッグできなかった?
投影情報を持っていないShapeファイルを読み込んで「QgsVectorLayer」を作成した後に投影情報を設定する
訂正
layer = QgsVectorLayer(Shapeファイルのフルパス, レイヤ名, "ogr") crs = QgsCoordinateReferenceSystem.fromEpsgId(2451) layer.setCrs(crs) × crs = layer.crs() × crs.createFromString('EPSG:2451')
CRSが未設定のレイヤを表示するとQgsMessageBarが表示される
「新しいレイヤの投影座標系」を「プロジェクトのCRSを使用」に設定してもこれは避けられない
QgisAppクラスのvalidateCrsを確認すると
void QgisApp::validateCrs( QgsCoordinateReferenceSystem &srs ) { static QString sAuthId = QString(); QgsSettings mySettings; QString myDefaultProjectionOption = mySettings.value( QStringLiteral( "Projections/defaultBehavior" ), "prompt" ).toString(); if ( myDefaultProjectionOption == QLatin1String( "prompt" ) ) { 省略 } else if ( myDefaultProjectionOption == QLatin1String( "useProject" ) ) { // XXX TODO: Change project to store selected CS as 'projectCRS' not 'selectedWkt' sAuthId = QgsProject::instance()->crs().authid(); srs.createFromOgcWmsCrs( sAuthId ); QgsDebugMsg( "Layer srs set from project: " + sAuthId ); messageBar()->pushMessage( tr( "CRS was undefined" ), tr( "defaulting to project CRS %1 - %2" ).arg( sAuthId, srs.description() ), Qgis::Warning, messageTimeout() ); } else ///Projections/defaultBehavior==useGlobal { 省略 } }
「プロジェクトのCRSを使用」に設定するとかならず「messageBar()->pushMessage」が呼ばれてしまう。
フラグなどで対応することはできそうもない。
QgsMessageBarクラス参考
とりあえず以下のコードで表示される時間を1秒に設定
QSettings().setValue( "qgis/messageTimeout", 1 )
ポリゴンのシンボルQgsFillSymbolの設定(構築)はQgsFillSymbolクラスのメソッドcreateSimpleにスタイルを渡して設定する。
内部の色、外周の色を設定する時は
QgsFillSymbol.createSimple({'color': '0,0,0,0','outline_color': '255,0,0,255'})
更に内部のパターンを設定する時は
QgsFillSymbol.createSimple({'color': '0,0,0,0','outline_color': '255,0,0,255','style' : 'diagonal_x'})
設定のキーはQgsSymbolLayer::createを参考
QgsSymbolLayer *QgsSimpleFillSymbolLayer::create( const QgsStringMap &props ) { QColor color = DEFAULT_SIMPLEFILL_COLOR; Qt::BrushStyle style = DEFAULT_SIMPLEFILL_STYLE; QColor strokeColor = DEFAULT_SIMPLEFILL_BORDERCOLOR; Qt::PenStyle strokeStyle = DEFAULT_SIMPLEFILL_BORDERSTYLE; double strokeWidth = DEFAULT_SIMPLEFILL_BORDERWIDTH; Qt::PenJoinStyle penJoinStyle = DEFAULT_SIMPLEFILL_JOINSTYLE; QPointF offset; if ( props.contains( QStringLiteral( "color" ) ) ) color = QgsSymbolLayerUtils::decodeColor( props[QStringLiteral( "color" )] ); if ( props.contains( QStringLiteral( "style" ) ) ) style = QgsSymbolLayerUtils::decodeBrushStyle( props[QStringLiteral( "style" )] ); if ( props.contains( QStringLiteral( "color_border" ) ) ) { //pre 2.5 projects used "color_border" strokeColor = QgsSymbolLayerUtils::decodeColor( props[QStringLiteral( "color_border" )] ); } else if ( props.contains( QStringLiteral( "outline_color" ) ) ) { strokeColor = QgsSymbolLayerUtils::decodeColor( props[QStringLiteral( "outline_color" )] ); } else if ( props.contains( QStringLiteral( "line_color" ) ) ) { strokeColor = QgsSymbolLayerUtils::decodeColor( props[QStringLiteral( "line_color" )] ); } if ( props.contains( QStringLiteral( "style_border" ) ) ) { //pre 2.5 projects used "style_border" strokeStyle = QgsSymbolLayerUtils::decodePenStyle( props[QStringLiteral( "style_border" )] ); } else if ( props.contains( QStringLiteral( "outline_style" ) ) ) { strokeStyle = QgsSymbolLayerUtils::decodePenStyle( props[QStringLiteral( "outline_style" )] ); } else if ( props.contains( QStringLiteral( "line_style" ) ) ) { strokeStyle = QgsSymbolLayerUtils::decodePenStyle( props[QStringLiteral( "line_style" )] ); } if ( props.contains( QStringLiteral( "width_border" ) ) ) { //pre 2.5 projects used "width_border" strokeWidth = props[QStringLiteral( "width_border" )].toDouble(); } else if ( props.contains( QStringLiteral( "outline_width" ) ) ) { strokeWidth = props[QStringLiteral( "outline_width" )].toDouble(); } else if ( props.contains( QStringLiteral( "line_width" ) ) ) { strokeWidth = props[QStringLiteral( "line_width" )].toDouble(); } if ( props.contains( QStringLiteral( "offset" ) ) ) offset = QgsSymbolLayerUtils::decodePoint( props[QStringLiteral( "offset" )] ); if ( props.contains( QStringLiteral( "joinstyle" ) ) ) penJoinStyle = QgsSymbolLayerUtils::decodePenJoinStyle( props[QStringLiteral( "joinstyle" )] ); QgsSimpleFillSymbolLayer *sl = new QgsSimpleFillSymbolLayer( color, style, strokeColor, strokeStyle, strokeWidth, penJoinStyle ); sl->setOffset( offset ); if ( props.contains( QStringLiteral( "border_width_unit" ) ) ) { sl->setStrokeWidthUnit( QgsUnitTypes::decodeRenderUnit( props[QStringLiteral( "border_width_unit" )] ) ); } else if ( props.contains( QStringLiteral( "outline_width_unit" ) ) ) { sl->setStrokeWidthUnit( QgsUnitTypes::decodeRenderUnit( props[QStringLiteral( "outline_width_unit" )] ) ); } else if ( props.contains( QStringLiteral( "line_width_unit" ) ) ) { sl->setStrokeWidthUnit( QgsUnitTypes::decodeRenderUnit( props[QStringLiteral( "line_width_unit" )] ) ); } if ( props.contains( QStringLiteral( "offset_unit" ) ) ) sl->setOffsetUnit( QgsUnitTypes::decodeRenderUnit( props[QStringLiteral( "offset_unit" )] ) ); if ( props.contains( QStringLiteral( "border_width_map_unit_scale" ) ) ) sl->setStrokeWidthMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( props[QStringLiteral( "border_width_map_unit_scale" )] ) ); if ( props.contains( QStringLiteral( "offset_map_unit_scale" ) ) ) sl->setOffsetMapUnitScale( QgsSymbolLayerUtils::decodeMapUnitScale( props[QStringLiteral( "offset_map_unit_scale" )] ) ); sl->restoreOldDataDefinedProperties( props ); return sl; }
設定値はQgsSymbolLayerUtilsを参照
Qt::BrushStyle QgsSymbolLayerUtils::decodeBrushStyle( const QString &str ) { if ( str == QLatin1String( "solid" ) ) return Qt::SolidPattern; if ( str == QLatin1String( "horizontal" ) ) return Qt::HorPattern; if ( str == QLatin1String( "vertical" ) ) return Qt::VerPattern; if ( str == QLatin1String( "cross" ) ) return Qt::CrossPattern; if ( str == QLatin1String( "b_diagonal" ) ) return Qt::BDiagPattern; if ( str == QLatin1String( "f_diagonal" ) ) return Qt::FDiagPattern; if ( str == QLatin1String( "diagonal_x" ) ) return Qt::DiagCrossPattern; if ( str == QLatin1String( "dense1" ) ) return Qt::Dense1Pattern; if ( str == QLatin1String( "dense2" ) ) return Qt::Dense2Pattern; if ( str == QLatin1String( "dense3" ) ) return Qt::Dense3Pattern; if ( str == QLatin1String( "dense4" ) ) return Qt::Dense4Pattern; if ( str == QLatin1String( "dense5" ) ) return Qt::Dense5Pattern; if ( str == QLatin1String( "dense6" ) ) return Qt::Dense6Pattern; if ( str == QLatin1String( "dense7" ) ) return Qt::Dense7Pattern; if ( str == QLatin1String( "no" ) ) return Qt::NoBrush; return Qt::SolidPattern; } QString QgsSymbolLayerUtils::encodeSldBrushStyle( Qt::BrushStyle style ) { switch ( style ) { case Qt::CrossPattern: return QStringLiteral( "cross" ); case Qt::DiagCrossPattern: return QStringLiteral( "x" ); /* The following names are taken from the presentation "GeoServer * Cartographic Rendering" by Andrea Aime at the FOSS4G 2010. * (see http://2010.foss4g.org/presentations/3588.pdf) */ case Qt::HorPattern: return QStringLiteral( "horline" ); case Qt::VerPattern: return QStringLiteral( "line" ); case Qt::BDiagPattern: return QStringLiteral( "slash" ); case Qt::FDiagPattern: return QStringLiteral( "backslash" ); /* define the other names following the same pattern used above */ case Qt::Dense1Pattern: case Qt::Dense2Pattern: case Qt::Dense3Pattern: case Qt::Dense4Pattern: case Qt::Dense5Pattern: case Qt::Dense6Pattern: case Qt::Dense7Pattern: return QStringLiteral( "brush://%1" ).arg( encodeBrushStyle( style ) ); default: return QString(); } }