2013-07-17 22 views
12

私はPyQtテーブルにpandasデータフレームを表示したいと思います。私はこれでいくつかの進歩を遂げましたが、Table Modelクラスを正しく導出できませんでした。これについてのどんな助けも大いに感謝されるでしょう。PyQt - QTableViewに表示するQAbstractTableModelを実装します。

**完全なコード例here注**

私は、有効なQtCore.QAbstractTableModel派生クラスを生成するのに苦労しています。 QItemDelegatesに関する以前の質問から、実際のデータを挿入するためにPandas DataFrameからテーブルモデルを生成しようとしています。私は例コードhereを使用していますが、私がTableModelをWidgetクラス(ln 152)のTableModel2で置き換えると、表示するテーブルを取得できません。

class TableModel2(QtCore.QAbstractTableModel): 
    def __init__(self, parent=None, *args): 
     super(TableModel2, self).__init__() 
     #QtCore.QAbstractTableModel.__init__(self, parent, *args) 
     self.datatable = None 
     self.headerdata = None 
     self.dataFrame = None 
     self.model = QtGui.QStandardItemModel(self) 

    def update(self, dataIn): 
     print 'Updating Model' 
     self.datatable = dataIn 
     print 'Datatable : {0}'.format(self.datatable) 
     headers = dataIn.columns.values 
     header_items = [ 
        str(field) 
        for field in headers 
     ] 
     self.headerdata = header_items 
     print 'Headers' 
     print self.headerdata 

     for i in range(len(dataIn.index.values)): 
      for j in range(len(dataIn.columns.values)): 
       #self.datatable.setItem(i,j,QtGui.QTableWidgetItem(str(df.iget_value(i, j)))) 
       self.model.setItem(i,j,QtGui.QStandardItem(str(dataIn.iget_value(i, j)))) 

    def rowCount(self, parent=QtCore.QModelIndex()): 
     return len(self.datatable.index) 

    def columnCount(self, parent=QtCore.QModelIndex()): 
     return len(self.datatable.columns.values) 

    def data(self, index, role=QtCore.Qt.DisplayRole): 
     if not index.isValid(): 
      return QtCore.QVariant() 
     elif role != QtCore.Qt.DisplayRole: 
      return QtCore.QVariant() 
     #return QtCore.QVariant(self.model.data(index)) 
      return QtCore.QVariant(self.model.data(index)) 

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

    def setData(self, index, value, role=QtCore.Qt.DisplayRole): 
     print "setData", index.row(), index.column(), value 

    def flags(self, index): 
     if (index.column() == 0): 
      return QtCore.Qt.ItemIsEditable | QtCore.Qt.ItemIsEnabled 
     else: 
      return QtCore.Qt.ItemIsEnabled 

私はこのように、モデルを作成し、ビューに追加しようとしています:あなたの注意のための

class Widget(QtGui.QWidget): 
    """ 
    A simple test widget to contain and own the model and table. 
    """ 
    def __init__(self, parent=None): 
     QtGui.QWidget.__init__(self, parent) 

     l=QtGui.QVBoxLayout(self) 
     cdf = self.get_data_frame() 
     self._tm=TableModel(self) 
     self._tm.update(cdf) 
     self._tv=TableView(self) 
     self._tv.setModel(self._tm) 
     for row in range(0, self._tm.rowCount()): 
      self._tv.openPersistentEditor(self._tm.index(row, 0)) 
     l.addWidget(self._tv) 

    def get_data_frame(self): 
     df = pd.DataFrame({'Name':['a','b','c','d'], 
     'First':[2.3,5.4,3.1,7.7], 'Last':[23.4,11.2,65.3,88.8], 'Class':[1,1,2,1], 'Valid':[True, True, True, False]}) 
     return df 

感謝を!

注:編集2 私はQStandardItemModelをTableModel2に組み込みました。また、@ mataのコメントの後にdataFrameToQtTable関数を削除しました。これは少し近づいていますが、まだ動作していません。

+0

パンダをしている使用して、この機能を追加することができます参照してくださいqtpandas DataFrameModelDataFrameWidget

ため

PySideのサポート:13は、実験的な機能として提供します。 https://github.com/pydata/pandas/commits/master/pandas/sandbox/qtpandas.py –

答えて

10

私はこれを上記の提案とSummerfieldのRapid GUIブックの助けを借りて考え出しました。 QAbstractTableModelに存在する基本モデルはありません。 3つの関数のみをオーバーライドする必要があり、データがデータ呼び出しで返される限り、ユーザー定義の形式でデータを格納できます。

Aは非常に単純な実装は次のようになります。これは、Qtのビュー内の任意のcompatableデータフレームを表示することができます

class TableModel(QtCore.QAbstractTableModel): 
    def __init__(self, parent=None, *args): 
     super(TableModel, self).__init__() 
     self.datatable = None 

    def update(self, dataIn): 
     print 'Updating Model' 
     self.datatable = dataIn 
     print 'Datatable : {0}'.format(self.datatable) 

    def rowCount(self, parent=QtCore.QModelIndex()): 
     return len(self.datatable.index) 

    def columnCount(self, parent=QtCore.QModelIndex()): 
     return len(self.datatable.columns.values) 

    def data(self, index, role=QtCore.Qt.DisplayRole): 
     if role == QtCore.Qt.DisplayRole: 
      i = index.row() 
      j = index.column() 
      return '{0}'.format(self.datatable.iget_value(i, j)) 
     else: 
      return QtCore.QVariant() 

    def flags(self, index): 
     return QtCore.Qt.ItemIsEnabled 

私はこれは、あなたもこれを実行する必要がある場合は、すぐに軌道に乗る必要があります

here上で要点を更新しました。

+0

残念ながら、列名とインデックス名は表示されませんか?もしあなたがそれを修正できるなら、それはいいだろう。 – working4coins

1

これはおそらくあなたの問題です:あなたは、それはpd.DataFrameすることはできませんので、あなたの方法は、常にタイプがなければ0

を返します、あなたのdatatabledataFrameToQtTableQTableWidgetに設定

def rowCount(self, parent=QtCore.QModelIndex()): 
    if type(self.datatable) == pd.DataFrame: 
    ... 


def columnCount(self, parent=QtCore.QModelIndex()): 
    if (self.datatable) == pd.DataFrame: 
    ... 

チェックすると、すぐに問題が発生します。あなたのタイプが一致しないすべてのケースを静かに無視したいのですか?(期待しているのと同じインターフェースに従わないと、エラーが発生しやすくなります)型チェックはin most cases unnecessaryです。

+0

はい、私はこれが間違っていることを知っていますが、これは私の問題です。私はそれがQTableWidgetItemに設定されるべきだとは思わない。私はQAbstractTableModelで内部モデルを更新したいと思いますが、これを行う方法や行数や列数を見つける方法がわかりません。ありがとう。 – drexiya

+0

このdataFrameToQtTableを削除するためのサンプルコードを簡略化しました。 – drexiya

関連する問題