試験運用中なLinux備忘録・旧記事

はてなダイアリーで公開していた2007年5月-2015年3月の記事を保存しています。

PyGTKでツリービューにリストのデータ(ListStore)を表示(ボタンからデータの順番を入れ替える・メモ)

GTK+のツリービュー上のデータの並び順を変えられるようにしたいとき、「PyGTKでツリービューにリストのデータ(ListStore)を表示(項目をGUI上で追加/削除、データの並べ替えや入れ替えなど)」の例のようにドラッグ・アンド・ドロップを用いて移動できるようにする方法もあるが、GNOMEのデスクバーの設定ダイアログのように項目をボタンから上下に移動できるようになっているものもある。
ここではボタンから選択項目の移動ができるような例を扱う。

方法

ツリービュー上のデータ自体はListStoreかTreeStoreなので、これらのオブジェクトのデータを並べ替えるためのメンバ関数を呼ぶ。

  • 選択項目はこれまでにも試したようにgtk.TreeViewオブジェクトget_selection()により得られるgtk.TreeSelectionオブジェクトget_selected()の戻り値から得る*1・ただし複数選択モードのときにはこのようにはできない
  • 項目を一番上に移動させるにはモデルのmove_after()の2番目の引数にNoneを指定するだけでOK
  • 項目を一番下に移動させるには同様にmove_before()の2番目の引数にNoneを指定するだけでOK
  • 項目を1つ上に移動させるには選択項目の1つ上の項目を示すgtk.TreeIterオブジェクトを得てからモデルのmove_before()で移動
  • 項目を1つ下に移動させるには同様に選択項目の1つ下の項目を示すgtk.TreeIterオブジェクトを得てからモデルのmove_after()で移動
選択項目の1つ上の項目を示すgtk.TreeIterオブジェクトを得る

少なくとも以下の2つの方法がある。

  • モデルのget_iter_first()で最初のgtk.TreeIterオブジェクトを得た後ループでiter_next()により1つずつ進めていき、その中でiter_next()の戻り値が示すツリーパスと現在参照しているツリーパスとが一致*2したときにループを抜けるようにする
  • 選択項目のツリーパスを取得してその値をタプルから取り出して値を1引いたものをモデルのget_iter()gtk.TreeIterオブジェクトに変換したものを使用
選択項目の1つ下の項目を示すgtk.TreeIterオブジェクトを得る

選択項目を指し示すgtk.TreeIterオブジェクトをモデルのiter_next()の引数に渡した戻り値として得られる。
こちらは1つ上に移動する場合と違って次に進めるための操作(メンバ関数)が用意されているので楽。

複数選択モードで選択項目が1つのときに項目を移動できるようにする

ツリービューを複数選択モードにして、複数個のデータを選択してまとめて削除などの操作を行えるようにしつつ、単一の項目が選択されているときにはそれを移動できるようにしたいという場合がある。そのとき、gtk.TreeSelectionオブジェクトget_selected()の代わりにget_selected_rows()を使用しなくてはならず、gtk.TreeIterオブジェクトは複数個得られるような形になっているのだが、ここで得られたオブジェクト数が1つのときに0番の要素を取り出して単独選択モードのときのように処理できるようにすることはできる。

    (model, selected) = treeview.get_selection().get_selected_rows()
    iters = [model.get_iter(path) for path in selected]
    # 複数個の項目が選択されている場合は処理を行わない
    if len(iters) == 1:
      (以下iters[0]を選択項目のTreeIterとして移動の処理...)

関連記事:

参考URL:

*1:タプルで返り、1番目にモデル(gtk.ListStoreオブジェクトgtk.TreeStoreオブジェクト)、2番目に選択項目を指し示すgtk.TreeIterオブジェクトが返る

*2:gtk.TreeIterオブジェクトどうしを比較するのではない