Skip to content

UI基本功能封装包

Funcs模块基于Modules.UI中的QUIControlFuntion扩展实现

  • UI.Funcs 为UI提供更多扩展功能 以便高效的完成项目开发/维护

  • QuModLibs内置的UI功能类均不需要手动管理释放问题 遵循即开即用

class QGridAdapter

网格适配器

基于QGridData的封装实现 允许您动态的为控件添加网格更新监听

python
# -*- coding: utf-8 -*-
from QuModLibs.Modules.UI.Funcs import QGridAdapter

uiNode = ...	# ui实例对象self
adapter = QGridAdapter(uiNode, "/panel/xxx", isScrollGrid=False, bindFunc = lambda *_: None, bindGridConName = "", bindUpdateBeforeFunc = lambda *_: None, bindUpdateFinishFunc = lambda *_: None)
"""
    @uiNode - 绑定的UI节点
    @isScrollGrid - 按网格列表计算(即列表直接引用网格的控件关系)
    @bindFunc - 绑定关联func(viewPath: str, i: int) -> None
    @bindGridConName - 设置绑定网格控件名称 (基于pos计算算法 如果您的控件本身带有数字结尾需设置该属性)
    @bindUpdateBeforeFunc - 绑定更新前触发func() -> None
    @bindUpdateFinishFunc - 绑定更新完毕触发func() -> None
"""
adapter.init()	# 初始化启动
adapter.setGridDimension((2, 2))	# 设置网格大小(初始化后才可以设置)

# adapter.updateRender()	立即刷新渲染(仅可见区域的控件)将会重新执行绑定的函数 实现状态改变处理


"""
绑定函数触发时机:
    bindFunc 每个控件进入渲染状态时分别代入执行
    bindUpdateBeforeFunc 每轮更新前执行 在bindFunc之前(更新时会一次性渲染多个控件触发多个bindFunc此功能触发单位为轮次而不是单次)
    bindUpdateFinishFunc 同bindUpdateBeforeFunc 区别于在此之后执行
"""

该功能和UI类提供的适配器注解功能类似 其中实现算法略微不同 更多的是给与可控管理 相比固定的绑定您可以随时销毁适配器

使用案例

基于QGridAdapter实现原生网格功能绑定

python
# -*- coding: utf-8 -*-
from QuModLibs.UI import EasyScreenNodeCls
from QuModLibs.Modules.UI.Funcs import QGridAdapter

class CustomData:
    """ 自定义数据类型 以便数据关联绑定网格渲染 """
    def __init__(self, text="", img=""):
        self.text = text
        self.img = img

@EasyScreenNodeCls.Binding("testUI4.main")
class TEST_UI4(EasyScreenNodeCls):
    def __init__(self):
        self.dataList = [
            CustomData("Hello", "..."),
            CustomData("World", "...")
        ]
        self.gridAdapter = QGridAdapter(self, "/panel/scroll_view", True, bindFunc=self.renderView)
        # 创建网格适配器 并初始化
        self.gridAdapter.init()
        self.gridAdapter.setGridDimension((1, len(self.dataList)))     		# 设置网格内容关联dataList大小 
    
    def renderView(self, viewPath="", index=0):
        data = self.dataList[index]		# 读取关联的数据
        self.GetBaseUIControl(viewPath+"/text").asLabel().SetText(data.text)
        self.GetBaseUIControl(viewPath+"/img").asImage().SetSprite(data.img)

网格的渲染机制是异步可视范围渲染, 通过适配器建立UI异步渲染与数据对象的绑定关系 以便实现高性能网格列表处理

class QVirtualGridManager 实验性

虚拟网格管理器

基于QGridAdapter封装的自动资源托管 允许您像常规控件一样操作(而不是异步监听)并由内部自动完成异步处理

python
# -*- coding: utf-8 -*-
from QuModLibs.UI import EasyScreenNodeCls
from QuModLibs.Modules.UI.Funcs import QVirtualGridManager

@EasyScreenNodeCls.Binding("testUI4.main")
class TEST_UI4(EasyScreenNodeCls):
    def __init__(self):
        self.virtualGrid = QVirtualGridManager(self, "/panel/scroll_view", True)    # 创建虚拟网格管理对象
        
        def createClickFun(text=""):
            """ 创建点击执行的函数 使用闭包完成 """
            def _click():
                print(text)
            return _click
        
        for text in ["你好", "世界", "KID", "DIK", "Test1"]:
            virtualCon = self.virtualGrid.addVirtualControl()           # 添加虚拟控件
            virtualCon.button.setBindClickFun(createClickFun(text))   	# 设置点击逻辑
            virtualCon.getChild("/text").label.text = text				# 设置文本内容
        self.virtualGrid.setGridWidth(3)	# 设置宽度大小排版
        self.virtualGrid.init() 			# 初始化加载
        # 如若在运行过程中修改了虚拟控件对象 可发起更新并重新计算
        # self.virtualGrid.updateRender()

传统网格的处理方案有多种 常见的如:

  1. 延迟固定时间等待全部渲染完毕再设置数据 (缺乏实时性且不适合列表网格翻页)
  2. 动态添加控件绘制网格状排版 (异步与可视控件判定不好解决 性能开销巨大)
  3. 原版绑定器 (QuModLibs中对应替代为适配器)

虚拟网格对象管理器 将所有控件信息储存并由内部完成管理适配器对接渲染逻辑 简化开发操作的同时尽可能接近原生性能

Released under the BSD3 License