[QGIS3][Qt5] メッセージボックスを Python から表示する方法

[QGIS3][Qt5] メッセージボックスを Python から表示する方法

QGIS3 のプラグインでメッセージボックスを表示したい

QGIS3 のプラグインを開発中にメッセージボックスを表示したくなったので調べました。その方法をまとめます。

Python のコード上から Qt5 のメッセージボックス表示用のAPIを利用します。確認は QGIS3 のPythonコンソール上から行えます。

プラグインのコード上から実行する場合は、以下のように QMessageBox をインポートしておく必要があります。

from PyQt5.QtWidgets import QMessageBox

QMessageBox のドキュメントは以下のページにあります。

QMessageBox — Qt for Python

静的関数で表示する

よく使う通知や確認、警告、エラー等の基本的なメッセージボックスであれば静的に呼び出して使えます。

この場合カスタマイズできるのはあらかじめ用意されたパターンだけです。タイトル、メッセージ、アイコン、ボタンの種類がカスタマイズできます。凝ったものでなければこれがお手軽に使えて便利です。

QMessageBox.question()

QMessageBox.question(None, "確認", "本当によろしいですか?", QMessageBox.Ok, QMessageBox.Cancel)
QMessageBox.question()
QMessageBox.question()

QMessageBox.critical()

QMessageBox.critical(None, "エラー", "予期せぬエラーが発生しました。", QMessageBox.Yes)
QMessageBox.critical()
QMessageBox.critical()

QMessageBox.warning()

QMessageBox.warning(None, "警告", "これは警告メッセージです。", QMessageBox.Yes)
QMessageBox.warning()
QMessageBox.warning()

QMessageBox.information()

QMessageBox.information(None, "通知", "インフォメーションです。", QMessageBox.Yes)
QMessageBox.information()
QMessageBox.information()

QMessageBox.about()

QMessageBox.about(None, "about", "about text ...")
QMessageBox.about()
QMessageBox.about()

about() だけ特殊でアイコンやボタンのカスタマイズはできないみたいです。

メッセージボックスのボタン押下を戻り値で判定する方法

QMessageBox.xxx() は表示したいアイコンによって関数を使い分けます。その際表示するボタンを指定し、その結果を戻り値で受け取れます。

関数の戻り値でメッセージボックスで押下したボタンの判定を取得できます。必要に応じて処理を分岐させられます。以下のような感じです。

result = QMessageBox.question(None, "確認", "本当によろしいですか?", QMessageBox.Ok, QMessageBox.Cancel)
if result == QMessageBox.Ok:
    print("OK")
elif result == QMessageBox.Cancel:
    print("Cancel")

戻り値は表示するボタンの種類を指定するときに使った定数と同じ値です。

ボタンについてはいくつかの種類が用意されていて、最大2つまで配置できます。3つ以上配置したい場合は後述の方法で対応しなければなりません。

用意されたボタンの種類

用意されたボタンの種類は以下の通りです。ボタンに表示されるテキストについては Windows 環境での確認です。

定数名 テキスト Role
QMessageBox.OK 開く AcceptRole
QMessageBox.Open 開く AcceptRole
QMessageBox.Cancel キャンセル AcceptRole
QMessageBox.Close キャンセル RejectRole
QMessageBox.Discard 変更を破棄 RejectRole
QMessageBox.Apply 適応 RejectRole
QMessageBox.Reset リセット ResetRole
QMessageBox.RestoreDefaults デフォルトに戻す ResetRole
QMessageBox.RestoreDefaults Help HelpRole
QMessageBox.SaveAll すべて保存 AcceptRole
QMessageBox.Yes はい(Y) YesRole
QMessageBox.SaveAll 全てはい(A) YesRole
QMessageBox.No いいえ(N) NoRole
QMessageBox.NoToAll 全ていいえ(O) NoRole
QMessageBox.NoToAll 全ていいえ(O) NoRole
QMessageBox.Abort 中止 RejectRole
QMessageBox.Retry 再試行 AcceptRole
QMessageBox.Ignore 中止 AcceptRole
QMessageBox.NoButton 無効なボタン

よく使うボタンがあらかじめ定義されています。

QMessageBox をインスタンス化してカスタマイズする

QMessageBox — Qt for Python

QMessageBox をインスタンス化することである程度メッセージボックスのカスタマイズができるようになります。

ボタンを3つ配置する

例えば静的関数では2つまでしかボタンを配置できませんでしたが、以下の例では3つのボタンを配置しています。

msgBox = QMessageBox()
msgBox.setWindowTitle("確認")
msgBox.setText("ドキュメントは変更されています。")
msgBox.setInformativeText("閉じる前に保存しますか?")
msgBox.setIcon(QMessageBox.Question)
msgBox.setStandardButtons(QMessageBox.Save | QMessageBox.Discard | QMessageBox.Cancel)
msgBox.setDefaultButton(QMessageBox.Save)
result = msgBox.exec_()

アイコンやテキスト、タイトル等も設定可能です。

テキストをカスタマイズする

メッセージボックス内のボタンのテキストをカスタマイズすることも可能です。また、メッセージ本文はHTMLで書くこともできます。たとえば以下のような感じです。

msgBox = QMessageBox()
msgBox.setText('<span style="color: blue">Good</span> or <span style="color: red">Bad</span> ?')
msgBox.setIcon(QMessageBox.Question)
goodButton = msgBox.addButton("Good", QMessageBox.ActionRole)
badButton = msgBox.addButton("Bad", QMessageBox.ActionRole)
msgBox.setDefaultButton(goodButton)
msgBox.exec_()

if msgBox.clickedButton() == goodButton:
    print("Good")
elif msgBox.clickedButton() == badButton:
    print("Bad")

ボタンテキストはHTMLにはできません。テキストにXMLタグがあればHTMLとして解釈されるようです。明示的にするには setTextFormat() を指定します。(この時指定する定数がどこにあるのかわかりませんでした … 。)

ボタン追加時にロールを設定する必要があるみたいですが適当なロールを定数から選びましょう。

ボタンをカスタマイズする場合、処理結果は戻り値ではなく clickedButton() を使って判定します。

詳細テキストを表示する

メッセージボックスに詳細なテキスト、例えば実行ログを表示するようなプロパティも用意されています。

msgBox = QMessageBox()
msgBox.setText("処理が完了しました。")
msgBox.setIcon(QMessageBox.Information)
msgBox.setStandardButtons(QMessageBox.Ok)
msgBox.setDetailedText("aaa\nbbb\nccc")
result = msgBox.exec_()

まとめ

ただのメッセージ通知であれば静的関数を使って処理しましょう。

細かいカスタマイズが必要であれば自分でインスタンス化して適宜必要な設定を施して使いましょう。

以上。

QGISカテゴリの最新記事