2010-11-18 2 views
1

ドラッグアンドドロップを実装してアイテムの並べ替えを可能にするQTreeViewがあります。ドラッグ可能としてマークされた何かをドラッグすることができるqt:QTreeView - 特定の祖父母(祖先)内でのみドラッグアンドドロップが発生するように制限する

Food      <--fixed 
|--Vegetables    <--fixed 
| |--carrots   <-- draggable/parentable 
| |--lettuce   <-- draggable/parentable 
| | |--icebergLettuce <-- draggable but NOT parentable 
|--Fruit     <-- fixed 
| |--apple    <-- draggable/parentable 
| |--orange    <-- draggable/parentable 
| |--bloodOrange  <-- draggable/parentable 
etc... 

は、ツリーの次の例を考えます。 parentableとしてマークされたものは、子供としてドラッグ可能なアイテムを持つことができます。固定されているものはすべて固定されています。

私の質問は、特定の親の中に留まるためにアイテムを落とすことをどのように制限するのですか?例えば、私は 'bloodOrange'をドラッグして 'りんご'や 'オレンジ'の子にすることができます(あるいは「フルーツ」内の順序を変更することもできます)が、私はそれをニンジンの子にすることはできませんレタスなど。

私は、特定の親にとどまるようにドロップ操作を制限する部分を除いて、すべてのフラグを正しくコーディングすることができました。私はちょうどドラッグされたQModelIndex(私は親、祖父母などを決定することができます)をキャプチャする方法を知りません

ありがとう!

ここではフラグメソッドのコードを参考にしています。注:トップレベルの子ノードをノード(つまり「食品」)、グループの次のレベル(「フルーツ」)、最終レベル2つのレベル(すなわちレタスとアイスバーグレタス)はどちらもParamsです。

#--------------------------------------------------------------------------- 
def flags(self, index): 
    """ 
    Returns whether or not the current item is editable/selectable/etc. 
    """ 

    if not index.isValid(): 
     return QtCore.Qt.ItemIsEnabled 

    #by default, you can't do anything 
    enabled = QtCore.Qt.NoItemFlags 
    selectable = QtCore.Qt.NoItemFlags 
    editable = QtCore.Qt.NoItemFlags 
    draggable = QtCore.Qt.NoItemFlags 
    droppable = QtCore.Qt.NoItemFlags 

    #get a pointer to the referenced object 
    item = index.internalPointer() 

    #only 'valid' cells may be manipulated ('valid' is defined by the obj) 
    if item.column_is_valid(index.column()): 

     #all valid cells are selectable and enabled 
     selectable = QtCore.Qt.ItemIsSelectable 
     enabled = QtCore.Qt.ItemIsEnabled 

     #column 0 cells may occasionally be dragged and dropped 
     if index.column() == 0: 

      #drag/drop is only possible if it is a param... 
      if item.get_obj_type() == 'param': 

       #...and then only child-less params may be dragged... 
       if item.get_child_count() == 0: 
        draggable = QtCore.Qt.ItemIsDragEnabled 

       #...and only params with a group as parent may be dropped on 
       if item.get_parent().get_obj_type() == "group": 
        droppable = QtCore.Qt.ItemIsDropEnabled 

     #all other valid columns > 0 may be edited (no drag or drop) 
     else:     
      editable = QtCore.Qt.ItemIsEditable 

    #return our flags. 
    return enabled | selectable| editable| draggable| droppable 

答えて

1

特定の行にカーソルを置いたときにドラッグが「許可されていません」アイコンを表示するようにするには、モデルから行えないと思います。 ViewウィジェットのdragEnter/Moveイベントをインターセプトする必要があります。

ただし、dropMimeData()は、ドロップが拒否されたことを示すFalseを返すことができます。

私のQtバージョンでは、モデルによって拒否されたドロップに関するqdnd_winのバグがあります。ここでは、いくつかのソースダイビングに基づく私の回避策です。これは私のQTreeViewサブクラスで定義されたメソッドです。

def dropEvent(self, evt): 
    QTreeView.dropEvent(self, evt) 
    if not evt.isAccepted(): 
     # qdnd_win.cpp has weird behavior -- even if the event isn't accepted 
     # by target widget, it sets accept() to true, which causes the executed 
     # action to be reported as "move", which causes the view to remove the 
     # source rows even though the target widget didn't like the drop. 
     # Maybe it's better for the model to check drop-okay-ness during the 
     # drag rather than only on drop; but the check involves not-insignificant work. 
     evt.setDropAction(Qt.IgnoreAction) 

(「-無視できない仕事」で、私は本当に「私はイベントをインターセプトする気にしたくない」を意味することに注意してください:-)

+0

これは、ました非常に有益なおかげで、私はこの正確な問題を経験していました。 – TrevorB

関連する問題