PyQt实现懒加载

PyQt通过 QStackedLayout/Dict 实现懒加载
参见项目示例
github
gitee

问题

为了学习PyQt,新建了个练手项目,每一个小主题一个tab页。
部分页面初始化时,需要Http请求、绘制图表,耗时较长。随着页面的增多,加载越来越慢。

原实现方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

class TabPane(QFrame):
def __init__(self, buttonNameTuple, parent=None):
super().__init__(parent)
self.mainStackedLayout = QStackedLayout(self)
self.mainStackedLayout.setContentsMargins(0, 0, 0, 0)
for i in range(len(buttonNameTuple)):
page = self.__pageFactory(buttonNameTuple[i][1]) #注意1
self.mainStackedLayout.addWidget(page) #注意2

self.setLayout(self.mainStackedLayout)

def setCurrentIndex(self, index):
self.mainStackedLayout.setCurrentIndex(index)

  1. 通过工厂函数__pageFactory()产生页面示例,详见python 反射实现简单工厂/python 反射实现简单工厂
  2. 初始化时,将每个页面都构建并添加到QStackedLayout中。随着页面的增多,加载越来越慢。

之前写WPF时,用到过一个叫做懒加载Lazy<T>的东西,受其启发,自己写了个LazyTabPane

懒加载(LazyTabPane)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23

class LazyTabPane(QFrame):
def __init__(self, firstPageName, parent=None):
super().__init__(parent)
self.__mainStackedLayout = QStackedLayout(self)
self.__mainStackedLayout.setContentsMargins(0, 0, 0, 0)
self.__pageDict = {}
self.__addWidget(firstPageName)
self.setLayout(self.__mainStackedLayout)

def setCurrentPage(self, pageName):
pageIndex = self.__pageDict.get(pageName, -1)
if pageIndex == -1:
self.__addWidget(pageName)
pageIndex = self.__pageDict.get(pageName)

self.__mainStackedLayout.setCurrentIndex(pageIndex)

def __addWidget(self, pageName):
page = self.__pageFactory(pageName)
self.__pageDict[pageName] = self.__mainStackedLayout.count()
self.__mainStackedLayout.addWidget(page)

  1. 只初始化第一个页面
  2. 当调用setCurrentPage()切换其他页面时,判断__pageDict中是否已存有盖页面,如果没有则通过工厂函数创建该页面。然后求出该页面的索引并切换到该页。
  3. __pageDict中所存的索引和界面上的顺序不同。