zhiyiYo / PyQt-Fluent-Widgets

A fluent design widgets library based on C++ Qt/PyQt/PySide. Make Qt Great Again.
https://qfluentwidgets.com
GNU General Public License v3.0
5.61k stars 541 forks source link

[Bug]: 在StackedWidgets中嵌入数据量较大的TableView,页面切换出现卡顿 #805

Closed AlvnCapriSHEP closed 7 months ago

AlvnCapriSHEP commented 7 months ago

What happened?

在StackedWidget中添加TableView,表格行数较多时(>2000),StackedWidget切换当前页,有较为明显的卡顿;

推测 TableBase.showEvent() 中使用 resizeRowsToContents() 导致 ,数据量大时耗时较长;

也许让用户决定resize的调用时机会好一点?

Operation System

Windows10 22H2

Python Version

3.11.8

PyQt/PySide Version

PySide 6.6.2

PyQt/PySide-Fluent-Widgets Version

v1.5.3

How to Reproduce?

  1. Embedeed a TableView in a StackedWidget;
  2. Update model's data with rows above 1000;
  3. Switch StackedWidget's current page to other one, then switch it back;

Minimum code

# coding: utf-8
import sys
from PySide6.QtCore import Qt, QAbstractTableModel
from PySide6.QtWidgets import QApplication, QWidget, QHBoxLayout, QTableView
from qfluentwidgets import TableView, FluentWindow
from qfluentwidgets import FluentIcon as FIF

Test_Row_Count=2000

class testModel(QAbstractTableModel):
    def __init__(self, table_data):
        super(testModel, self).__init__()
        self.table_data = table_data  # 简单的二维列表

    def data(self, index, role):
        if role == Qt.DisplayRole:
            return self.table_data[index.row()][index.column()]

    def rowCount(self, index):
        return len(self.table_data)

    def columnCount(self, index):
        return len(self.table_data[0])

class TableView_NoRowResize(TableView):
    def __init__(self, parent=None):
        super().__init__(parent)

    def showEvent(self, e):
        QTableView.showEvent(self, e)
        # self.resizeRowsToContents()

class widget_page1(QWidget):

    def __init__(self):
        super().__init__()
        self.tableView = TableView(self)
        self.model = testModel([[str(i) for i in range(5)] for i in range(Test_Row_Count)])
        self.tableView.setModel(self.model)
        self.hBoxLayout = QHBoxLayout(self)
        self.hBoxLayout.addWidget(self.tableView)

class widget_page2(QWidget):

    def __init__(self):
        super().__init__()
        self.tableView = TableView_NoRowResize(self)  # showEvent()中取消对行resize
        self.model = testModel([[str(i) for i in range(5)] for i in range(Test_Row_Count)])
        self.tableView.setModel(self.model)
        self.hBoxLayout = QHBoxLayout(self)
        self.hBoxLayout.addWidget(self.tableView)

class Window(FluentWindow):  # page3切换至page1发生卡顿;page3切换至page2正常;

    def __init__(self):
        super().__init__()
        self.widget_page1 = widget_page1()
        self.widget_page1.setObjectName("page1")
        self.widget_page2 = widget_page2()
        self.widget_page2.setObjectName("page2")
        self.widget_page3 = QWidget()
        self.widget_page3.setObjectName("page3")
        self.addSubInterface(self.widget_page1, FIF.DOCUMENT, 'page1')
        self.addSubInterface(self.widget_page2, FIF.DOCUMENT, 'page2')
        self.addSubInterface(self.widget_page3, FIF.ROTATE, 'page3')

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = Window()
    w.show()
    app.exec()
rainzee commented 7 months ago

我会提交一个优化,判断总行数,如果大于 500 行,则只对可视部分进行调整。

rainzee commented 7 months ago

https://github.com/zhiyiYo/PyQt-Fluent-Widgets/assets/4585440/6f5a3d75-8b22-4dd5-8345-efcfb7b02ac2

https://github.com/zhiyiYo/PyQt-Fluent-Widgets/assets/4585440/966ea92e-f63b-4f00-9a8b-c4c57d26f4f5

这是优化前后的效果对比,应该符合你的预期

AlvnCapriSHEP commented 7 months ago

我会提交一个优化,判断总行数,如果大于 500 行,则只对可视部分进行调整。

收到,感谢;