我有四个单元格的网格布局(0,0),(0,1),(1,0),(1,1)。每个单元格都是带有滚动条的垂直布局。最初只有 (0,0) 单元格包含 QLineEdit。我想将它们拖放到单元格的任何一个中。我该怎么做。我想要如下图所示的布局。
我已经尝试过使用 PyQt5 代码拖放 QLabels,但它不起作用。 我想从 (0,0) 单元格拖动元素并放置任何单元格,以便它将从单元格 (0,0) 中删除并添加到它放置的单元格布局中。每个单元格都包含滚动条,因为每个单元格中可以有很多元素。
QLineEdit
启用拖动功能。
QLineEdit
的子类以启用拖动。覆盖
mousePressEvent
和
mouseMoveEvent
开始拖动。
QVBoxLayout
以使其接受掉落。覆盖
dragEnterElement
、
dragMoveElement
和
dropEvent
。
QGridLayout
确保将其设置为处理放置事件并管理重新定位
QLineEdit
小部件。
from PyQt5.QtWidgets import QApplication, QWidget, QLineEdit, QVBoxLayout, QGridLayout
from PyQt5.QtCore import Qt, QMimeData, QPoint
from PyQt5.QtGui import QDrag
class DraggableLineEdit(QLineEdit):
def __init__(self, parent=None):
super(DraggableLineEdit, self).__init__(parent)
self.setDragEnabled(True)
def mousePressEvent(self, event):
if event.button() == Qt.LeftButton:
self.drag_start_position = event.pos()
def mouseMoveEvent(self, event):
if not (event.buttons() & Qt.LeftButton):
return
if (event.pos() - self.drag_start_position).manhattanLength() < QApplication.startDragDistance():
return
drag = QDrag(self)
mimedata = QMimeData()
mimedata.setText(self.objectName())
drag.setMimeData(mimedata)
drag.exec_(Qt.CopyAction | Qt.MoveAction)
class DropAcceptingVBoxLayout(QVBoxLayout):
def __init__(self, parent=None):
super(DropAcceptingVBoxLayout, self).__init__(parent)
self.setAcceptDrops(True)
def dragEnterEvent(self, event):
event.accept()
def dragMoveEvent(self, event):
event.accept()
def dropEvent(self, event):
widget_name = event.mimeData().text()
widget = self.parent().findChild(QLineEdit, widget_name)
if widget:
event.setDropAction(Qt.MoveAction)
event.accept()
self.addWidget(widget)
class MainWidget(QWidget):
def __init__(self, parent=None):
super(MainWidget, self).__init__(parent)
self.gridLayout = QGridLayout(self)
self.layouts = {}
for row in range(2):
for col in range(2):
layout = DropAcceptingVBoxLayout()
self.layouts[(row, col)] = layout
self.gridLayout.addLayout(layout, row, col)
self.lineEdit = DraggableLineEdit("Drag me!")
self.lineEdit.setObjectName("draggableLineEdit")
self.layouts[(0, 0)].addWidget(self.lineEdit)
if __name__ == "__main__":
import sys
app = QApplication(sys.argv)
mainWidget = MainWidget()
mainWidget.show()
sys.exit(app.exec_())