forked from M-Labs/artiq
dndwidgets: add DragDropFlowLayoutWidget
This commit is contained in:
parent
147a2b83cf
commit
9d93ad444a
@ -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):
|
class VDragDropSplitter(QtWidgets.QSplitter):
|
||||||
@ -98,3 +100,65 @@ class VDragScrollArea(QtWidgets.QScrollArea):
|
|||||||
dy = self._direction * self._speed
|
dy = self._direction * self._speed
|
||||||
new_val = min(max_, max(min_, val + dy))
|
new_val = min(max_, max(min_, val + dy))
|
||||||
self.verticalScrollBar().setValue(new_val)
|
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)
|
||||||
|
Loading…
Reference in New Issue
Block a user