3

私はカスタム GenericTreeModel を持っていますが、これは問題なく動作します。ここで、ユーザーがドラッグ アンド ドロップを使用してノードを再配置できるようにしたいので、ノードをデータ モデル内の新しい親に移動します。ただし、TreeModel は 、 、 などのメソッドを使用して通知を受ける必要がrow_has_child_toggledありrow_deletedますrow_inserted

したがって、(元のパスの場合) と(新しいパスの場合)row_movedを呼び出すだけでは十分ではないようです。したがって、これらの変更を再帰的に発行する必要があるかもしれないと考えました。row_deletedrow_inserted

次の例を検討してください。

* A (0,)
* B (1,)
  * C (1,0)
    * D (1,0,0)

ここで、C を A に移動すると、次のことが起こります。

row_delete( (1,0) ) # C
row_delete( (1,0,0) ) # D
row_inserted( (0,0) ) # C'
row_inserted( (0,0,0) ) # D'
child_toggle( (0,) ) # A
child_toggle( (1,) ) # B
child_toggle( (0,1) ) # C'

ただし、gtk はまだモデルの状態に一貫性がないことについて不平を言っています。次の 2 つのことが頭に浮かびます。

  • おそらく、これらの関数を呼び出す順序が関連している可能性があります(もしそうなら、どのように考えていますか?)
  • 技術的child_toggle( (1,0) )にも発生しますが、行は a) 既に削除されており、b)参照row_has_child_toggledが必要tree_iterですが、もう存在しないため取得できません。

たぶん私はここで完全に間違ったアプローチに従っているので、これを行う最善の方法は何ですか?

4

2 に答える 2

2

サブツリーの削除は、サブツリーのルート ノード行を削除することで正常に機能します (パスがなくなったことをモデルに通知し、条件付きで parent.has_child を切り替えます)。同じことが新しいサブツリーの挿入にも当てはまるので、モデルに再帰的に伝える必要はありません。

ただし、組み合わせが重要なので、

  1. 最初の削除、モデルへの通知
  2. 次に、モデルを再度挿入して通知します。
于 2011-09-09T10:32:38.393 に答える
1

IMHO、この更新は、ツリービューを「drag_data_get」および「drag_data_received」メソッドで正しく接続し、「enable_model_drag_dest」および「enable_model_drag_source」メソッドでソースおよび宛先にすることを許可すると、ツリービューに対して自動的に行われます。ツリービューに対して行うことはこれ以上ありません。

「drag_data_received_data」の呼び出しでモデルを更新する必要がありますが、「削除」は必要ありません。ここに示すように、特定の「insert_before」または「insert_after」のみを実行します。

   def drag_data_received_data(self, treeview, context, x, y, selection,
                               info, etime):
       model = treeview.get_model()
       data = selection.data
       drop_info = treeview.get_dest_row_at_pos(x, y)
       if drop_info:
           path, position = drop_info
           iter = model.get_iter(path)
           if (position == gtk.TREE_VIEW_DROP_BEFORE
               or position == gtk.TREE_VIEW_DROP_INTO_OR_BEFORE):
               model.insert_before(iter, [data])
           else:
               model.insert_after(iter, [data])
       else:
           model.append([data])
       if context.action == gtk.gdk.ACTION_MOVE:
           context.finish(True, True, etime)
       return

このスニペットは次のものから来ています:

http://www.pygtk.org/pygtk2tutorial/sec-TreeViewDragAndDrop.html#DragDropReordering

プログラム「treeviewdnd.py」は、必要なものを表示するために完全に機能します。

これであなたのクエストが解決することを願っています!

于 2011-09-06T09:03:43.057 に答える