Sort QTableView in pyqt5

I want to sort QTableView in PyQT5. I found an example that uses PyQT4, but in PyQT5 SIGNALs no longer exist. This is my sample code.

class MainWindow(QWidget): def __init__(self, parent=None): super(MainWindow, self).__init__(parent) # create table self.get_table_data() table = self.createTable() # layout layout = QVBoxLayout() layout.addWidget(table) self.setLayout(layout) def get_table_data(self): stdouterr = os.popen("dir c:\\").read() lines = stdouterr.splitlines() lines = lines[5:] lines = lines[:-2] self.tabledata = [re.split(r"\s+", line, 4) for line in lines] def createTable(self): # create the view tv = QTableView() # set the table model header = ['date', 'time', '', 'size', 'filename'] tm = MyTableModel(self.tabledata, header, self) tv.setModel(tm) # set the minimum size tv.setMinimumSize(400, 300) # hide grid tv.setShowGrid(False) tv.setSelectionBehavior(QAbstractItemView.SelectRows) # set the font # 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 nrows = len(self.tabledata) for row in range(nrows): tv.setRowHeight(row, 18) # enable sorting tv.setSortingEnabled(True) return tv self.setWindowTitle("Finance") class MyTableModel(QAbstractTableModel): def __init__(self, datain, headerdata, parent=None, *args): """ datain: a list of lists headerdata: a list of strings """ QAbstractTableModel.__init__(self, parent, *args) self.arraydata = datain self.headerdata = headerdata def rowCount(self, parent): return len(self.arraydata) def columnCount(self, parent): return len(self.arraydata[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 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__': from PyQt5.QtWidgets import QApplication app = QApplication(sys.argv) helloPythonWidget = MainWindow() helloPythonWidget.show() sys.exit(app.exec_()) 

I tried many different ways to use self.layoutAboutToBeChanged () and pyqtSignal, but to be honest, I do not understand this, since I'm new to python and PyQT in general. I tried to get information from the Documentation, but I did not get any hints from the documentation and did not find a good example on the Internet.

UPDATE:

I solved the riddle:

self.layoutAboutToBeChanged.emit() emits a signal (the encoding in the eclipse is a bit misleading)

 def sort(self, Ncol, order): """Sort table by given column number. """ self.layoutAboutToBeChanged.emit() self.arraydata = sorted(self.arraydata, key=operator.itemgetter(Ncol)) if order == Qt.DescendingOrder: self.arraydata.reverse() self.layoutChanged.emit() 

This decision

+7
python eclipse pyqt5
source share
1 answer

for those of you who want to import pandas dataframe into qt model, try this:

 class PandasModel(QtCore.QAbstractTableModel): def __init__(self, data, parent=None): """ :param data: a pandas dataframe :param parent: """ QtCore.QAbstractTableModel.__init__(self, parent) self._data = data # self.headerdata = data.columns 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, rowcol, orientation, role): # print(self._data.columns[rowcol]) # print(self._data.index[rowcol]) if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole: return self._data.columns[rowcol] if orientation == QtCore.Qt.Vertical and role == QtCore.Qt.DisplayRole: return self._data.index[rowcol] return None def flags(self, index): flags = super(self.__class__, self).flags(index) flags |= QtCore.Qt.ItemIsEditable flags |= QtCore.Qt.ItemIsSelectable flags |= QtCore.Qt.ItemIsEnabled flags |= QtCore.Qt.ItemIsDragEnabled flags |= QtCore.Qt.ItemIsDropEnabled return flags def sort(self, Ncol, order): """Sort table by given column number. """ try: self.layoutAboutToBeChanged.emit() self._data = self._data.sort_values(self._data.columns[Ncol], ascending=not order) self.layoutChanged.emit() except Exception as e: print(e) 

I forgot where I got the base pandasmodel, possibly from here

0
source share