PyQt:使用 QAbstractTableModel 向 QTableView 添加行 [英] PyQt: Adding rows to QTableView using QAbstractTableModel

查看:159
本文介绍了PyQt:使用 QAbstractTableModel 向 QTableView 添加行的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是 Qt 编程的新手.我正在尝试制作一个简单的表格,可以通过单击按钮添加行.我可以很好地实现表格,但似乎无法将更新的数据显示在表格上.我相信我的问题源于这样一个事实,即我似乎无法使用按钮正确调用任何类型的更改数据"方法.我在网上尝试了几种不同的解决方案,所有这些都导致了 4 岁的死胡同.到目前为止,我拥有的是基本结构,我只是不知道如何使用新数据更新表.

I am super new to Qt programming. I am trying to make a simple table that can have rows added by clicking a button. I can implement the table fine but can't seem to get the updated data to show on the table. I believe my problem stems from the fact that I can't seem to properly call any sort of "change data" method using the button. I've tried several different solutions online all of which have lead to 4 year old, dead-end posts. What I have so far is the basic structure, I just can't figure out how to make the table update with new data.

这是基本视图

我已经设置了一些测试数据.

I have set up with some test data.

在最终的实现中,表格将开始为空,我想追加行并将它们显示在表格视图中.

In the final implementation, the table will start empty and I would like to append rows and have them displayed in the table view.

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *

class MyWindow(QWidget):
    def __init__(self):
        QWidget.__init__(self)

        # create table
        self.get_table_data()
        self.table = self.createTable()

        # layout
        self.layout = QVBoxLayout()

        self.testButton = QPushButton("test")
        self.connect(self.testButton, SIGNAL("released()"), self.test)        

        self.layout.addWidget(self.testButton)
        self.layout.addWidget(self.table)
        self.setLayout(self.layout)

    def get_table_data(self):
        self.tabledata = [[1234567890,2,3,4,5],
                          [6,7,8,9,10],
                          [11,12,13,14,15],
                          [16,17,18,19,20]]

    def createTable(self):
        # create the view
        tv = QTableView()

        # set the table model
        header = ['col_0', 'col_1', 'col_2', 'col_3', 'col_4']
        tablemodel = MyTableModel(self.tabledata, header, self)
        tv.setModel(tablemodel)

        # set the minimum size
        tv.setMinimumSize(400, 300)

        # hide grid
        tv.setShowGrid(False)

        # hide vertical header
        vh = tv.verticalHeader()
        vh.setVisible(False)

        # set horizontal header properties
        hh = tv.horizontalHeader()
        hh.setStretchLastSection(True)

        # set column width to fit contents
        tv.resizeColumnsToContents()

        # set row height
        tv.resizeRowsToContents()

        # enable sorting
        tv.setSortingEnabled(False)

        return tv

    def test(self):
        self.tabledata.append([1,1,1,1,1])
        self.emit(SIGNAL('dataChanged()'))
        print 'success'

class MyTableModel(QAbstractTableModel):
    def __init__(self, datain, headerdata, parent=None):
        """
        Args:
            datain: a list of lists\n
            headerdata: a list of strings
        """
        QAbstractTableModel.__init__(self, parent)
        self.arraydata = datain
        self.headerdata = headerdata

    def rowCount(self, parent):
        return len(self.arraydata)

    def columnCount(self, parent):
        if len(self.arraydata) > 0: 
            return len(self.arraydata[0]) 
        return 0

    def data(self, index, role):
        if not index.isValid():
            return QVariant()
        elif role != Qt.DisplayRole:
            return QVariant()
        return QVariant(self.arraydata[index.row()][index.column()])

    def setData(self, index, value, role):
        pass         # not sure what to put here

    def headerData(self, col, orientation, role):
        if orientation == Qt.Horizontal and role == Qt.DisplayRole:
            return QVariant(self.headerdata[col])
        return QVariant()

    def sort(self, Ncol, order):
        """
        Sort table by given column number.
        """
        self.emit(SIGNAL("layoutAboutToBeChanged()"))
        self.arraydata = sorted(self.arraydata, key=operator.itemgetter(Ncol))       
        if order == Qt.DescendingOrder:
            self.arraydata.reverse()
        self.emit(SIGNAL("layoutChanged()"))

if __name__ == "__main__":
    app = QApplication(sys.argv)
    w = MyWindow()
    w.show()
    sys.exit(app.exec_())

推荐答案

当模型的底层数据发生变化时,模型应该发出 layoutChangedlayoutAboutToBeChanged,以便正确更新视图(还有 dataChanged,如果您想更新特定范围的单元格).

When the underlying data of the model changes, the model should emit either layoutChanged or layoutAboutToBeChanged, so that view updates properly (there's also dataChanged, if you want to update a specific range of cells).

所以你只需要这样的东西:

So you just need something like this:

    def test(self):
        self.tabledata.append([1,1,1,1,1])
        self.table.model().layoutChanged.emit()
        print 'success'

这篇关于PyQt:使用 QAbstractTableModel 向 QTableView 添加行的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆