QListWidget 自定义滑块 实现动态加载item

在python2和PySide2环境下可以直接运行(除了resource是资源文件(不提供),只是加载了一个图标给Item对象)

VerticalWheelThread只是在滚动滚轮的时候用了一个Qthread实现滚动动画效果

ListWidget对象在初始化的时候重新指定滑块为自定义的滑块对象ScrollBar

ScrollBar的valueChanged信号更新max_page从而使ListWidget实现动态添加Item

#!/usr/bin/env python27
# -*- coding: utf-8 -*-
import time
import math
from PySide2.QtWidgets import *
from PySide2.QtGui import *
from PySide2.QtCore import *
import resource
 
 
class VerticalWheelThread(QThread):
    delta_val = Signal(int)
 
    def __init__(self, parent):
        super(VerticalWheelThread, self).__init__()
        self.delta = 0
        self.direct = 1
        self.delta_val.connect(parent.set_value)
 
    def set_delta(self, delta):
        self.delta = delta
        self.direct = 1 if self.delta > 0 else -1
 
    def run(self):
        # 每1毫秒移动一个像素,实现滚轮动画效果
        for i in range(abs(self.delta)):
            time.sleep(0.001)
            self.delta_val.emit(self.direct)
 
 
class ScrollBar(QScrollBar):
 
    def __init__(self, parent):
        super(ScrollBar, self).__init__(parent)
        self.parent_wid = parent
        self.max_page = 0
        self.current_page = 1
        self.document_length = 0
        self.wheel_thread = VerticalWheelThread(self)
        self.valueChanged.connect(self.value_changed)
 
    def gridSize(self):
        return self.parent_wid.gridSize()
 
    def gridWidth(self):
        return self.gridSize().width()
 
    def gridHeight(self):
        return self.gridSize().height()
 
    def rowCount(self):
        return self.parent_wid.rowCount()
 
    def colCount(self):
        return self.parent_wid.colCount()
 
    def itemCount(self):
        return self.parent_wid.count()
 
    def rectAreaHeight(self):
        return self.parent_wid.rect().height()
 
    def rectAreaWidth(self):
        return self.parent_wid.rect().width()
 
    def documentRowCount(self):
        _height = self.rectAreaHeight() + self.document_length
        return int(math.ceil(float(_height) / float(self.gridHeight())))
 
    def update_page(self):
        _count = self.rowCount() * self.colCount()
        _item_count = self.itemCount()
        if _item_count == 0:
            self.max_page = 0
        elif _item_count <= _count:
            self.max_page = 1
        else:
            self.max_page = _item_count/_count + 1 if (_item_count % _count) else _item_count/_count
 
        self.current_page = int(math.ceil(float(self.documentRowCount()) / float(self.rowCount())))
        if self.current_page == self.max_page or self.document_length == self.maximum():
            self.parent_wid.update_list(self.max_page+1)
 
    def value_changed(self, value):
        self.document_length = value
        self.update_page()
 
    def set_value(self, value):
        val = max(0, self.value() - value)
        self.setValue(val)
 
    def wheelEvent(self, event):
        delta = event.delta()
        self.wheel_thread.set_delta(delta)
        self.wheel_thread.start()
 
 
class ListWidget(QListWidget):
    def __init__(self, parent):
        super(ListWidget, self).__init__(parent)
        self.assets_data = [str(x).zfill(4) for x in range(100000)]
        self.initUi()
 
    def initUi(self):
        self.setSizePolicy(QSizePolicy.Expanding, QSizePolicy.Expanding)
        self.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOff)
        self.setVerticalScrollBarPolicy(Qt.ScrollBarAsNeeded)
        scroll_bar = ScrollBar(self)
        self.setVerticalScrollBar(scroll_bar)
        self.setViewMode(QListWidget.IconMode)
        self.setIconSize(QSize(192, 108))
        self.setContentsMargins(0, 0, 0, 0)
        self.setGridSize(QSize(200, 138))
        self.setResizeMode(self.Adjust)
        self.setFlow(self.LeftToRight)
 
    def init_list(self):
        row = int(math.floor(float(self.parent().width()) / float(self.gridSize().width())))
        col = int(math.floor(float(self.parent().height()) / float(self.gridSize().height())))
        for i in range(min(2 * row * col, len(self.assets_data))):
            self.addItem(Item(self.assets_data[i]))
 
    def update_list(self, page):
        _count = self.rowCount() * self.colCount()
        items_count = self.count()
        for i in range(min(_count * page, len(self.assets_data))):
            if i < items_count:
                continue
            self.addItem(Item(self.assets_data[i]))
 
    def colCount(self):
        rect_width = self.rect().width()
        grid_width = self.gridSize().width()
        return int(math.floor(float(rect_width) / float(grid_width)))
 
    def rowCount(self):
        rect_height = self.rect().height()
        grid_height = self.gridSize().height()
        return int(math.ceil(float(rect_height) / float(grid_height)))
 
    def resizeEvent(self, event):
        super(ListWidget, self).resizeEvent(event)
 
 
class Item(QListWidgetItem):
    def __init__(self, text):
        super(Item, self).__init__()
        self.setIcon(QIcon(':/resources/folder.png'))
        self.setText(text)
        self.setSizeHint(QSize(192, 130))
        self.setTextAlignment(Qt.AlignBottom | Qt.AlignHCenter)
 
 
class Dlg(QDialog):
    def __init__(self, parent=None):
        super(Dlg, self).__init__(parent)
        self.resize(1280, 720)
        self.move(500, 200)
        layout1 = QVBoxLayout(self)
        layout1.setContentsMargins(0, 0, 0, 0)
        layout1.setSpacing(0)
        self.list_widget = ListWidget(self)
        layout1.addWidget(self.list_widget)
        self.list_widget.init_list()
 
 
if __name__ == '__main__':
    import sys
    app = QApplication(sys.argv)
    ui = Dlg()
    ui.show()
    sys.exit(app.exec_())
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值