• 6012阅读
  • 6回复

[提问]如何使QTreeWidget的节点只能在同级间拖放 [复制链接]

上一主题 下一主题
离线cjalchange
 
只看楼主 倒序阅读 楼主  发表于: 2012-08-26
如题。本人初学者,希望高手指点。
离线祥龙九霄

只看该作者 1楼 发表于: 2013-07-31
你判断你拖放的的节点和要拖到的节点的父节点的索引是否相同,如果相同就让它拖动,否则就不让拖放。

步骤:
1、获取选中的节点为currItem。
2、用parentItem = currItem->parent()获取父节点,判断父节点是否存在,如果存在的话继续调用parent()函数一直到不存在,此时说明已经找到你选中的节点的最上层的根节点。然后调用his->indexOfTopLevelItem(parentItem)来获取最顶层父节点的索引,之后用parentItem->indexOfChild(currItem)来获取从最顶层父节点一直到currItem最近父节点的所有索引。
3、获取要拖动到的item,同步骤2一样获取所有父节点的索引。
4、根据2和3获取的所有所以逐级对比,如果完全相同则说明是在同一级目录,则可以拖放,否则不能拖放。
离线pain22

只看该作者 2楼 发表于: 2013-08-01
回 1楼(祥龙九霄) 的帖子
能给出具体的代码吗???谢谢
离线pain22

只看该作者 3楼 发表于: 2013-08-01
回 1楼(祥龙九霄) 的帖子
4和3的逻辑对吗?  4才让它可以拖动,3就要获取要拖动到的item,这可能吗????
离线ppdayz

只看该作者 4楼 发表于: 2013-08-01
最简单的办法就是创建item的时候给item设置一个层级,topLevelItem设置为0,他的子节点都是1,再子节点都是2,
拖动的时候做简单的判断就可以了。
用item->setData函数,这样在相同种类的不同树之间拖拽也很方便。
离线祥龙九霄

只看该作者 5楼 发表于: 2013-08-07
鼠标拖动到的位置可以获取坐标点,用这个坐标点就可以获得鼠标所在的item,之后才可以拖动的,我这段时间做的东西就是这样实现的。
离线祥龙九霄

只看该作者 6楼 发表于: 2013-08-07

这段代码写的是针对二级树的,你要是树有多级的话就一直判断父节点存在不并记录索引号即可。下边是实现拖放的
部分代码。

  1. void CTreeWidget::mousePressEvent(QMouseEvent *event)
  2. {
  3.     // restore the sign
  4.     m_bAdjustPos = true;
  5.     m_iLastItemIndex = -1;        //    要拖放的选中的点的父节点的索引
  6.     m_iCurrItemIndex = -1;        //    要拖放的选中的点相对于父节点的索引
  7.     m_iLastParentIndex = -1;    //    要拖放到的点的父节点的索引
  8.     m_iCurrParentIndex = -1;    //    要拖放到的点相对于父节点的索引
  9.     QPoint pt = event->pos();
  10.     QTreeWidgetItem *currItem = this->itemAt(pt);
  11.     if(currItem)
  12.     {
  13.         QTreeWidgetItem *parentItem = currItem->parent();
  14.         if(parentItem)                  //  当前选中的是子节点
  15.         {
  16.             m_iLastParentIndex = this->indexOfTopLevelItem(parentItem);  //    获取父节点和本身相对于父节点的索引
  17.             m_iLastItemIndex = parentItem->indexOfChild(currItem);
  18.         }
  19.         else                                        //  当前选中的是父节点
  20.         {
  21.             //   对顶级节点的操作
  22.             m_iLastParentIndex = this->indexOfTopLevelItem(currItem);
  23.         }
  24.     }
  25. }
  26. void CTreeWidget::mouseReleaseEvent(QMouseEvent *event)
  27. {
  28.     QPoint pt = event->pos();
  29.     QTreeWidgetItem *currItem = this->itemAt(pt);
  30.     if(currItem && m_bAdjustPos)            //  父节点不能调整顺序,即只能调整子节点顺序,
  31.                                         //  调整子节点顺序分在同一个父节点下不在同一个父节点下
  32.     {
  33.         QTreeWidgetItem *parentItem = currItem->parent();
  34.         if(parentItem)                  //  说明选中的是子节点
  35.         {
  36.             m_iCurrParentIndex = this->indexOfTopLevelItem(parentItem);
  37.             m_iCurrItemIndex = parentItem->indexOfChild(currItem);
  38.         }
  39.         else                            //  选中的是父节点
  40.         {
  41.             m_iCurrParentIndex = this->indexOfTopLevelItem(currItem);
  42.         }
  43.         adjustItemInfo(m_iLastParentIndex, m_iLastItemIndex, m_iCurrParentIndex, m_iCurrItemIndex);
  44.     }
  45.     m_bAdjustPos = false;
  46. }
  47. void CTreeWidget::adjustItemInfo(int lastParIndex, int lastSubIndex, int currParIndex, int currSubIndex)
  48. {
  49.     if(lastParIndex == -1)          //  没有选中交换的节点
  50.     {
  51.         return;
  52.     }
  53.     if(lastSubIndex == -1)          //  选中的是父节点,不能拖入到其它级别中
  54.     {
  55.         return;
  56.     }
  57.     if(currParIndex == -1)          //  要拖入的节点不存在
  58.     {
  59.         return;
  60.     }
  61.     if(lastParIndex == currParIndex  &&  lastSubIndex == currSubIndex)
  62.     {
  63.         return;
  64.     }
  65.     CTreeWidgetItem *lastParItem = static_cast<CTreeWidgetItem*>(this->topLevelItem(m_iLastParentIndex));            //    获取要拖动的节点的父节点
  66.     CTreeWidgetItem *lastSubItem = static_cast<CTreeWidgetItem*>(lastParItem->takeChild(m_iLastItemIndex));                //    获取要拖动的节点并移除
  67.     //    在指定位置插入节点
  68.     CTreeWidgetItem *currParItem = static_cast<CTreeWidgetItem*>(this->topLevelItem(m_iCurrParentIndex));
  69.     if(m_iCurrItemIndex == -1)
  70.     {
  71.         m_iCurrItemIndex = 0;
  72.         currParItem->insertChild(m_iCurrItemIndex, lastSubItem);
  73.     }
  74.     else
  75.     {
  76.         currParItem->insertChild(m_iCurrItemIndex, lastSubItem);
  77.     }
  78. }





快速回复
限100 字节
 
上一个 下一个