Python PyQt4中的多个拖放操作
我找不到使用Qt/PyQt拖放多个元素的示例; 在本例中,我需要从该QTableView中拖动元素:Python PyQt4中的多个拖放操作,python,drag-and-drop,pyqt,pyqt4,Python,Drag And Drop,Pyqt,Pyqt4,我找不到使用Qt/PyQt拖放多个元素的示例; 在本例中,我需要从该QTableView中拖动元素: class DragTable(QTableView): def __init__(self, parent = None): super(DragTable, self).__init__(parent) self.setDragEnabled(True) def dragEnterEvent(self, event): if
class DragTable(QTableView):
def __init__(self, parent = None):
super(DragTable, self).__init__(parent)
self.setDragEnabled(True)
def dragEnterEvent(self, event):
if event.mimeData().hasFormat("application/pubmedrecord"):
event.setDropAction(Qt.MoveAction)
event.accept()
else:
event.ignore()
def startDrag(self, event):
print type(event)
index = self.indexAt(event.pos())
if not index.isValid():
return
selected = index.row()
bstream = cPickle.dumps(selected)
mimeData = QMimeData()
mimeData.setData("application/pubmedrecord", bstream)
drag = QDrag(self)
drag.setMimeData(mimeData)
pixmap = QPixmap(":/drag.png")
drag.setHotSpot(QPoint(pixmap.width()/3, pixmap.height()/3))
drag.setPixmap(pixmap)
result = drag.start(Qt.MoveAction)
def mouseMoveEvent(self, event):
self.startDrag(event)
到此QLabel My dropzone:
class TagLabel(QLabel):
def __init__(self, text, color, parent = None):
super(TagLabel, self).__init__(parent)
self.tagColor = color
self.setText(text)
self.setStyleSheet("QLabel { background-color: %s; font-size: 14pt; }" % self.tagColor)
self.defaultStyle = self.styleSheet()
self.setAlignment(Qt.AlignHCenter|Qt.AlignVCenter)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasFormat("application/pubmedrecord"):
self.set_bg(True)
event.accept()
else:
event.reject()
def dragLeaveEvent(self, event):
self.set_bg(False)
event.accept()
def dropEvent(self, event):
self.set_bg(False)
data = event.mimeData()
bstream = data.retrieveData("application/pubmedrecord", QVariant.ByteArray)
selected = pickle.loads(bstream.toByteArray())
event.accept()
self.emit(SIGNAL("dropAccepted(PyQt_PyObject)"), (selected, str(self.text()), str(self.tagColor)))
def set_bg(self, active = False):
if active:
style = "QLabel {background: yellow; font-size: 14pt;}"
self.setStyleSheet(style)
else:
self.setStyleSheet(self.defaultStyle)
有什么建议吗?谢谢大家! 下面是一个完整的工作示例:
from PyQt4 import QtCore, QtGui, Qt
import cPickle
import pickle
你为什么既用泡菜又用cPickle
您可能希望在这里设置选择行为,因为我假设的是基于行的数据表示。你当然可以改变这一点
def dragEnterEvent(self, event):
if event.mimeData().hasFormat("application/pubmedrecord"):
event.setDropAction(Qt.MoveAction)
event.accept()
else:
event.ignore()
def startDrag(self, event):
根据事件位置,您的代码在此仅假定一个索引。对于QTableView,这是不必要的,因为它已经处理了鼠标单击本身。相反,像往常一样,最好依靠Qt为您提供实际需要的信息。在这里,我选择使用selectedIndex
索引现在是QModelIndex实例的列表,我选择将其转换为一组行号。根据您的需要,还可以将它们转换为QPersistentModelIndex列表
这里可能会让您感到惊讶的一点是,索引包含表中所有单元格的索引,而不是所有行的索引,无论选择行为如何。这就是为什么我选择使用集合而不是列表
我没动其余的,假设你知道你在那里做什么
bstream = cPickle.dumps(selected)
mimeData = QtCore.QMimeData()
mimeData.setData("application/pubmedrecord", bstream)
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
pixmap = QtGui.QPixmap(":/drag.png")
drag.setHotSpot(QtCore.QPoint(pixmap.width()/3, pixmap.height()/3))
drag.setPixmap(pixmap)
result = drag.start(QtCore.Qt.MoveAction)
def mouseMoveEvent(self, event):
self.startDrag(event)
class TagLabel(QtGui.QLabel):
def __init__(self, text, color, parent = None):
super(TagLabel, self).__init__(parent)
self.tagColor = color
self.setText(text)
self.setStyleSheet("QLabel { background-color: %s; font-size: 14pt; }" % self.tagColor)
self.defaultStyle = self.styleSheet()
self.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasFormat("application/pubmedrecord"):
self.set_bg(True)
event.accept()
else:
event.reject()
def dragLeaveEvent(self, event):
self.set_bg(False)
event.accept()
def dropEvent(self, event):
self.set_bg(False)
data = event.mimeData()
bstream = data.retrieveData("application/pubmedrecord", QtCore.QVariant.ByteArray)
selected = pickle.loads(bstream.toByteArray())
event.accept()
self.emit(QtCore.SIGNAL("dropAccepted(PyQt_PyObject)"), (selected, str(self.text()), str(self.tagColor)))
除非您使用此信号与C++代码交互,否则不必在此处添加信号参数,您也可以使用不带括号的dropAccepted,PyQt4将做正确的事情
def set_bg(self, active = False):
if active:
style = "QLabel {background: yellow; font-size: 14pt;}"
self.setStyleSheet(style)
else:
self.setStyleSheet(self.defaultStyle)
app = QtGui.QApplication([])
l = TagLabel("bla bla bla bla bla bla bla", "red")
l.show()
m = QtGui.QStandardItemModel()
for _ in xrange(4):
m.appendRow([QtGui.QStandardItem(x) for x in ["aap", "noot", "mies"]])
t = DragTable()
t.setModel(m)
t.show()
def h(o):
print "signal handled", o
l.connect(l, QtCore.SIGNAL("dropAccepted(PyQt_PyObject)"), h)
app.exec_()
下面是一个完整的工作示例:
from PyQt4 import QtCore, QtGui, Qt
import cPickle
import pickle
你为什么既用泡菜又用cPickle
您可能希望在这里设置选择行为,因为我假设的是基于行的数据表示。你当然可以改变这一点
def dragEnterEvent(self, event):
if event.mimeData().hasFormat("application/pubmedrecord"):
event.setDropAction(Qt.MoveAction)
event.accept()
else:
event.ignore()
def startDrag(self, event):
根据事件位置,您的代码在此仅假定一个索引。对于QTableView,这是不必要的,因为它已经处理了鼠标单击本身。相反,像往常一样,最好依靠Qt为您提供实际需要的信息。在这里,我选择使用selectedIndex
索引现在是QModelIndex实例的列表,我选择将其转换为一组行号。根据您的需要,还可以将它们转换为QPersistentModelIndex列表
这里可能会让您感到惊讶的一点是,索引包含表中所有单元格的索引,而不是所有行的索引,无论选择行为如何。这就是为什么我选择使用集合而不是列表
我没动其余的,假设你知道你在那里做什么
bstream = cPickle.dumps(selected)
mimeData = QtCore.QMimeData()
mimeData.setData("application/pubmedrecord", bstream)
drag = QtGui.QDrag(self)
drag.setMimeData(mimeData)
pixmap = QtGui.QPixmap(":/drag.png")
drag.setHotSpot(QtCore.QPoint(pixmap.width()/3, pixmap.height()/3))
drag.setPixmap(pixmap)
result = drag.start(QtCore.Qt.MoveAction)
def mouseMoveEvent(self, event):
self.startDrag(event)
class TagLabel(QtGui.QLabel):
def __init__(self, text, color, parent = None):
super(TagLabel, self).__init__(parent)
self.tagColor = color
self.setText(text)
self.setStyleSheet("QLabel { background-color: %s; font-size: 14pt; }" % self.tagColor)
self.defaultStyle = self.styleSheet()
self.setAlignment(QtCore.Qt.AlignHCenter|QtCore.Qt.AlignVCenter)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
if event.mimeData().hasFormat("application/pubmedrecord"):
self.set_bg(True)
event.accept()
else:
event.reject()
def dragLeaveEvent(self, event):
self.set_bg(False)
event.accept()
def dropEvent(self, event):
self.set_bg(False)
data = event.mimeData()
bstream = data.retrieveData("application/pubmedrecord", QtCore.QVariant.ByteArray)
selected = pickle.loads(bstream.toByteArray())
event.accept()
self.emit(QtCore.SIGNAL("dropAccepted(PyQt_PyObject)"), (selected, str(self.text()), str(self.tagColor)))
除非您使用此信号与C++代码交互,否则不必在此处添加信号参数,您也可以使用不带括号的dropAccepted,PyQt4将做正确的事情
def set_bg(self, active = False):
if active:
style = "QLabel {background: yellow; font-size: 14pt;}"
self.setStyleSheet(style)
else:
self.setStyleSheet(self.defaultStyle)
app = QtGui.QApplication([])
l = TagLabel("bla bla bla bla bla bla bla", "red")
l.show()
m = QtGui.QStandardItemModel()
for _ in xrange(4):
m.appendRow([QtGui.QStandardItem(x) for x in ["aap", "noot", "mies"]])
t = DragTable()
t.setModel(m)
t.show()
def h(o):
print "signal handled", o
l.connect(l, QtCore.SIGNAL("dropAccepted(PyQt_PyObject)"), h)
app.exec_()
很好的解释,我不能要求更多:谢谢!为什么QListWidget不能代替QLabel工作?好的,它可以工作,但只有在QListWidget上使用setDragDropMode4。很好的解释,我不能要求更多:谢谢!为什么这不适用于QListWidget而不是QLabel?好的,它可以工作,但只有在QListWidget上使用setDragDropMode4时才能工作。