2017-06-17 788 views
0

我在self.tableView.set??????????(df)以下的行中遇到问题,它应该显示PyQt5中的数据帧。我放 ???那里我错过了我需要的代码。如何用PyQt5显示Pandas数据帧

def btn_clk(self): 
     path = self.lineEdit.text() 
     df = pd.read_csv(path) 
     self.tableView.set??????????(df) 

的代码的其余部分的工作原理,因为如果我在上面的代码中使用print(df),数据帧在IPython的控制台打印。所以,熊猫读取CSV并打印出来。

但是,我尝试了很多事情让它显示在PyQt5中,没有任何工作。我对PyQt不是很熟悉,只是开始玩弄它,而我被困在这里。

这是我的代码:

from PyQt5 import QtCore, QtGui, QtWidgets 
import pandas as pd 
class Ui_MainWindow(object): 
    def setupUi(self, MainWindow): 
     MainWindow.setObjectName("MainWindow") 
     MainWindow.resize(662, 512) 
     self.centralwidget = QtWidgets.QWidget(MainWindow) 
     self.centralwidget.setObjectName("centralwidget") 
     self.horizontalLayout = QtWidgets.QHBoxLayout(self.centralwidget) 
     self.horizontalLayout.setObjectName("horizontalLayout") 
     self.verticalLayout = QtWidgets.QVBoxLayout() 
     self.verticalLayout.setObjectName("verticalLayout") 
     self.lineEdit = QtWidgets.QLineEdit(self.centralwidget) 
     self.lineEdit.setObjectName("lineEdit") 
     self.verticalLayout.addWidget(self.lineEdit) 
     self.tableView = QtWidgets.QTableView(self.centralwidget) 
     self.tableView.setObjectName("tableView") 
     self.verticalLayout.addWidget(self.tableView) 
     self.pushButton = QtWidgets.QPushButton(self.centralwidget) 
     self.pushButton.setObjectName("pushButton") 
     self.verticalLayout.addWidget(self.pushButton) 
     self.horizontalLayout.addLayout(self.verticalLayout) 
     MainWindow.setCentralWidget(self.centralwidget) 
     self.menubar = QtWidgets.QMenuBar(MainWindow) 
     self.menubar.setGeometry(QtCore.QRect(0, 0, 662, 21)) 
     self.menubar.setObjectName("menubar") 
     MainWindow.setMenuBar(self.menubar) 
     self.statusbar = QtWidgets.QStatusBar(MainWindow) 
     self.statusbar.setObjectName("statusbar") 
     MainWindow.setStatusBar(self.statusbar) 

     self.retranslateUi(MainWindow) 
     QtCore.QMetaObject.connectSlotsByName(MainWindow) 

    def retranslateUi(self, MainWindow): 
     _translate = QtCore.QCoreApplication.translate 
     MainWindow.setWindowTitle(_translate("MainWindow", "MainWindow")) 
     self.pushButton.setText(_translate("MainWindow", "PushButton")) 


     self.pushButton.clicked.connect(self.btn_clk) 

     MainWindow.show() 

    def btn_clk(self): 
     path = self.lineEdit.text() 
     df = pd.read_csv(path) 
     self.tableView.set????????????(df) 


if __name__ == "__main__": 
    import sys 
    app = QtWidgets.QApplication(sys.argv) 
    MainWindow = QtWidgets.QMainWindow() 
    ui = Ui_MainWindow() 
    ui.setupUi(MainWindow) 
    MainWindow.show() 
    sys.exit(app.exec_()) 

回答

5

在数据必须通过模型来提供的QTableView的情况下,因为它实现了MVC模型 - 视图 - 控制器)范例,在大熊猫的情况下没有默认的模式,但我们可以创建如下面的部分所示的自定义:

class PandasModel(QtCore.QAbstractTableModel): 
    def __init__(self, df = pd.DataFrame(), parent=None): 
     QtCore.QAbstractTableModel.__init__(self, parent=parent) 
     self._df = df 

    def headerData(self, section, orientation, role=QtCore.Qt.DisplayRole): 
     if role != QtCore.Qt.DisplayRole: 
      return QtCore.QVariant() 

     if orientation == QtCore.Qt.Horizontal: 
      try: 
       return self._df.columns.tolist()[section] 
      except (IndexError,): 
       return QtCore.QVariant() 
     elif orientation == QtCore.Qt.Vertical: 
      try: 
       # return self.df.index.tolist() 
       return self._df.index.tolist()[section] 
      except (IndexError,): 
       return QtCore.QVariant() 

    def data(self, index, role=QtCore.Qt.DisplayRole): 
     if role != QtCore.Qt.DisplayRole: 
      return QtCore.QVariant() 

     if not index.isValid(): 
      return QtCore.QVariant() 

     return QtCore.QVariant(str(self._df.ix[index.row(), index.column()])) 

    def setData(self, index, value, role): 
     row = self._df.index[index.row()] 
     col = self._df.columns[index.column()] 
     if hasattr(value, 'toPyObject'): 
      # PyQt4 gets a QVariant 
      value = value.toPyObject() 
     else: 
      # PySide gets an unicode 
      dtype = self._df[col].dtype 
      if dtype != object: 
       value = None if value == '' else dtype.type(value) 
     self._df.set_value(row, col, value) 
     return True 

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

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

    def sort(self, column, order): 
     colname = self._df.columns.tolist()[column] 
     self.layoutAboutToBeChanged.emit() 
     self._df.sort_values(colname, ascending= order == QtCore.Qt.AscendingOrder, inplace=True) 
     self._df.reset_index(inplace=True, drop=True) 
     self.layoutChanged.emit() 

,然后使用它:

def btn_clk(self): 
    path = self.lineEdit.text() 
    df = pd.read_csv(path) 
    model = PandasModel(df) 
    self.tableView.setModel(model) 

enter image description here

的完整源代码here

+0

非常感谢这样做。我是否应该用'PandasModel import PandasModel'将'PandasModel'导入到我的原始代码中?我试图把它放在一起,但它还没有工作。当我尝试导入'PandasModel'时,我得到'no module named PandasModel'错误。我相信我错过了一些东西。你能指点我正确的方向吗? –

+0

通过添加您应该如何使用它的代码更新我的答案 – eyllanesc

+0

哇!这真的很棒!非常感谢。这是一个很大的帮助。它完美的作品。 –