2014-04-01 396 views
6

我是Qt編程的超級新手。我正在嘗試製作一個簡單的表格,通過單擊按鈕可以添加行。我可以很好地實現表格,但似乎無法獲取更新的數據以在表格中顯示。我相信我的問題源於這樣的事實:我似乎無法使用按鈕正確調用任何種類的「更改數據」方法。我在網上嘗試了幾種不同的解決方案,所有這些解決方案都導致了4年前的死衚衕。到目前爲止,我的基本結構是,我無法弄清楚如何使用新數據更新表格。PyQt:使用QAbstractTableModel將行添加到QTableView

這是基本的觀點

我已經設置了一些測試數據。

在最後的實現中,表將開始爲空,我想追加行並將它們顯示在表視圖中。

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_()) 
+1

謝謝你的示例代碼!非常有幫助! – Hephaestus

+0

同意..您的問題中的代碼示例是許多其他問題的答案。 –

回答

3

當更改模型的基礎數據,模型應發出任layoutChangedlayoutAboutToBeChanged,使視圖更新正確(有也是dataChanged,如果你想更新細胞的指定範圍內)。

所以,你只需要像這樣:

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

模型中不需要setData()嗎?我查看了所有的文檔,並且一直看到需要setData()或insertRows()等的引用。問題是我不是100%確定如何實現setData()方法,或者更重要的是如何實現叫它。 - 編輯︰嗯,我只是試過你的編輯,它沒有setData()方法完美的工作,所以我想這畢竟是不需要的!我非常感謝幫助! – user3439556

+0

通常,當需要可編輯網格時,需要實現setData()以更新模型中的正確值。例如: 'def setData(self,index,value,role = Qt.EditRole): if role == Qt.EditRole: setattr(self.arraydata [index.row()],self.columns [index。 column()],value) self.dataChanged.emit(index,index,()) return True else: return False' – TheGerm