dndwidgets: add DragDropFlowLayoutWidget

This commit is contained in:
Simon Renblad 2024-04-30 16:01:59 +08:00
parent 147a2b83cf
commit 9d93ad444a

View File

@ -1,4 +1,6 @@
from PyQt5 import QtCore, QtWidgets
from PyQt5 import QtCore, QtWidgets, QtGui
from artiq.gui.flowlayout import FlowLayout
class VDragDropSplitter(QtWidgets.QSplitter):
@ -98,3 +100,65 @@ class VDragScrollArea(QtWidgets.QScrollArea):
dy = self._direction * self._speed
new_val = min(max_, max(min_, val + dy))
self.verticalScrollBar().setValue(new_val)
# Widget with FlowLayout and drag and drop support between widgets
class DragDropFlowLayoutWidget(QtWidgets.QWidget):
def __init__(self):
QtWidgets.QWidget.__init__(self)
self.layout = FlowLayout()
self.setLayout(self.layout)
self.setAcceptDrops(True)
def _get_index(self, pos):
for i in range(self.layout.count()):
if self.itemAt(i).geometry().contains(pos):
return i
return -1
def mousePressEvent(self, event):
if event.buttons() == QtCore.Qt.LeftButton \
and event.modifiers() == QtCore.Qt.ShiftModifier:
index = self._get_index(event.pos())
if index == -1:
return
drag = QtGui.QDrag(self)
mime = QtCore.QMimeData()
mime.setData("index", str(index).encode())
drag.setMimeData(mime)
pixmapi = QtWidgets.QApplication.style().standardIcon(
QtWidgets.QStyle.SP_FileIcon)
drag.setPixmap(pixmapi.pixmap(32))
drag.exec_(QtCore.Qt.MoveAction)
event.accept()
def dragEnterEvent(self, event):
event.accept()
def dropEvent(self, event):
index = self._get_index(event.pos())
source_layout = event.source()
source_index = int(bytes(event.mimeData().data("index")).decode())
if source_layout == self:
if index == source_index:
return
widget = self.layout.itemAt(source_index).widget()
self.layout.removeWidget(widget)
self.layout.addWidget(widget)
self.layout.itemList.insert(index, self.layout.itemList.pop())
else:
widget = source_layout.layout.itemAt(source_index).widget()
source_layout.layout.removeWidget(widget)
self.layout.addWidget(widget)
if index != -1:
self.layout.itemList.insert(index, self.layout.itemList.pop())
event.accept()
def addWidget(self, widget):
self.layout.addWidget(widget)
def count(self):
return self.layout.count()
def itemAt(self, i):
return self.layout.itemAt(i)