2016-10-21 7 views
0

한 목록 위젯에서 다른 목록 위젯으로 항목을 복사 할 수 있어야합니다. 이 작업은 충분히 쉽지만 드래그되는 항목이 목록에 생성되었는지 여부에 따라 드롭 액션을 구별 할 수있는 방법을 찾지 못하는 것 같습니다. 거의 모든 드래그 앤 드롭 기능을 개인적인. 한 목록에서 다른 목록으로 항목을 드래그하면 복사 할 수 있지만 같은 목록에서 항목을 드래그하면 해당 항목을 옮기고 싶습니다.한 목록에서 끌어서 놓기로 복사 할 수 있지만 내부 끌어서 놓기로 이동하려면

mimetypes를 설정하는 방법을 살펴 보았지만 드래그 한 항목의 출처를 말할 수있는 방법으로 직접 mouseMoveEvent를 작성해야했지만 지금까지 시도한 모든 항목이 손상되었습니다. mouseMoveEvent를 오버라이드 (override)하지 않고 아이템의 MIME 타입을 설정할 수 있습니까?

드래그하는 항목은 사용자 정의 된 것이므로 두 번째 목록으로 이동하거나 복사 할 때 다시 정의하기 위해 자체 정의를 작성해야합니다. 기본 드래그 기능을 사용하면이 모든 것이 내부 이동과 함께 잘 작동합니다. 그러나 지금까지 드래그가 내부 이동 인 경우 기본 드래그 드롭 함수를 사용하는 방법을 알아낼 수 없었고 드롭이 다른 목록에서 나왔을 때 항목을 복사하기 위해 내 사용자 지정 함수로 전환했습니다.

import sys 
from PyQt4 import QtGui , QtCore 


def main(): 

    app = QtGui.QApplication(sys.argv) 

    w = QtGui.QWidget() 
    w.resize(250, 150) 
    w.move(300, 300) 
    w.setWindowTitle('Simple') 
    layout=QtGui.QHBoxLayout(w) 
    dragList=DragDropListWidget() 
    layout.addWidget(dragList) 
    dragList.setDragDropMode(QtGui.QAbstractItemView.InternalMove) 
    dragList.name='dragList' 
    dragList.populate(['one','two','three']) 
    dragList2=DragDropListWidget() 
    dragList2.setDragDropMode(QtGui.QAbstractItemView.DragDrop) 
    dragList2.name='dragList' 


    layout.addWidget(dragList2) 
    w.show() 

    sys.exit(app.exec_()) 

class scriptsWidget(QtGui.QWidget): 


    def __init__(self, parent=None): 
     QtGui.QWidget.__init__(self) 

     self.name='' 

     self.widget_QHBoxLayout = QtGui.QHBoxLayout(self) 
     self.widget_QHBoxLayout.setSpacing(0) 
     self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0) 

     self.name_QLabel = QtGui.QLabel(self) 
     self.widget_QHBoxLayout.addWidget(self.name_QLabel) 

     self.user_QLabel = QtGui.QLabel(self) 
     self.widget_QHBoxLayout.addWidget(self.user_QLabel) 

     self.widget_QHBoxLayout.setSpacing(0) 
     self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0) 



    def setName(self,name): 
     self.name_QLabel.setText(name) 
     self.name=name 

    def setUser(self,user): 
     self.user_QLabel.setText(user) 

class customQListWidgetItem(QtGui.QListWidgetItem): 


    def __init__(self, parent=None): 
     QtGui.QWidget.__init__(self) 
     self.name='' 

    def setName(self,name): 
     self.name=name 




class DragDropListWidget(QtGui.QListWidget): 
    _drag_info = [] 
    def __init__(self, parent = None): 

     super(DragDropListWidget, self).__init__(parent) 


     self.name='' 


    def dragMoveEvent(self, event): 
     if event.mimeData().hasUrls(): 
      event.setDropAction(QtCore.Qt.CopyAction) 
      event.accept() 

     else: 
      super(DragDropListWidget, self).dragMoveEvent(event) 


    def dropEvent(self, event): 
     if event.mimeData().hasText(): 
      event.setDropAction(QtCore.Qt.CopyAction) 
      event.accept() 
      links = [] 
      for url in event.mimeData().urls(): 
       links.append(str(url.toLocalFile())) 
      self.emit(QtCore.SIGNAL("dropped"), links) 

     else: 
      event.setDropAction(QtCore.Qt.CopyAction) 
      items = [] 
      for index in xrange(self.count()): 
       items.append(self.item(index)) 

      super(DragDropListWidget, self).dropEvent(event) 

      for index in xrange(self.count()): 
       if self.item(index) not in items: 
        self.populateDrop(self.item(index), index, [self.item(index).data(QtCore.Qt.UserRole).toPyObject()]) 

    def populateDrop(self,item,row,items=[]): 
     for i in items: 
      widget = scriptsWidget() 
      widget.setName(i) 
      widget.setUser('x') 
      self.takeItem(row) 
      item = customQListWidgetItem() 
      item.setName(i) 
      item.setWhatsThis(i) 
      data = (i) 
      item.setData(QtCore.Qt.UserRole, data) 
      self.insertItem (row, item) 
      self.setItemWidget(item,widget) 



    def populate(self,items=[]): 
     self.clear() 
     for i in items: 
      print(i) 
      widget = scriptsWidget() 
      widget.setName(i) 
      widget.setUser('x') 
      item = customQListWidgetItem() 
      item.setName(i) 
      data = (i) 
      item.setData(QtCore.Qt.UserRole, data) 
      self.addItem(item) 
      self.setItemWidget(item,widget) 



if __name__ == '__main__': 
    main() 

답변

0

글쎄, 내가 생각해 냈다. 항목을 클릭 할 때 클래스 데이터 변수를 설정하므로 항목이 삭제되었을 때의 위치를 ​​알 수 있습니다. 나는 DragDropListWidget 내부에서 클래스 변수를 사용했지만 어떤 이유로 현재 목록의 로컬 이름 만 저장하려고했습니다. 이상한. 전역 변수도 작동했지만 바람직하지 않습니다.

import sys 
from PyQt4 import QtGui , QtCore 

def main(): 

    app = QtGui.QApplication(sys.argv) 

    w = QtGui.QWidget() 
    w.resize(250, 150) 
    w.move(300, 300) 
    w.setWindowTitle('Simple') 
    layout=QtGui.QHBoxLayout(w) 
    dragList=DragDropListWidget() 
    layout.addWidget(dragList) 
    d=data() 
    dragList.setDragDropMode(QtGui.QAbstractItemView.InternalMove) 
    dragList.name='dragList' 
    dragList.populate(['one','two','three']) 
    dragList.data=d 
    dragList2=DragDropListWidget() 
    dragList2.setDragDropMode(QtGui.QAbstractItemView.DragDrop) 
    dragList2.name='dragList2' 
    dragList2.external='dragList2' 
    dragList2.data=d 


    layout.addWidget(dragList2) 
    w.show() 

    sys.exit(app.exec_()) 

class data(object): 
    def __init__(self, parent=None): 
     self.origin='new' 




class scriptsWidget(QtGui.QWidget): 


    def __init__(self, parent=None): 
     QtGui.QWidget.__init__(self) 

     self.name='' 

     self.widget_QHBoxLayout = QtGui.QHBoxLayout(self) 
     self.widget_QHBoxLayout.setSpacing(0) 
     self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0) 

     self.name_QLabel = QtGui.QLabel(self) 
     self.widget_QHBoxLayout.addWidget(self.name_QLabel) 

     self.user_QLabel = QtGui.QLabel(self) 
     self.widget_QHBoxLayout.addWidget(self.user_QLabel) 

     self.widget_QHBoxLayout.setSpacing(0) 
     self.widget_QHBoxLayout.setContentsMargins(0, 0, 0, 0) 



    def setName(self,name): 
     self.name_QLabel.setText(name) 
     self.name=name 

    def setUser(self,user): 
     self.user_QLabel.setText(user) 

class customQListWidgetItem(QtGui.QListWidgetItem): 


    def __init__(self, parent=None): 
     QtGui.QWidget.__init__(self) 
     self.name='' 
     self.list='' 

    def setName(self,name): 
     self.name=name 




class DragDropListWidget(QtGui.QListWidget): 

    def __init__(self, parent = None): 

     super(DragDropListWidget, self).__init__(parent) 
     self._dropping = False 
     self.itemPressed.connect(self.clicked) 

     self.data='' 

     self.name='' 
     self.external='' 
     self.internal=False 

    def clicked(self): 
     global origin 
     self.data.origin=self.name 


    def dragMoveEvent(self, event): 

     if event.mimeData().hasUrls(): 
      event.setDropAction(QtCore.Qt.CopyAction) 
      event.accept() 

     else: 

      super(DragDropListWidget, self).dragMoveEvent(event) 


    def dropEvent(self, event): 

     if event.mimeData().hasText(): 
      event.setDropAction(QtCore.Qt.CopyAction) 
      event.accept() 
      links = [] 
      for url in event.mimeData().urls(): 
       links.append(str(url.toLocalFile())) 
      self.emit(QtCore.SIGNAL("dropped"), links) 

     else: 
      if self.external is self.name and self.data.origin is not self.name: 
       print('external') 
       event.setDropAction(QtCore.Qt.CopyAction) 
       items = [] 
       for index in xrange(self.count()): 
        items.append(self.item(index)) 
       print items 

       super(DragDropListWidget, self).dropEvent(event) 

       for index in xrange(self.count()): 
        if self.item(index) not in items: 
         print(index) 
         self.populateDrop(self.item(index), index, [self.item(index).data(QtCore.Qt.UserRole).toPyObject()]) 

      else: 
       print('internal') 
       event.setDropAction(QtCore.Qt.MoveAction) 

       super(DragDropListWidget, self).dropEvent(event) 

     self.data.origin = None  

    def populateDrop(self,item,row,items=[]): 
     for i in items: 
      widget = scriptsWidget() 
      widget.setName(i) 
      widget.setUser('x') 
      self.takeItem(row) 
      item = customQListWidgetItem() 
      item.setName(i) 
      item.setWhatsThis(i) 
      item.list=self.name 
      data = (i) 
      item.setData(QtCore.Qt.UserRole, data) 
      self.insertItem (row, item) 
      self.setItemWidget(item,widget) 



    def populate(self,items=[]): 
     self.clear() 
     for i in items: 
      print(i) 
      widget = scriptsWidget() 
      widget.setName(i) 
      widget.setUser('x') 

      item = customQListWidgetItem() 
      item.setName(i) 
      item.list=self.name 
      data = (i) 
      item.setData(QtCore.Qt.UserRole, data) 
      self.addItem(item) 
      self.setItemWidget(item,widget) 



if __name__ == '__main__': 
    main() 
관련 문제