我使用PyQt并在QTableView中显示数据表。我只是在寻找一种避免在屏幕上出现不超过100行的情况下将ENTIRE数据集调入内存的方法。从理论上讲,如果我只是检索可见数据,我几乎可以立即浏览包含数十万条记录的表格。
据我了解,当QTableView想要显示一个数据单元格时,它会调用" data()"我的表模型的功能(其子类QAbstractTableModel)。该函数接收应该显示的单元格的行和列索引。如果我已经加载了我需要的所有数据,这对我很有用。
但如果我还没有获得所有数据,那么我不得不对每个单元格进行查询吗?还有另一种方法吗?也许有一种逐行而不是逐个单元地获取数据的方法。也许我们正在使用MySql的数据库特定解决方案。
答案 0 :(得分:2)
这绝对可行。我使用这种技术滚动数十万甚至几十万行的pandas表,没有任何障碍。就像你说的那样,你需要使用QAbstractTableModel将数据子类化。
代码看起来很大但这里的关键是要记住代码的主要部分是"数据"为每个可见数据单元调用。
类似于:
class MyTableModel(QAbstractTableModel):
def __init__(self, datain, headerdata, parent=None, *args):
QAbstractTableModel.__init__(self, parent, *args)
self.arraydata = datain
self.headerdata = headerdata
def rowCount(self, parent):
return len(self.arraydata)
def columnCount(self, parent):
return len(self.arraydata[0])
def data(self, index, role):
if not index.isValid():
return QVariant()
elif role == Qt.TextAlignmentRole:
return QVariant(Qt.AlignRight | Qt.AlignVCenter)
elif role == Qt.DisplayRole:
return QVariant(str(self.arraydata[index.row()][index.column()]))
return QVariant()
活动小部件将是QWidget的子类,其中__init__
类似于:
class DbsVarWindow(QWidget):
"""Display a Qt window of a Zacks Dbs Var. inputs:
* fname file name (full path) of the dbs file
* vname var name (openvest munged name' to display"""
def __init__(self, fname, vname, *args):
QWidget.__init__(self, *args)
dbs = ZacksDbs(fname)
vals = dbs.get(vname)#[:,:10]
tickers = dbs.get('ticker')
# set the title
self.setWindowTitle(vname)
# set the minimum size
self.resize(800, 600)
# set the model and table view settings
tablemodel = MyTableModel(vals,tickers, self)
tableview = QTableView()
# try some sorting
tableview.setSortingEnabled(True)
# allow drag to rearrange columns
tableview.horizontalHeader().setMovable(True)
tableview.setModel(tablemodel)
# set the font
font = QFont("Courier", 12, 1)
tableview.setFont(font)
layout = QVBoxLayout(self)
layout.addWidget(tableview)
self.setLayout(layout)
self.show()
tableview.setModel(tablemodel)
行是将数据(tablemodel)挂钩到窗口小部件的内容。
如果代码太多,请道歉。这与我可以刮掉的一个典型的例子很接近。