2014-04-01 22 views
6

Tôi siêu mới để lập trình Qt. Tôi đang cố gắng tạo một bảng đơn giản có thể có hàng được thêm bằng cách nhấp vào nút. Tôi có thể thực hiện các bảng tốt nhưng dường như không thể có được dữ liệu cập nhật để hiển thị trên bảng. Tôi tin rằng vấn đề của tôi bắt nguồn từ thực tế là tôi dường như không thể gọi bất kỳ phương thức "thay đổi dữ liệu" nào bằng cách sử dụng nút. Tôi đã thử một số giải pháp khác nhau trực tuyến, tất cả đều dẫn đến 4 năm, các bài đăng cuối cùng. Những gì tôi có cho đến nay là cấu trúc cơ bản, tôi chỉ không thể tìm ra cách làm cho bảng cập nhật với dữ liệu mới.PyQt: Thêm hàng vào QTableView bằng cách sử dụng QAbstractTableModel

Đây là quan điểm cơ bản

Tôi đã thiết lập với một số dữ liệu thử nghiệm.

Trong lần triển khai cuối cùng, bảng sẽ bắt đầu trống và tôi muốn nối thêm các hàng và hiển thị chúng trong chế độ xem bảng.

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

Cảm ơn bạn đã mã mẫu! Vô cùng hữu ích! – Hephaestus

+0

Đồng ý .. Mẫu mã trong câu hỏi của bạn là câu trả lời cho nhiều câu hỏi khác. –

Trả lời

3

Khi dữ liệu cơ bản của những thay đổi mô hình, mô hình được thải hoặc layoutChanged hoặc layoutAboutToBeChanged, để xem thông tin cập nhật đúng cách (có cũng dataChanged, nếu bạn muốn cập nhật một phạm vi cụ thể của các tế bào).

Vì vậy, bạn chỉ cần một cái gì đó như thế này:

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

Sẽ không đặtData() cũng cần thiết trong mô hình? Tôi đã xem qua tất cả các tài liệu và tôi tiếp tục thấy các tham chiếu cần phải có setData() hoặc insertRows(), v.v. Vấn đề là tôi không chắc chắn 100% cách triển khai phương thức setData() hoặc quan trọng hơn là làm thế nào để gọi nó đi. - EDIT: Vâng, tôi vừa thử chỉnh sửa của bạn và nó hoạt động hoàn hảo mà không có phương thức setData() vì vậy tôi đoán nó không cần thiết sau khi tất cả! Tôi thực sự đánh giá cao sự giúp đỡ! – user3439556

+0

Thông thường, bạn cần triển khai setData() khi bạn muốn có lưới chỉnh sửa, để cập nhật giá trị chính xác trong mô hình của bạn. Ví dụ: 'def setData (tự, chỉ mục, giá trị, vai trò = Qt.EditRole): nếu vai trò == Qt.EditRole: setattr (self.arraydata [index.row()], self.columns [index. cột()], giá trị) self.dataChanged.emit (chỉ mục, chỉ mục,()) trả về Đúng khác: trả về Sai' – TheGerm

Các vấn đề liên quan