如何将QLineEdit从QGridLayout的一个单元格拖动到pyqt中的其他单元格?

问题描述 投票:0回答:1

我有四个单元格的网格布局(0,0),(0,1),(1,0),(1,1)。每个单元格都是带有滚动条的垂直布局。最初只有 (0,0) 单元格包含 QLineEdit。我想将它们拖放到单元格的任何一个中。我该怎么做。我想要如下图所示的布局。 enter image description here

我已经尝试过使用 PyQt5 代码拖放 QLabels,但它不起作用。 我想从 (0,0) 单元格拖动元素并放置任何单元格,以便它将从单元格 (0,0) 中删除并添加到它放置的单元格布局中。每个单元格都包含滚动条,因为每个单元格中可以有很多元素。

python user-interface pyqt pyqt5
1个回答
0
投票
使用

QLineEdit

 
启用拖动功能。

  1. 创建QLineEdit
    的子类以
    启用拖动。覆盖 mousePressEvent
    mouseMoveEvent
     开始拖动。
  2. 子类QVBoxLayout
    以使其接受掉落。覆盖 
    dragEnterElement
    dragMoveElement
    dropEvent
  3. 修改 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_())
    
© www.soinside.com 2019 - 2024. All rights reserved.