QListWidget自定义Item并拖拽
This commit is contained in:
parent
27ef6536fb
commit
08281da545
4 changed files with 276 additions and 0 deletions
|
@ -21,6 +21,7 @@ encoding//QGraphicsView\u7EC3\u4E60/\u7B80\u5355\u56FE\u50CF\u5904\u7406/SimpleI
|
|||
encoding//QGraphicsView\u7EC3\u4E60/\u7B80\u5355\u56FE\u50CF\u5904\u7406/SimpleImageView.py=utf-8
|
||||
encoding//QListView/\u663E\u793A\u81EA\u5B9A\u4E49Widget.py=utf-8
|
||||
encoding//QListView/\u663E\u793A\u81EA\u5B9A\u4E49Widget\u5E76\u6392\u5E8F.py=utf-8
|
||||
encoding//QListWidget\u81EA\u5B9A\u4E49Item\u5E76\u62D6\u62FD/DragListWidget.py=utf-8
|
||||
encoding//QRC\u8D44\u6E90\u6587\u4EF6\u4F7F\u7528/qrctest1.py=utf-8
|
||||
encoding//QRC\u8D44\u6E90\u6587\u4EF6\u4F7F\u7528/qrctest2.py=utf-8
|
||||
encoding//QRC\u8D44\u6E90\u6587\u4EF6\u4F7F\u7528/res_rc.py=utf-8
|
||||
|
|
192
QListWidget自定义Item并拖拽/DragListWidget.py
Normal file
192
QListWidget自定义Item并拖拽/DragListWidget.py
Normal file
|
@ -0,0 +1,192 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Created on 2018年9月14日
|
||||
@author: Irony
|
||||
@site: https://github.com/892768447
|
||||
@email: 892768447@qq.com
|
||||
@file: DragListWidget
|
||||
@description:
|
||||
"""
|
||||
from PyQt5.QtCore import Qt, QSize, QRect, QPoint
|
||||
from PyQt5.QtGui import QColor, QPixmap, QDrag, QPainter, QCursor
|
||||
from PyQt5.QtWidgets import QListWidget, QListWidgetItem, QLabel, QRubberBand
|
||||
|
||||
|
||||
__Author__ = """By: Irony
|
||||
QQ: 892768447
|
||||
Email: 892768447@qq.com"""
|
||||
__Copyright__ = "Copyright (c) 2018 Irony"
|
||||
__Version__ = "Version 1.0"
|
||||
|
||||
|
||||
class DropListWidget(QListWidget):
|
||||
# 可以拖进来的QListWidget
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DropListWidget, self).__init__(*args, **kwargs)
|
||||
self.resize(400, 400)
|
||||
self.setAcceptDrops(True)
|
||||
# 设置从左到右、自动换行、依次排列
|
||||
self.setFlow(self.LeftToRight)
|
||||
self.setWrapping(True)
|
||||
self.setResizeMode(self.Adjust)
|
||||
# item的间隔
|
||||
self.setSpacing(5)
|
||||
|
||||
def makeItem(self, size, cname):
|
||||
item = QListWidgetItem(self)
|
||||
item.setData(Qt.UserRole + 1, cname) # 把颜色放进自定义的data里面
|
||||
item.setSizeHint(size)
|
||||
label = QLabel(self) # 自定义控件
|
||||
label.setMargin(2) # 往内缩进2
|
||||
label.resize(size)
|
||||
pixmap = QPixmap(size.scaled(96, 96, Qt.IgnoreAspectRatio)) # 调整尺寸
|
||||
pixmap.fill(QColor(cname))
|
||||
label.setPixmap(pixmap)
|
||||
self.setItemWidget(item, label)
|
||||
|
||||
def dragEnterEvent(self, event):
|
||||
mimeData = event.mimeData()
|
||||
if not mimeData.property('myItems'):
|
||||
event.ignore()
|
||||
else:
|
||||
event.acceptProposedAction()
|
||||
|
||||
def dropEvent(self, event):
|
||||
# 获取拖放的items
|
||||
items = event.mimeData().property('myItems')
|
||||
event.accept()
|
||||
for item in items:
|
||||
# 取出item里的data并生成item
|
||||
self.makeItem(QSize(100, 100), item.data(Qt.UserRole + 1))
|
||||
|
||||
|
||||
class DragListWidget(QListWidget):
|
||||
# 可以往外拖的QListWidget
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(DragListWidget, self).__init__(*args, **kwargs)
|
||||
self.resize(400, 400)
|
||||
# 隐藏横向滚动条
|
||||
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
# 不能编辑
|
||||
self.setEditTriggers(self.NoEditTriggers)
|
||||
# 开启拖功能
|
||||
self.setDragEnabled(True)
|
||||
# 只能往外拖
|
||||
self.setDragDropMode(self.DragOnly)
|
||||
# 忽略放
|
||||
self.setDefaultDropAction(Qt.IgnoreAction)
|
||||
# ****重要的一句(作用是可以单选,多选。Ctrl、Shift多选,可从空白位置框选)****
|
||||
# ****不能用ExtendedSelection,因为它可以在选中item后继续框选会和拖拽冲突****
|
||||
self.setSelectionMode(self.ContiguousSelection)
|
||||
# 设置从左到右、自动换行、依次排列
|
||||
self.setFlow(self.LeftToRight)
|
||||
self.setWrapping(True)
|
||||
self.setResizeMode(self.Adjust)
|
||||
# item的间隔
|
||||
self.setSpacing(5)
|
||||
# 橡皮筋(用于框选效果)
|
||||
self._rubberPos = None
|
||||
self._rubberBand = QRubberBand(QRubberBand.Rectangle, self)
|
||||
|
||||
self.initItems()
|
||||
|
||||
# 实现拖拽的时候预览效果图
|
||||
# 这里演示拼接所有的item截图(也可以自己写算法实现堆叠效果)
|
||||
def startDrag(self, supportedActions):
|
||||
items = self.selectedItems()
|
||||
drag = QDrag(self)
|
||||
mimeData = self.mimeData(items)
|
||||
# 由于QMimeData只能设置image、urls、str、bytes等等不方便
|
||||
# 这里添加一个额外的属性直接把item放进去,后面可以根据item取出数据
|
||||
mimeData.setProperty('myItems', items)
|
||||
drag.setMimeData(mimeData)
|
||||
pixmap = QPixmap(self.viewport().visibleRegion().boundingRect().size())
|
||||
pixmap.fill(Qt.transparent)
|
||||
painter = QPainter()
|
||||
painter.begin(pixmap)
|
||||
for item in items:
|
||||
rect = self.visualRect(self.indexFromItem(item))
|
||||
painter.drawPixmap(rect, self.viewport().grab(rect))
|
||||
painter.end()
|
||||
drag.setPixmap(pixmap)
|
||||
drag.setHotSpot(self.viewport().mapFromGlobal(QCursor.pos()))
|
||||
drag.exec_(supportedActions)
|
||||
|
||||
def mousePressEvent(self, event):
|
||||
# 列表框点击事件,用于设置框选工具的开始位置
|
||||
super(DragListWidget, self).mousePressEvent(event)
|
||||
if event.buttons() != Qt.LeftButton or self.itemAt(event.pos()):
|
||||
return
|
||||
self._rubberPos = event.pos()
|
||||
self._rubberBand.setGeometry(QRect(self._rubberPos, QSize()))
|
||||
self._rubberBand.show()
|
||||
|
||||
def mouseReleaseEvent(self, event):
|
||||
# 列表框点击释放事件,用于隐藏框选工具
|
||||
super(DragListWidget, self).mouseReleaseEvent(event)
|
||||
self._rubberPos = None
|
||||
self._rubberBand.hide()
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
# 列表框鼠标移动事件,用于设置框选工具的矩形范围
|
||||
super(DragListWidget, self).mouseMoveEvent(event)
|
||||
if self._rubberPos:
|
||||
pos = event.pos()
|
||||
lx, ly = self._rubberPos.x(), self._rubberPos.y()
|
||||
rx, ry = pos.x(), pos.y()
|
||||
size = QSize(abs(rx - lx), abs(ry - ly))
|
||||
self._rubberBand.setGeometry(
|
||||
QRect(QPoint(min(lx, rx), min(ly, ry)), size))
|
||||
|
||||
def makeItem(self, size, cname):
|
||||
item = QListWidgetItem(self)
|
||||
item.setData(Qt.UserRole + 1, cname) # 把颜色放进自定义的data里面
|
||||
item.setSizeHint(size)
|
||||
label = QLabel(self) # 自定义控件
|
||||
label.setMargin(2) # 往内缩进2
|
||||
label.resize(size)
|
||||
pixmap = QPixmap(size.scaled(96, 96, Qt.IgnoreAspectRatio)) # 调整尺寸
|
||||
pixmap.fill(QColor(cname))
|
||||
label.setPixmap(pixmap)
|
||||
self.setItemWidget(item, label)
|
||||
|
||||
def initItems(self):
|
||||
size = QSize(100, 100)
|
||||
for cname in QColor.colorNames():
|
||||
self.makeItem(size, cname)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
app = QApplication(sys.argv)
|
||||
app.setStyleSheet("""QListWidget {
|
||||
outline: 0px;
|
||||
background-color: transparent;
|
||||
}
|
||||
QListWidget::item:selected {
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(0, 170, 255);
|
||||
}
|
||||
QListWidget::item:selected:!active {
|
||||
border-radius: 2px;
|
||||
border: 1px solid transparent;
|
||||
}
|
||||
QListWidget::item:selected:active {
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(0, 170, 255);
|
||||
}
|
||||
QListWidget::item:hover {
|
||||
border-radius: 2px;
|
||||
border: 1px solid rgb(0, 170, 255);
|
||||
}"""
|
||||
)
|
||||
wa = DragListWidget()
|
||||
wa.show()
|
||||
wo = DropListWidget()
|
||||
wo.show()
|
||||
sys.exit(app.exec_())
|
83
QListWidget自定义Item并拖拽/README.md
Normal file
83
QListWidget自定义Item并拖拽/README.md
Normal file
|
@ -0,0 +1,83 @@
|
|||
# QListWidget 拖拽、框选
|
||||
|
||||
```python
|
||||
# 隐藏横向滚动条
|
||||
self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
|
||||
# 不能编辑
|
||||
self.setEditTriggers(self.NoEditTriggers)
|
||||
# 开启拖功能
|
||||
self.setDragEnabled(True)
|
||||
# 只能往外拖
|
||||
self.setDragDropMode(self.DragOnly)
|
||||
# 忽略放
|
||||
self.setDefaultDropAction(Qt.IgnoreAction)
|
||||
# ****重要的一句(作用是可以单选,多选。Ctrl、Shift多选,可从空白位置框选)****
|
||||
# ****不能用ExtendedSelection,因为它可以在选中item后继续框选会和拖拽冲突****
|
||||
self.setSelectionMode(self.ContiguousSelection)
|
||||
# 设置从左到右、自动换行、依次排列
|
||||
self.setFlow(self.LeftToRight)
|
||||
self.setWrapping(True)
|
||||
self.setResizeMode(self.Adjust)
|
||||
# item的间隔
|
||||
self.setSpacing(5)
|
||||
# 橡皮筋(用于框选效果)
|
||||
self._rubberPos = None
|
||||
self._rubberBand = QRubberBand(QRubberBand.Rectangle, self)
|
||||
```
|
||||
|
||||
## 拖动Item
|
||||
```python
|
||||
# 实现拖拽的时候预览效果图
|
||||
# 这里演示拼接所有的item截图(也可以自己写算法实现堆叠效果)
|
||||
def startDrag(self, supportedActions):
|
||||
items = self.selectedItems()
|
||||
drag = QDrag(self)
|
||||
mimeData = self.mimeData(items)
|
||||
# 由于QMimeData只能设置image、urls、str、bytes等等不方便
|
||||
# 这里添加一个额外的属性直接把item放进去,后面可以根据item取出数据
|
||||
mimeData.setProperty('myItems', items)
|
||||
drag.setMimeData(mimeData)
|
||||
pixmap = QPixmap(self.viewport().visibleRegion().boundingRect().size())
|
||||
pixmap.fill(Qt.transparent)
|
||||
painter = QPainter()
|
||||
painter.begin(pixmap)
|
||||
for item in items:
|
||||
rect = self.visualRect(self.indexFromItem(item))
|
||||
painter.drawPixmap(rect, self.viewport().grab(rect))
|
||||
painter.end()
|
||||
drag.setPixmap(pixmap)
|
||||
drag.setHotSpot(self.viewport().mapFromGlobal(QCursor.pos()))
|
||||
drag.exec_(supportedActions)
|
||||
```
|
||||
|
||||
## 模拟框选
|
||||
```python
|
||||
def mousePressEvent(self, event):
|
||||
# 列表框点击事件,用于设置框选工具的开始位置
|
||||
super(DragListWidget, self).mousePressEvent(event)
|
||||
if event.buttons() != Qt.LeftButton or self.itemAt(event.pos()):
|
||||
return
|
||||
self._rubberPos = event.pos()
|
||||
self._rubberBand.setGeometry(QRect(self._rubberPos, QSize()))
|
||||
self._rubberBand.show()
|
||||
|
||||
def mouseReleaseEvent(self, event):
|
||||
# 列表框点击释放事件,用于隐藏框选工具
|
||||
super(DragListWidget, self).mouseReleaseEvent(event)
|
||||
self._rubberPos = None
|
||||
self._rubberBand.hide()
|
||||
|
||||
def mouseMoveEvent(self, event):
|
||||
# 列表框鼠标移动事件,用于设置框选工具的矩形范围
|
||||
super(DragListWidget, self).mouseMoveEvent(event)
|
||||
if self._rubberPos:
|
||||
pos = event.pos()
|
||||
lx, ly = self._rubberPos.x(), self._rubberPos.y()
|
||||
rx, ry = pos.x(), pos.y()
|
||||
size = QSize(abs(rx - lx), abs(ry - ly))
|
||||
self._rubberBand.setGeometry(
|
||||
QRect(QPoint(min(lx, rx), min(ly, ry)), size))
|
||||
```
|
||||
|
||||
## 截图
|
||||
![截图](ScreenShot/1.gif)
|
BIN
QListWidget自定义Item并拖拽/ScreenShot/1.gif
Normal file
BIN
QListWidget自定义Item并拖拽/ScreenShot/1.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 168 KiB |
Loading…
Reference in a new issue