Search code examples
pythonpyqtqtableviewqfilesystemmodel

QFileSystemModel QTableView Date Modified highlighting


I am trying to make a little file browser using QFileSystemModel and QTableView.

I was wondering if it is possible to highlight rows with same value in "Date Modified" column, for instance if I have two or more files which been modified today row gets highlighted in green, those modified yesterday highlighted in green but lighter shade, etc.


Solution

  • To change the background color there are several options such as:

    • override the data() method of the model so that the return value associated with the role Qt.BackgroundRole.

    • Use a QIdentityProxyModel that modifies the value associated with Qt.BackgroundRole similar to the previous option

    • Use a QStyledItemDelegate to modify the backgroundBrush property of QStyleOptionViewItem.

    The simplest option is the last option so I will show your implementation:

    from PyQt5 import QtCore, QtGui, QtWidgets
    
    
    class DateDelegate(QtWidgets.QStyledItemDelegate):
        def initStyleOption(self, option, index):
            super().initStyleOption(option, index)
            model = index.model()
            if isinstance(model, QtWidgets.QFileSystemModel):
                dt = model.lastModified(index)
    
                today = QtCore.QDateTime.currentDateTime()
                yesterday = today.addDays(-1)
                if dt < yesterday:
                    option.backgroundBrush = QtGui.QColor(0, 255, 0)
                else:
                    option.backgroundBrush = QtGui.QColor(0, 155, 0)
    
    
    def main():
        import sys
    
        app = QtWidgets.QApplication(sys.argv)
    
        path_dir = QtCore.QDir.currentPath()
    
        view = QtWidgets.QTableView()
        model = QtWidgets.QFileSystemModel()
        view.setModel(model)
        model.setRootPath(path_dir)
    
        view.setRootIndex(model.index(path_dir))
    
        view.show()
    
        delegate = DateDelegate(view)
        view.setItemDelegate(delegate)
    
        sys.exit(app.exec_())
    
    
    if __name__ == "__main__":
        main()