Pythonスクリプトアイテム

Pythonスクリプトアイテムとは

Pythonスクリプトアイテム(PythonScriptItem)は、Pythonスクリプトファイル(.py)に対応するアイテムです。スクリプトファイルをプロジェクトのアイテムとして管理し、GUI上の操作で実行できるようにするものです。アイテムはプロジェクトの一部として保存されるため、プロジェクトに関連するスクリプトをプロジェクトと一緒に管理することができます。

スクリプトの読み込み

スクリプトファイルは、メインメニューの「ファイル」-「読み込み」-「Pythonスクリプト」で読み込みます。読み込むと、スクリプトファイルに対応するアイテムがアイテムツリーに追加されます。

なお、Choreonoid起動時にコマンドラインオプションでスクリプトをアイテムとして読み込むこともできます。これについては コマンドラインからのスクリプト実行 を参照してください。

スクリプトの実行

スクリプトの実行は、アイテムツリー上でこのアイテムを右クリックして表示されるコンテキストメニューから行います。コンテキストメニューには「実行」と「停止」の項目が追加されており、任意のタイミングでスクリプトを実行したり、実行中のスクリプトを停止したりすることができます。

スクリプトの出力(printの出力やエラーメッセージ等)はメッセージビューに表示されます。

また、ツールバーの「スクリプトバー」を表示しておくと、そのボタンを押すことで、チェックの入った全てのスクリプトアイテムをまとめて実行することができます。ツールバーはメインメニューの「表示」-「ツールバーの表示」から表示できます。

プロジェクト読み込み時の自動実行

「プロジェクト読込時に実行」プロパティをtrueにしておくと、プロジェクトの読み込みと同時にスクリプトが自動実行されます。プロジェクトの初期化処理等をスクリプト化しておくのに便利です。

バックグラウンド実行

スクリプトは通常メインスレッド(GUIのスレッド)で実行されます。このため実行時間の長いスクリプトを実行すると、その間GUIの操作がブロックされてしまいます。「バックグラウンド実行」プロパティをtrueにすると、スクリプトはメインスレッドとは別のスレッドで実行されるようになり、実行中もGUIの操作が可能となります。

ただし、バックグラウンド実行には以下の注意点があります。

GUIに関わる処理はメインスレッドに委譲する

GUIに関わるオブジェクト(アイテムやビュー、ウィジェット等)をバックグラウンド実行のスレッドから直接操作することはスレッドセーフではなく、クラッシュ等の原因となり得ます。アイテムの操作についても、シグナルを介してビューの表示更新等の処理を同じスレッド上で引き起こすことがあるため、これに該当します。

バックグラウンドで実行するスクリプトでそのような処理を行いたい場合は、 cnoid.Base モジュールの callLater 関数か callSynchronously 関数を用いて、処理をメインスレッドに委譲するようにしてください。

from cnoid.Base import *

def updateItems():
    ...  # ここにGUIに関わる処理を記述します

callLater(updateItems)

callLater は処理をメインスレッドに依頼してすぐに戻ります。一方 callSynchronously は、メインスレッドでの処理の完了を待ってから戻ります。

「停止」で必ず停止できるとは限らない

バックグラウンド実行中のスクリプトは、コンテキストメニューの「停止」で中断することができます。この停止処理は、スクリプトを実行中のスレッドに対して停止用の例外を送り込むことで実現されています。この例外が処理されるのはスクリプトがPythonのコードを実行しているタイミングであるため、C++等で実装された関数の呼び出しの中で長時間ブロックしているような場合は、停止できないことがあります。

アイテムのプロパティ

Pythonスクリプトアイテムでは以下のプロパティが利用できます。

プロパティ

デフォルト値

意味

スクリプト

読み込んでいるスクリプトのファイル名です(表示のみ)。

プロジェクト読込時に実行

false

trueにすると、プロジェクトの読み込みと同時にスクリプトが自動実行されます。

バックグラウンド実行

false

trueにすると、スクリプトをメインスレッドとは別のスレッドでバックグラウンド実行します。時間のかかるスクリプトでもGUIの操作がブロックされなくなります。

独立名前空間

false

trueにすると、スクリプトを独立した名前空間で実行します。他のスクリプトやPythonコンソールと変数等を共有したくない場合に使用します。