删除自定义Item
This commit is contained in:
parent
badbbac675
commit
c092046a9d
5 changed files with 109 additions and 84 deletions
|
@ -24,6 +24,7 @@ encoding//\u5176\u5B83/\u81EA\u5B9A\u4E49import/src/test.py=utf-8
|
|||
encoding//\u5176\u5B83/\u81EA\u5B9A\u4E49\u5C5E\u6027\u6D4B\u8BD5/\u81EA\u5B9A\u4E49\u5C5E\u6027\u6D4B\u8BD5.py=utf-8
|
||||
encoding//\u5217\u8868/QListView/\u663E\u793A\u81EA\u5B9A\u4E49Widget.py=utf-8
|
||||
encoding//\u5217\u8868/QListView/\u663E\u793A\u81EA\u5B9A\u4E49Widget\u5E76\u6392\u5E8F.py=utf-8
|
||||
encoding//\u5217\u8868/QListWidget/\u5220\u9664\u81EA\u5B9A\u4E49Item.py=utf-8
|
||||
encoding//\u5217\u8868/QListWidget/\u817E\u8BAF\u89C6\u9891\u70ED\u64AD\u5217\u8868/TencentMovieHotPlay.py=utf-8
|
||||
encoding//\u5217\u8868/QListWidget/\u817E\u8BAF\u89C6\u9891\u70ED\u64AD\u5217\u8868/TencentMovieHotPlay_Flow.py=utf-8
|
||||
encoding//\u5217\u8868/QListWidget/\u817E\u8BAF\u89C6\u9891\u70ED\u64AD\u5217\u8868/TencentMovieHotPlay_ListWidget.py=utf-8
|
||||
|
|
|
@ -1,83 +0,0 @@
|
|||
# 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/ScreenShot/删除自定义Item.gif
Normal file
BIN
列表/QListWidget/ScreenShot/删除自定义Item.gif
Normal file
Binary file not shown.
After Width: | Height: | Size: 64 KiB |
99
列表/QListWidget/删除自定义Item.py
Normal file
99
列表/QListWidget/删除自定义Item.py
Normal file
|
@ -0,0 +1,99 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
"""
|
||||
Created on 2018年11月4日
|
||||
@author: Irony
|
||||
@site: https://pyqt5.com, https://github.com/892768447
|
||||
@email: 892768447@qq.com
|
||||
@file: 删除Item
|
||||
@description:
|
||||
"""
|
||||
from PyQt5.QtCore import QSize, pyqtSignal
|
||||
from PyQt5.QtWidgets import QWidget, QHBoxLayout, QLineEdit, QPushButton,\
|
||||
QListWidgetItem, QVBoxLayout, QListWidget
|
||||
|
||||
|
||||
__Author__ = """By: Irony
|
||||
QQ: 892768447
|
||||
Email: 892768447@qq.com"""
|
||||
__Copyright__ = 'Copyright (c) 2018 Irony'
|
||||
__Version__ = 1.0
|
||||
|
||||
|
||||
class ItemWidget(QWidget):
|
||||
|
||||
itemDeleted = pyqtSignal(QListWidgetItem)
|
||||
|
||||
def __init__(self, text, item, *args, **kwargs):
|
||||
super(ItemWidget, self).__init__(*args, **kwargs)
|
||||
self._item = item # 保留list item的对象引用
|
||||
layout = QHBoxLayout(self)
|
||||
layout.setContentsMargins(0, 0, 0, 0)
|
||||
layout.addWidget(QLineEdit(text, self))
|
||||
layout.addWidget(QPushButton('x', self, clicked=self.doDeleteItem))
|
||||
|
||||
def doDeleteItem(self):
|
||||
self.itemDeleted.emit(self._item)
|
||||
|
||||
def sizeHint(self):
|
||||
# 决定item的高度
|
||||
return QSize(200, 40)
|
||||
|
||||
|
||||
class Window(QWidget):
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(Window, self).__init__(*args, **kwargs)
|
||||
layout = QVBoxLayout(self)
|
||||
|
||||
# 列表
|
||||
self.listWidget = QListWidget(self)
|
||||
layout.addWidget(self.listWidget)
|
||||
|
||||
# 清空按钮
|
||||
self.clearBtn = QPushButton('清空', self, clicked=self.doClearItem)
|
||||
layout.addWidget(self.clearBtn)
|
||||
|
||||
# 添加测试数据
|
||||
self.testData()
|
||||
|
||||
def doDeleteItem(self, item):
|
||||
# 根据item得到它对应的行数
|
||||
row = self.listWidget.indexFromItem(item).row()
|
||||
# 删除item
|
||||
item = self.listWidget.takeItem(row)
|
||||
# 删除widget
|
||||
self.listWidget.removeItemWidget(item)
|
||||
del item
|
||||
|
||||
def doClearItem(self):
|
||||
# 清空所有Item
|
||||
for _ in range(self.listWidget.count()):
|
||||
# 删除item
|
||||
# 一直是0的原因是一直从第一行删,删掉第一行后第二行变成了第一行
|
||||
# 这个和删除list [] 里的数据是一个道理
|
||||
item = self.listWidget.takeItem(0)
|
||||
# 删除widget
|
||||
self.listWidget.removeItemWidget(item)
|
||||
del item
|
||||
|
||||
def testData(self):
|
||||
# 生成测试数据
|
||||
for i in range(100):
|
||||
item = QListWidgetItem(self.listWidget)
|
||||
widget = ItemWidget('item: {}'.format(i), item, self.listWidget)
|
||||
# 绑定删除信号
|
||||
widget.itemDeleted.connect(self.doDeleteItem)
|
||||
self.listWidget.setItemWidget(item, widget)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
import sys
|
||||
import cgitb
|
||||
sys.excepthook = cgitb.enable(1, None, 5, 'text')
|
||||
from PyQt5.QtWidgets import QApplication
|
||||
app = QApplication(sys.argv)
|
||||
w = Window()
|
||||
w.show()
|
||||
sys.exit(app.exec_())
|
|
@ -25,3 +25,11 @@
|
|||
2. 滚动条滑动到底部加载更多
|
||||
|
||||
![截图](QListWidget/腾讯视频热播列表/ScreenShot/1.gif)
|
||||
|
||||
### 3. [删除自定义Item](QListWidget/删除自定义Item.py)
|
||||
1. 删除item时先要通过`QListWidget.indexFromItem(item).row()`得到它的行数
|
||||
2. 通过`takeItem`函数取出该Item并删除掉,`item = self.listWidget.takeItem(row)`
|
||||
3. 移除item对应的自定义控件`self.listWidget.removeItemWidget(item)`
|
||||
4. 如果是清空所有Item,可以通过循环删除,但是删除的时候行号一直是0即可,原因和删除list数组一样。
|
||||
|
||||
![截图](QListWidget/ScreenShot/删除自定义Item.gif)
|
Loading…
Reference in a new issue