我很难将图标从列表视图(ViewMode设置为IconMode)拖放到另一个视图。它与我在docs中发现的相似。
场景:用户将QIcon 1从ListView 1拖放到ListView2。ListView2应该将QIcon 1添加到其模型中。此外,当将特定 QIcon添加到ListView 2时,我想做一些后台工作。我如何知道QIcon 1放到ListView 2而不是QIcon 2上?
主窗口(设置布局,将图像加载到列表视图1中):
class Ui_MainWindow(object):
...
def loadImages(self):
model = QStandardItemModel()
images = Path("images").glob("*.*")
for image in images:
item = QStandardItem()
item.setIcon(QIcon(str(image)))
model.appendRow(item)
self.listView1.setModel(model)
列表视图1:
class ListView1(QListView):
def __init__(self):
super().__init__()
self.setAcceptDrops(False)
self.setViewMode(QtWidgets.QListView.IconMode)
self.setEditTriggers(QAbstractItemView.NoEditTriggers)
self.setIconSize(QSize(50, 50))
self.setResizeMode(QtWidgets.QListView.Adjust)
self.setDragDropMode(QAbstractItemView.DragOnly)
列表视图2:
class ListView2(QListView):
def __init__(self):
super().__init__()
self.setViewMode(QtWidgets.QListView.IconMode)
self.setDragDropMode(QAbstractItemView.DropOnly)
self.setIconSize(QSize(50, 50))
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
event.accept()
def dropEvent(self, event):
event.accept()
event.setDropAction(QtCore.Qt.MoveAction)
event.acceptProposedAction()
如何将图标从列表视图1拖放到列表视图2并访问其属性?
答案 0 :(得分:1)
由于这些实现已经存在并且可以正常工作,因此不必覆盖dragEnterEvent,dragMoveEvent或dropEvent,您所指出的示例适用于未实现这些事件的其他类型的小部件。
from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
class LListView(QtWidgets.QListView):
def __init__(self, parent=None):
super(LListView, self).__init__(parent)
self.model = QtGui.QStandardItemModel(self)
self.setModel(self.model)
self.setAcceptDrops(False)
self.setViewMode(QtWidgets.QListView.IconMode)
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.setIconSize(QtCore.QSize(50, 50))
self.setResizeMode(QtWidgets.QListView.Adjust)
self.setDragDropMode(QtWidgets.QAbstractItemView.DragOnly)
class RListView(QtWidgets.QListView):
def __init__(self, parent=None):
super(RListView, self).__init__(parent)
self.model = QtGui.QStandardItemModel(self)
self.setModel(self.model)
self.setAcceptDrops(True)
self.setViewMode(QtWidgets.QListView.IconMode)
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.setIconSize(QtCore.QSize(50, 50))
self.setResizeMode(QtWidgets.QListView.Adjust)
self.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
central_widget = QtWidgets.QWidget()
self.l_view = LListView()
self.r_view = RListView()
self.setCentralWidget(central_widget)
lay = QtWidgets.QHBoxLayout(central_widget)
lay.addWidget(self.l_view)
lay.addWidget(self.r_view)
self.loadImages()
def loadImages(self):
images = Path("images").glob("*.*")
for image in images:
item = QtGui.QStandardItem()
item.setIcon(QtGui.QIcon(str(image)))
self.l_view.model.appendRow(item)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())
更新:
如果要添加标识符,可以通过创建项目时传递的角色来完成,然后在dropEvent()
中获取所有角色,然后获取所需的角色,并通过它获得标识符:
from pathlib import Path
from PyQt5 import QtCore, QtGui, QtWidgets
class LListView(QtWidgets.QListView):
def __init__(self, parent=None):
super(LListView, self).__init__(parent)
self.m_model = QtGui.QStandardItemModel(self)
self.setModel(self.m_model)
self.setAcceptDrops(False)
self.setViewMode(QtWidgets.QListView.IconMode)
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.setIconSize(QtCore.QSize(50, 50))
self.setResizeMode(QtWidgets.QListView.Adjust)
self.setDragDropMode(QtWidgets.QAbstractItemView.DragOnly)
class RListView(QtWidgets.QListView):
def __init__(self, parent=None):
super(RListView, self).__init__(parent)
self.m_model = QtGui.QStandardItemModel(self)
self.setModel(self.m_model)
self.setAcceptDrops(True)
self.setEditTriggers(QtWidgets.QAbstractItemView.NoEditTriggers)
self.setIconSize(QtCore.QSize(50, 50))
self.setResizeMode(QtWidgets.QListView.Adjust)
self.setDragDropMode(QtWidgets.QAbstractItemView.DropOnly)
def dropEvent(self, event):
last_row_count = self.model().rowCount()
super(RListView, self).dropEvent(event)
# check if an item is added
if self.model().rowCount() > last_row_count:
md = event.mimeData()
fmt = "application/x-qabstractitemmodeldatalist"
if md.hasFormat(fmt):
encoded = md.data(fmt)
stream = QtCore.QDataStream(encoded, QtCore.QIODevice.ReadOnly)
datas = []
item = {}
while not stream.atEnd():
row = stream.readInt32()
column = stream.readInt32()
map_items = stream.readInt32()
for i in range(map_items):
key = stream.readInt32()
value = QtCore.QVariant()
stream >> value
item[QtCore.Qt.ItemDataRole(key)] = value
datas.append(item)
for data in datas:
identifier = data[QtCore.Qt.UserRole+1].value()
print("identifier: ", identifier)
class MainWindow(QtWidgets.QMainWindow):
def __init__(self, parent=None):
super(MainWindow, self).__init__(parent)
central_widget = QtWidgets.QWidget()
self.l_view = LListView()
self.r_view = RListView()
self.setCentralWidget(central_widget)
lay = QtWidgets.QHBoxLayout(central_widget)
lay.addWidget(self.l_view)
lay.addWidget(self.r_view)
self.loadImages()
def loadImages(self):
images = Path("images").glob("*.*")
for i, image in enumerate(images):
item = QtGui.QStandardItem()
identifier = "img_{:06d}".format(i+1)
item.setData(identifier, QtCore.Qt.UserRole+1)
item.setIcon(QtGui.QIcon(str(image)))
self.l_view.m_model.appendRow(item)
if __name__ == '__main__':
import sys
app = QtWidgets.QApplication(sys.argv)
w = MainWindow()
w.show()
sys.exit(app.exec_())