如何在 qlistwidget 上获取从 dropEvent 创建的项目
How to get the item created from dropEvent on a qlistwidget
因此,我尝试使用拖放操作将所选项目从一个 QListWidget 复制到另一个。
无论如何,我可能可以通过使用 item.setData 传递序列化参数来拼凑我需要的东西,但我想不出一个直接的方法来处理在第二个 listWidget 中创建的新项目.
我想我可以查看第二个 QListWidget 中的所有项目,并以某种方式确定刚刚创建的项目,但似乎应该有一种更简单的方法来了解 drop 事件正在创建哪个项目。
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()
您可以连接到列表视图模型上的 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
有趣.. 我的解决方案最终是在第二个 listwidget 之前存储一个项目列表,然后在添加新项目后进行比较,这工作得很好并且只需要几行代码。然后我将新项目传递给一个函数,该函数使用在第一个 listwidget 中创建它时使用的相同 类 创建该项目,并且我在 .data(QtCore.Qt.UserRole)[= 中传递了有关的序列化信息11=]
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)
因此,我尝试使用拖放操作将所选项目从一个 QListWidget 复制到另一个。
无论如何,我可能可以通过使用 item.setData 传递序列化参数来拼凑我需要的东西,但我想不出一个直接的方法来处理在第二个 listWidget 中创建的新项目.
我想我可以查看第二个 QListWidget 中的所有项目,并以某种方式确定刚刚创建的项目,但似乎应该有一种更简单的方法来了解 drop 事件正在创建哪个项目。
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()
您可以连接到列表视图模型上的 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
有趣.. 我的解决方案最终是在第二个 listwidget 之前存储一个项目列表,然后在添加新项目后进行比较,这工作得很好并且只需要几行代码。然后我将新项目传递给一个函数,该函数使用在第一个 listwidget 中创建它时使用的相同 类 创建该项目,并且我在 .data(QtCore.Qt.UserRole)[= 中传递了有关的序列化信息11=]
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)