QTableWidget 可以有多少行或多少列?
Posted
技术标签:
【中文标题】QTableWidget 可以有多少行或多少列?【英文标题】:How many rows or columns can QTableWidget have? 【发布时间】:2019-11-13 03:37:08 【问题描述】:我想制作一个类似 Excel 的电子表格。 Excel 2010 有 1048576 行和 A - ZZZ 列。但在 Qt 中,如果应用程序的行数超过 7000~8000 行,应用程序就会崩溃。
这是一个错误,还是 Qt 的默认设置?当然,这种崩溃发生在较低版本上。你也遇到同样的问题吗?
示例代码:
from PySide2 import QtWidgets
import PySide2
import os
dirname = os.path.dirname(PySide2.__file__)
plugin_path = os.path.join(dirname, 'plugins', 'platforms')
os.environ['QT_QPA_PLATFORM_PLUGIN_PATH'] = plugin_path
import sys
import itertools
alphabet = ["A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T", "U", "V", "W", "X", "Y", "Z"]
alphabet2 =[i[0]+i[1] for i in itertools.product(alphabet, alphabet)]
alphabet3 =[i[0]+i[1] for i in itertools.product(alphabet, alphabet2)]
alphabet = alphabet + alphabet2 + alphabet3
EXCEL2010_ROW_MAX = 1048576
NOW_POSSIBLE_MAX = 7000
def main():
app = QtWidgets.QApplication([])
tablewidget = QtWidgets.QTableWidget()
tablewidget.setRowCount(EXCEL2010_ROW_MAX)
tablewidget.setColumnCount(len(alphabet))
tablewidget.setHorizontalHeaderLabels(alphabet)
tablewidget.show()
sys.exit(app.exec_())
if __name__ == "__main__":
main()
【问题讨论】:
【参考方案1】:这不是错误 - 您的计算机只是内存不足。
您的示例代码创建了一个包含超过 190 亿个单元格的表格 ((26¹ + 26² + 26³) * 1048576 = 19165872128
)。因此,除非您的计算机有几十 GB 的可用内存,否则它将无法加载它。假设 Excel 也不会尝试呈现该大小的 实际表格 似乎是安全的。即使它支持 virtual 最大大小为 1048576 行 x 16384 列,但这并不意味着您可以用数据填充每个单元格。您将始终受到系统上可用内存(和磁盘空间)数量的限制。
当您使用QTableWidget
或QStandardItemModel
等基于项目的便利类时,您无法避免这些限制,因为需要预先分配太多内存。因此,如果您想在 Qt 中模拟 Excel,则需要将 QTableView
与自定义模型一起使用。这允许您创建任意大小的虚拟表,因为 Qt 只会尝试渲染当前在视口中可见的单元格。
这是一个简单的演示:
import sys
from PySide2 import QtCore, QtWidgets
class CustomModel(QtCore.QAbstractItemModel):
def rowCount(self, *args):
return 1048576
def columnCount(self, *args):
return 163846
def index(self, *args):
return QtCore.QModelIndex()
app = QtWidgets.QApplication(sys.argv)
table = QtWidgets.QTableView()
model = CustomModel()
table.setModel(model)
table.show()
sys.exit(app.exec_())
有关如何实施自定义模型的更多详细信息,请参阅Model Subclassing Reference。
【讨论】:
天哪...QTreeWidget
和QListWidget
的情况是否相同?从您的回答中已经很清楚了。我打算在我的应用程序中使用这种小部件。 ..对于许多数据。我使用视图类比使用它们更好吗...?它会是这样。嗯。这似乎很困难。我会对QAbstractItemModel
的实现感到困惑。我试一试。谢谢。
@Haru 你真的,真的需要一个包含 190 亿 个单元格的电子表格吗?你不可能填写这么大的电子表格,那有什么意义呢?对于 95% 的用例,您将只需要 QTreeWidget
、QListWidget
、QSqlTableModel
、QStandardItemModel
等便利类。但便利是有代价的,当处理非常大的数据集时,代价通常是更高的内存使用和/或更低的性能。编写自定义模型可能需要大量工作,因此请先尝试便捷类,并提防过早的优化。
我的app是一种自助服务。用户可以根据需要添加数据。我无法预先看到累积。我也在考虑临时数据处理不是一次查看所有数据。但是……我觉得它需要8000多行,我觉得我需要为案子做准备……而且……如果我能实现QAbstractItemModel
,它有很好的机会学习它……是不是很难以实现“QAbstractItemModel”?
我想我会尝试添加数据,直到测试的内存限制。故事从那开始。
@Haru 问题不在于行,而在于列。将列减少到您实际需要的列(例如,最多 30 列),您将能够大大增加行数。以上是关于QTableWidget 可以有多少行或多少列?的主要内容,如果未能解决你的问题,请参考以下文章
使用 PyQt/PySide 禁用 QTableWidget 中特定列中的排序箭头