PYQT 将Pandas/数据懒加载到QTableWidget上
也可以自己定义二维数组
参考博客 https://my.oschina.net/u/4405857/blog/3534796
完整版
上代码
df_widget.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2021/3/25 14:54
# @Author : Link
# @Site :
# @File : df_widget.py
# @Software: PyCharm
from PyQt5 import QtGui
from PyQt5.QtWidgets import QHBoxLayout, QTableWidget, QTableWidgetItem, QScrollBar, QWidget
from PyQt5.QtCore import Qt
from pandas import DataFrame, isnull
class dfQTable(QWidget):
rowCount = 0 # 单页可以显示的数据条数
df = DataFrame()
def __init__(self, *args):
super(dfQTable, self).__init__()
self.ui_setup()
self.signal_setup()
def ui_setup(self):
self.setGeometry(497, 200, 400, 300)
# 使用竖直Layout
self.horizontalLayout = QHBoxLayout(self)
# 建立一个QTableWidget
self.table = QTableWidget(self)
# self.table.verticalHeader().setStretchLastSection(True)
# 建立一个竖直QScrollBar
self.scrollbar = QScrollBar(self)
self.scrollbar.setOrientation(Qt.Vertical)
self.scrollbar.setSingleStep(1)
self.horizontalLayout.addWidget(self.table)
self.horizontalLayout.addWidget(self.scrollbar)
def signal_setup(self):
self.scrollbar.valueChanged.connect(self.scrollbar_emit)
def scrollbar_emit(self, e: int):
self.pdToQTableWidget()
def setDfData(self, df: DataFrame):
self.df = df
# 先计算 后预览
self.calculateRowCountParams()
self.pdToQTableWidget()
def calculateRowCountParams(self):
if any(self.df):
# 先计算
rowHeight = self.table.rowHeight(0)
rowHeight = 30 if rowHeight == 0 else rowHeight
tableHeight = self.table.height()
self.rowCount = int(tableHeight / rowHeight) - 1
# print("每页行数", self.rowCount, sep=":")
# 更新table的行数
self.table.setRowCount(self.rowCount)
# 滑块的长度
scrollbar_count = int(self.df.index.size / self.rowCount)
# print("滑块长度", scrollbar_count, sep=":")
self.scrollbar.setMaximum(scrollbar_count * 9)
def resizeEvent(self, a0: QtGui.QResizeEvent) -> None:
self.calculateRowCountParams()
self.pdToQTableWidget()
if a0:
super().resizeEvent(a0)
def pdToQTableWidget(self):
"""
更新页面数据
:return:
"""
if any(self.df):
df_columns = self.df.columns.size
df_header = self.df.columns.values.tolist()
self.table.setColumnCount(df_columns)
self.table.setHorizontalHeaderLabels(df_header)
start_row = int(self.scrollbar.value() / 9 * self.rowCount)
end_row = int((self.scrollbar.value() / 9 + 1) * self.rowCount)
# 数据预览窗口
for row in range(start_row, end_row):
for column in range(df_columns):
value = ''
if row < self.df.index.size:
value = '' if isnull(self.df.iloc[row, column]) else str(self.df.iloc[row, column])
tempItem = QTableWidgetItem(value)
self.table.setItem((row - start_row), column, tempItem)
self.table.item((row - start_row), column).setTextAlignment(Qt.AlignHCenter | Qt.AlignVCenter)
main.py
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
# @Time : 2021/3/25 14:54
# @Author : Link
# @Site :
# @File : main.py
# @Software: PyCharm
import sys
from PyQt5.QtWidgets import QApplication
from faker import Faker # pip install Faker
import pandas as pd
fake = Faker()
from df_widget import dfQTable
te_data = []
for index in range(1,50000):
te_data.append({
"ColumnOne":index,
"ColumnTwo":fake.word(),
"ColumnThree":fake.word(),
"ColumnFour":fake.word(),
"ColumnFive":fake.word(),
"ColumnSix":fake.word(),
"ColumnSeven":fake.word(),
})
print(f'{index}/500000')
df = pd.DataFrame(te_data)
print("start")
app = QApplication(sys.argv)
myWin = dfQTable()
myWin.show()
myWin.setDfData(df)
sys.exit(app.exec_())