我需要能够将项目从一个listWidget复制到另一个。这很容易做到,但我似乎无法找出一种方法来区分放下动作,这取决于被拖动的项目是否在它被删除的列表中,而不必覆盖几乎每个拖放功能用我自己的。当我将一个项目从一个列表拖到另一个列表时,我想复制它,但是当我在同一个列表中拖动项目时,我想移动它。
我一直在研究设置mimetypes,但后来我必须编写自己的mouseMoveEvent,作为一种方式来判断拖动项目的来源,但到目前为止尝试打破了所有内容。是否无法在不重写mouseMoveEvent的情况下为项设置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 :(得分: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()
答案 1 :(得分:0)
辨别拖动是来自这个小部件还是来自不同的小部件是微不足道的——只需在任何拖/放事件中使用事件源即可。例如:
void MyWidget::dragMoveEvent(QDragMoveEvent *event)
{
if (event->source() != this) {
// the drag comes from another widget
}
}