Houdini 19.5 Pythonスクリプト hou hou.qt

hou.qt.ListEditor class

文字列のリストを表示/編集するための(ダイアログまたは再利用可能ウィジェットとしての)便利ユーザインターフェース。

On this page

概要

ユーザインターフェースをデザインする時に、ユーザ側で文字列のリストを表示/編集できるようにしたい場合が多いです。 例えば、プラグインファイルが検索されるディレクトリのリスト、オブジェクトに適用するタグのリスト、ライトが照明するオブジェクトパスのリストなどを設定できるようにしたいです。

このようなジョブに対応できるように、このオブジェクトにはコンパクトでシンプルでも強力なエディタが備わっています。 ここでは、ユーザに表示する文字列のリストを用意します。 ウィジェットでは、(オプションに応じて)ユーザがそのリストにアイテムを追加、削除、並べ替え、編集をすることができます。

文字列のテキストの編集だけでなく、各アイテムの隣に チェックボックス を表示して、そのチェック状態を付加情報として使用することができます。 例えば、ユーザがプロップを取り出したいアセットライブラリのリストを指定できるインターフェースが欲しいとします。 アイテムの隣にチェックボックスを用意することで、アセットライブラリを個々に削除して再追加する必要なく、個々のアセットライブラリを一時的に有効/無効にすることができます。

hou.qt.ListEditorDialog便利クラスの使い方

ダイアログウィンドウ内のListEditorを取得するには、hou.qt.ListEditorDialog既製クラスを使用すると良いです。 このクラスは、ListEditorと同じキーワード引数を受け取り、単にダイアログウィンドウ内でそのListEditorウィジェットをラップしているだけです。

ListEditorDialog.editor()を使用すると、そのListEditorの参照を取得することができます。

このクラスはQtのQtWidgets.QDialogクラスを継承しています。 このオブジェクトに用意されている膨大な数の便利なメソッドの情報は、Qtドキュメントを参照してください。

モーダルダイアログ

この方法でウィジェットをコールすると、ユーザはそのダイアログを受け入れ、または、キャンセルしないと、他のHoudiniウィンドウを使用することができません。

  1. 必要なオプションを使ってウィジェットをインスタンス化して設定します。

  2. そのウィジェットの.exec_()メソッドをコールするとダイアログが開き、ユーザがそのダイアログの操作を終了するまで待機します。

  3. その.exec_()メソッドコールの戻り値を使用することで、ユーザがそのダイアログを受け入れたのか、または、キャンセルしたのかを判断することができます。

dialog = hou.qt.ListEditorDialog(allow_editing=True, allow_add_remove=True,
                                 allow_reorder=True, allow_empty_string=False)
dialog.setWindowTitle("Edit Files")
dialog.resize(400, 360)

editor = dialog.editor()
editor.setTopMessage("Add, remove, or edit which files to read")
# 変数から現在のファイルパスのリストを取得します。
editor.setStrings(list_of_file_paths)

accepted = editor.exec_()
if accepted:
    # その変数を新しく編集したファイルパスのリストに置換します。
    list_of_file_paths = editor.strings()

モードレスダイアログ

  1. 必要なオプションを使ってウィジェットをインスタンス化して設定します。

  2. そのウィジェットのacceptedrejectedfinishedのどれかのシグナルを接続します。

  3. そのダイアログオブジェクトの.show()メソッドをコールすると、そのオブジェクトがウィンドウとして開かれます。

def show_tag_editor_for(node):
    # エディターウィジェットを作成して設定します。
    dialog = hou.qt.ListEditorDialog(allow_editing=False, allow_add_remove=True,
                                     allow_reorder=False, keep_sorted=True,
                                     show_checkboxes=True, initial_check=False)
    dialog.setWindowTitle("Edit Tags")

    editor = dialog.editor()
    editor.setTopMessage("Check the tags you want to apply. You can add new tags.")

    # そのエディターの内容には、すべての既知のタグのリストを設定します。
    # 指定したノードに現在適用されているタグをチェックします。
    for tag in list_of_all_tags:
        editor.addListItem(tag, node.hasTag(tag))

    # そのタグを更新する関数にそのエディターの"accepted"シグナルを接続します。
    dialog.accepted.connect(lambda: update_node_tags(node, editor.stringsAndChecks()))

    # この関数が終了してもすぐに消えないようにこのウィジェットの参照を`hou.session`内に保存します。
    # これは変数に保存していて少し単純化されていますが、
    # 1度に1個のタグエディターしか存在できないことを意味します。
    hou.sesssion.tag_editor = editor

    # ユーザが操作できるようにウィジェットをウィンドウとして表示します。
    dialog.show()


def update_node_tags(node, tags_and_checks):
    for tag, checked in tags_and_checks:
        if checked:
            node.addTag(tag)

Note

このウィジェットへの持続的な参照が少なくとも1個なければならないことを忘れないでください。 そうしないと、そのウィンドウがガーベジコレクションされて即座に閉じられてしまいます。

Qtレイアウト内にListEditorをウィジェットとして埋め込む方法

もっと大きいユーザインターフェース内でListEditorをそのままウィジェットとして使用することができます。

  1. 必要なオプションを使ってウィジェットをインスタンス化して設定します。

  2. QWidgetの場合と同様に、そのウィジェットをQtインターフェースに追加します。

  3. 現在のエディターの内容を取得する必要がある場合は、そのウィジェットのstrings()またはstringsAndChecks()メソッドを使用します。

# Qtユーザインターフェースをセットアップします。
class MyUI(QtWidgets.QFrame):
    def __init__(self, parent):
        super(MyUI, self).__init__(parent)
        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)

        # ListEditorオブジェクトを作成して設定します。
        self._editor = hou.qt.ListEditor(allow_editing=True,
                                         allow_add_remove=True,
                                         allow_reorder=True,
                                         allow_empty_string=False)
        self._editor.setTopMessage("Add, remove, or edit which files to read")
        # 変数から現在のファイルパスのリストを取得します。
        self._editor.setStrings(list_of_file_paths)

        # そのウィジェットをユーザインターフェースに追加します。
        layout.addWidget(self._editor)

    def read_files(self):
        for filepath in self._editor.strings():
            ...

Tipsとメモ

  • allow_add_remove=True且つallow_editing=Falseの場合、ユーザは、新しく作成されたアイテムの初期文字列値を入力することができますが、Enterを押した後はその文字列を編集することができません。

  • allow_reorder=True且つkeep_sorted=Trueの場合、ユーザは、アイテムをドラッグすることができるものの、それらのアイテムをドラッグして並び替えることはできません。混乱を避けるために、keep_sortedを有効にしたらallow_reorderを無効にしてください。

シグナル

itemEdited(int, str)

アイテムのテキストが変更されると発動されます。 (0から始まる)行番号とそのアイテムの新しいテキストが指定されてコールされます。

checkChanged(int, str, bool)

アイテムのチェック状態が変更されると発動されます。 (0から始まる)行番号とそのアイテムのテキストと新しいチェック状態(TrueまたはFalse)が指定されてコールされます。

listChanged()

文字列のリストが変更される度に(ユーザがアイテムを追加、移動、削除する度に)発動されます。 strings()またはstringsAndChecks()メソッドをコールすることで、その新しいリストの内容を取得することができます。

メソッド

hou.qt