使用QTableView和QAbstractTableModel的大型记录集 - 仅检索可见行

时间:2015-01-19 21:18:49

标签: python mysql qt pyqt

我使用PyQt并在QTableView中显示数据表。我只是在寻找一种避免在屏幕上出现不超过100行的情况下将ENTIRE数据集调入内存的方法。从理论上讲,如果我只是检索可见数据,我几乎可以立即浏览包含数十万条记录的表格。

据我了解,当QTableView想要显示一个数据单元格时,它会调用" data()"我的表模型的功能(其子类QAbstractTableModel)。该函数接收应该显示的单元格的行和列索引。如果我已经加载了我需要的所有数据,这对我很有用。

但如果我还没有获得所有数据,那么我不得不对每个单元格进行查询吗?还有另一种方法吗?也许有一种逐行而不是逐个单元地获取数据的方法。也许我们正在使用MySql的数据库特定解决方案。

1 个答案:

答案 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)挂钩到窗口小部件的内容。

如果代码太多,请道歉。这与我可以刮掉的一个典型的例子很接近。