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