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 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 (我的拖放区):
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)
有什么提示吗?谢谢你!
i can't find an example on dragging (and dropping) multiple elements with Qt/PyQt;
In my case i need to drag elements from this QTableView:
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)
To this 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)
Any tips? Thank you!
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
这是一个完整的工作示例:
为什么使用
cPickle
以及pickle
?您可能想在此处设置选择行为,因为我假设基于行的数据表示。你当然可以改变这一点。
根据事件位置,您的代码在此仅假定一个索引。对于 QTableView 来说,这是不必要的,因为它本身已经处理了鼠标单击。相反,最好一如既往地依靠 Qt 为您提供您实际需要的信息。在这里,我选择使用
selectedIndexes()
。索引现在是
QModelIndex
实例的列表,我选择将其转换为一组行号。根据您的需要,还可以将它们转换为QPersistentModelIndex
列表。这里可能会让您感到惊讶的一件事是,索引包含表中所有单元格的索引,而不是所有行,无论选择行为如何。这就是为什么我选择使用
set
而不是list
。假设您知道自己在做什么,其余部分我保持不变。
除非您使用此信号与 C++ 代码交互,否则无需在此处添加信号参数,您也可以使用不带括号的
dropAccepted
,PyQt4 将执行正确的操作。Here's a full working example:
Why are you using
cPickle
as well aspickle
?You probably want to set the selection behavior here, because I'm assuming row-based data presentation. You may of course change that.
Your code assumes only one index here, based on the event position. For a
QTableView
, this is unnecessary, as it already handles the mouse click itself. Instead, it's better to depend on Qt to provide you with the information that you actually need, as always. Here, I've chose to useselectedIndexes()
.Indices is now a list of
QModelIndex
instances, that I chose to convert to a set of row numbers. It's also possible to convert these to a list ofQPersistentModelIndex
es, depending on your needs.One thing that may surprise you here, is that indices contains indexes for all cells in the table, not all rows, regardless of the selection behavior. That's why I chose to use a
set
instead of alist
.I left the rest untouched, assuming that you know what you're doing there.
Unless you are interfacing with C++-code with this signal, it's not necessary to add a signal argument here, you may also use
dropAccepted
without parentheses and PyQt4 will do the right thing.