Pandas Pyqt实现表过滤器排序

时间:2015-10-10 21:28:46

标签: python pandas pyqt

我试图在Pyqt应用程序中实现一些Pandas GUI。 我找到了一个在PyQt表中加载Pandas DF的类。 现在我希望能够过滤这些数据(例如excel确实如此)并相应地生成df。 然而Pyqt对我来说有点陡然,我不会实现它,如果它很难(我很惊讶它还不存在)

请在下面找到我的代码 任何建议或意见都表示赞赏

import sys
from PyQt4.QtCore import *
from PyQt4.QtGui import *
from PyQt4 import QtCore, QtGui
import pandas as pd
import numpy as np 


data = {'col1':['1','2','3'], 'col2':['4','5','6'], 'col3':['7','8','9']}
head807677=['Date','Heure','OK-NOK','Detect','C1','C2','C3','C4','C5','C6','C7']
head801986=['Date','Heure','Ok-NOK','Detect','C1','C2','C3','C4','C5','C6','C7','C8']
head=head807677

class PandasModel(QtCore.QAbstractTableModel):
    """
    Class to populate a table view with a pandas dataframe
    """
    def __init__(self, data, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self._data = data

    def rowCount(self, parent=None):
        return len(self._data.values)

    def columnCount(self, parent=None):
        return self._data.columns.size

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid():
            if role == QtCore.Qt.DisplayRole:
                return str(self._data.values[index.row()][index.column()])
        return None

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


class QMT(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(QMT, self).__init__(parent)
        #self.table=QMyTable(data,5,3)
        self.view = QtGui.QTableView(self)
        self.setCentralWidget(self.view)
        self.view.show()
        self.initUI()

    def initUI(self):               

        exitAction = QtGui.QAction(QtGui.QIcon('exit.png'), '&Exit', self)        
        exitAction.setShortcut('Ctrl+Q')
        exitAction.setStatusTip('Exit application')
        exitAction.triggered.connect(QtGui.qApp.quit)

        openFile = QtGui.QAction(QtGui.QIcon('open.png'), 'Open', self)
        openFile.setShortcut('Ctrl+O')
        openFile.setStatusTip('Open new File')
        openFile.triggered.connect(self.showDialog)

        menubar = self.menuBar()
        fileMenu = menubar.addMenu('&File')
        fileMenu.addAction(exitAction)
        fileMenu.addAction(openFile) 

        self.statusBar()
        self.setGeometry(200, 200, 400, 400)
        self.setWindowTitle('Menubar')    
        self.show() 

    def showDialog(self):
        fname = QtGui.QFileDialog.getOpenFileName(self, 'Open file', 
                'C:/Users/user11.HPO-SAMAT/Desktop/807677')     
        data=self.file2df(fname)
        data.columns=head 
        self.model = PandasModel(data)
        self.view.setModel(self.model)
        self.view.show()


    def file2df(self,elmnt):

        data=pd.read_csv(elmnt,names=head,
                     sep='\t+',
                     index_col=False,
                     header=None
                        )
        data=data[data['Detect']==True]
        return data

def main(args):
    app = QApplication(args)
    win = QMT()
    win.show()
    app.exec_()



if __name__=="__main__":
    main(sys.argv)

1 个答案:

答案 0 :(得分:3)

几点修改: 使用numpy =>对PandasMadel的更改真的快点见https://stackoverflow.com/a/31591015/5088513

class PandasModel(QtCore.QAbstractTableModel):
    """
    Class to populate a table view with a pandas dataframe
    """
    def __init__(self, data, parent=None):
        QtCore.QAbstractTableModel.__init__(self, parent)
        self._data = np.array(data.values)
        self._cols = data.columns
        self.r, self.c = np.shape(self._data)

    def rowCount(self, parent=None):
        return self.r

    def columnCount(self, parent=None):
        return self.c

    def data(self, index, role=QtCore.Qt.DisplayRole):
        if index.isValid():
            if role == QtCore.Qt.DisplayRole:
                return self._data[index.row(),index.column()]
        return None


    def headerData(self, p_int, orientation, role):
        if role == QtCore.Qt.DisplayRole:
            if orientation == QtCore.Qt.Horizontal:
                return self._cols[p_int]
            elif orientation == QtCore.Qt.Vertical:
                return p_int
        return None

然后是主要课程:

class QMT(QtGui.QMainWindow):
    def __init__(self, parent=None):
        super(QMT, self).__init__(parent)
        self.view = QtGui.QTableView(self)
        self.header = self.view.horizontalHeader()
        self.header.sectionClicked.connect(self.headerClicked)

...

和排序操作(在DF上但我需要在之后使用DF)

def headerClicked(self, logicalIndex):
    self.order = self.header.sortIndicatorOrder()
    self.pdata.sort(self.pdata.columns[logicalIndex],
                    ascending=self.order,inplace=True)
    self.model = PandasModel(self.pdata)
    self.view.setModel(self.model)
    self.view.update()