2016-10-19 2 views
1

그래서 드래그 앤 드롭을 사용하여 QListWidget에서 다른 항목으로 선택된 항목을 복사하려고합니다.qlistwidget에서 dropEvent로 만든 항목을 얻는 방법

어쨌든 item.setData를 사용하여 직렬화 된 매개 변수를 전달하면 필요한 부분을 해킹 할 수 있지만 두 번째 listWidget에서 생성되는 새 항목에 대한 핸들을 얻는 방법을 이해할 수는 없습니다.

두 번째 QListWidget의 모든 항목을 살펴보고 방금 생성 된 항목을 어떻게 든 결정할 수 있지만 드롭 이벤트에서 어떤 항목이 만들어지고 있는지 쉽게 알 수있는 것처럼 보입니다.

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): 
     print('dropEvent') 
     print event.mimeData().text() 

     if event.mimeData().hasText(): 
      print event.mimeData().text() 
      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) 
      super(DragDropListWidget, self).dropEvent(event) 
      items = [] 
      for index in xrange(self.count()): 
       items.append(self.item(index)) 
       print self.item(index).data(QtCore.Qt.UserRole).toPyObject() 



    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

재미있는 .. 물론 내 솔루션은 그 전에 두 번째 listwidget 항목의 목록을 저장하기 위해 었죠과 비교를 새 항목을 추가 한 후 코드가 몇 줄만 있으면 충분합니다. 그럼이 제 listwidget으로 만들고 난 .DATA에서 (QtCore.Qt.UserRole)에 대한 직렬화 정보

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) 
0

당신은 목록보기 모델에 rowsInserted 신호에 연결할 수 있습니다

class DragDropListWidget(...): 

    def __init__(...): 
     ... 
     self._dropping = False 
     self.model().rowsInserted.connect(self.on_rowsInserted) 

    def on_rowsInserted(self, parent_index, start, end): 
     if self._dropping: 
      # Recently dropped items 
      items = [self.item(i) for i in range(start, end + 1)] 

    def dropEvent(self, event): 
     self._dropping = True 
     # code that drops the new rows 
     ... 
     self._dropping = False 
+0

전달 될 때 사용 된 동일한 클래스를 이용하여 아이템을 생성하는 함수에 새로운 아이템을 건네 내가 정말로 도움이되기 전에 나는 이것을 조사했다. 인덱스가 새 항목에 속하는지 알기 위해 드롭 전후의 목록을 비교해야합니다. – obfuscated

+0

@obfuscated'on_rowsInserted' 콜백은 새 항목에 대해서만 트리거되어야합니다. –

+0

그럴 수도 있지만 다른 문제는 항목이 동일한 목록에서 시작된 경우 항목을 복사하는 대신 이동해야합니다 (다른 목록에서 시작된 항목을 복사하려고합니다). – obfuscated

관련 문제