簡體   English   中英

qt:QTreeView-將拖放限制為僅在特定的祖父母(祖先)中發生

[英]qt: QTreeView - limit drag and drop to only happen within a particlar grandparent (ancestor)

我有一個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...

標記為可拖動的任何內容都可以被拖動。 標記為可育的任何事物都可能具有可拖動項作為子項。 標記為固定的任何東西都是固定的。

我的問題是,我將如何限制物品掉落以留在特定的父母中? 例如,我可以拖動“ bloodOrange”並將其設為“ apple”或“ orange”的子代(甚至只是更改其在“ Fruit”內部的順序位置),但我不能使其成為胡蘿卜的子代或生菜等

我設法正確編碼了所有標志的標志,除了將放置操作限制在特定父級中的那部分之外。 我只是不知道如何捕獲當前拖動的QModelIndex(我可以從中確定父母,祖父母等)

謝謝!

這是我的flags方法的代碼(如果有幫助的話):注:我將頂層子節點稱為Node(即“食物”),將下一層子節點稱為Groups(即“水果”),將最后兩層子節點(即“水果”)稱為生菜和卷心菜都屬於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 

如果您希望拖動鼠標懸停在某些行上時顯示“不允許”圖標,我相信您不能從模型中做到這一點。 您必須在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)

(請注意,“無關緊要的工作”我的意思是“我不想打擾這些事件” :-)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM