【发布时间】:2017-05-26 11:42:59
【问题描述】:
我目前正在开发一个 Python 程序,我想通过拖放将项目从一个 QListWidget 移动到另一个。
我阅读了这个thread,并按照描述实现了拖放。它适用于标准 QListWidgetItems。 问题是,我想在 QListWidgetItems 中执行此自定义小部件,如 here 所述,将图标和几行存储到 1 个 QListWidgetItem 中。
所以当我现在将一个项目拖放到另一个列表中时,它是空的,因为它似乎只是移动/复制没有 ItemWidget 的 QListWidgetItem。
这是一个示例代码:
from PyQt4 import QtGui, QtCore
import sys, os
class ThumbListWidget(QtGui.QListWidget):
def __init__(self, type, parent=None):
super(ThumbListWidget, self).__init__(parent)
self.setIconSize(QtCore.QSize(124, 124))
self.setDragDropMode(QtGui.QAbstractItemView.DragDrop)
self.setSelectionMode(QtGui.QAbstractItemView.ExtendedSelection)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasUrls():
event.accept()
else:
super(ThumbListWidget, self).dragEnterEvent(event)
def dragMoveEvent(self, event):
if event.mimeData().hasUrls():
event.setDropAction(QtCore.Qt.CopyAction)
event.accept()
else:
super(ThumbListWidget, self).dragMoveEvent(event)
def dropEvent(self, event):
if event.mimeData().hasUrls():
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.MoveAction)
super(ThumbListWidget, self).dropEvent(event)
class Dialog_01(QtGui.QMainWindow):
def __init__(self):
super(QtGui.QMainWindow,self).__init__()
self.listItems={}
myQWidget = QtGui.QWidget()
myBoxLayout = QtGui.QVBoxLayout()
myQWidget.setLayout(myBoxLayout)
self.setCentralWidget(myQWidget)
self.myQListWidget = ThumbListWidget(self)
myBoxLayout.addWidget(self.myQListWidget)
for index, name, icon in [
('No.1', 'Meyoko', 'icon.png'),
('No.2', 'Nyaruko', 'icon.png'),
('No.3', 'Louise', 'icon.png')]:
# Create QCustomQWidget
myQCustomQWidget = QCustomQWidget()
myQCustomQWidget.setTextUp(index)
myQCustomQWidget.setTextDown(name)
myQCustomQWidget.setIcon(icon)
# Create QListWidgetItem
myQListWidgetItem = QtGui.QListWidgetItem(self.myQListWidget)
# Set size hint
myQListWidgetItem.setSizeHint(myQCustomQWidget.sizeHint())
# Add QListWidgetItem into QListWidget
self.myQListWidget.addItem(myQListWidgetItem)
self.myQListWidget.setItemWidget(myQListWidgetItem, myQCustomQWidget)
self.listWidgetB = ThumbListWidget(self)
myBoxLayout.addWidget(self.listWidgetB)
class QCustomQWidget (QtGui.QWidget):
def __init__ (self, parent = None):
super(QCustomQWidget, self).__init__(parent)
self.textQVBoxLayout = QtGui.QVBoxLayout()
self.textUpQLabel = QtGui.QLabel()
self.textDownQLabel = QtGui.QLabel()
self.textQVBoxLayout.addWidget(self.textUpQLabel)
self.textQVBoxLayout.addWidget(self.textDownQLabel)
self.allQHBoxLayout = QtGui.QHBoxLayout()
self.iconQLabel = QtGui.QLabel()
self.allQHBoxLayout.addWidget(self.iconQLabel, 0)
self.allQHBoxLayout.addLayout(self.textQVBoxLayout, 1)
self.setLayout(self.allQHBoxLayout)
# setStyleSheet
self.textUpQLabel.setStyleSheet('''
color: rgb(0, 0, 255);
''')
self.textDownQLabel.setStyleSheet('''
color: rgb(255, 0, 0);
''')
def setTextUp (self, text):
self.textUpQLabel.setText(text)
def setTextDown (self, text):
self.textDownQLabel.setText(text)
def setIcon (self, imagePath):
self.iconQLabel.setPixmap(QtGui.QPixmap(imagePath))
if __name__ == '__main__':
app = QtGui.QApplication(sys.argv)
dialog_1 = Dialog_01()
dialog_1.show()
dialog_1.resize(480,320)
sys.exit(app.exec_())
所以基本问题是:如何在使用拖放的同时传输项目 ItemWidget。
对这样的事情使用 QListView 会更好吗?
【问题讨论】:
-
你不能这样做。 Item 的数据和标志必须在拖放过程中进行序列化,并且无法序列化
QWidget(参见:Serializing Qt Data Types)。另见this relevant question。 -
不是我希望的答案,而是我期望的答案。:) 我什至无法从列表中读取 QWidget。现在我开始重新创建拖放的条目。明天我会试试 QListView。
-
QListWidget类是QListView,所以不会有任何区别。拖放机制在整个 Qt 中都是相同的,因此适用相同的限制。为什么需要将小部件作为数据存储在项目中?为什么不将键存储到包含对小部件的引用的字典中? -
不太明白。我将如何识别拖动的项目并在新的 ListWidget 中分配其小部件?
标签: python python-2.7 drag-and-drop pyqt4 qlistwidget