In PyQt 5.11.2 (on Windows 10), QFileDialog with the DontUseNativeDialog option set has a bug when sorting by the 'Date Modified' column: it does not sort by the actual date - it sorts alphabetically by the non-zero-padded MM-DD-YYYY string, meaning that 9-12-2018 shows up as being more recent than 12-12-2018.
Is there a workaround or a fix?
The native dialog does sort by date correctly, but, the motivation for using the non-native dialog is that the native dialog does not respect fileDialog.setProxyModel (used to filter out certain files by more complex regex rules), described here and here, which I think is spelled out / alluded to by this line in the docs:
By default, a platform-native file dialog will be used if the platform has one. In that case, the widgets which would otherwise be used to construct the dialog will not be instantiated, so related accessors such as layout() and itemDelegate() will return null. You can set the DontUseNativeDialog option to ensure that the widget-based implementation will be used instead of the native dialog.
The code: the dialog is spawned by calling self.load() (no arguments)
def load(self,fileName=None):
if not fileName:
fileDialog=QFileDialog()
fileDialog.setOption(QFileDialog.DontUseNativeDialog)
fileDialog.setProxyModel(CSVFileSortFilterProxyModel(self))
fileDialog.setNameFilter("CSV Radio Log Data Files (*.csv)")
fileDialog.setDirectory(self.firstWorkingDir)
if fileDialog.exec_():
fileName=fileDialog.selectedFiles()[0]
... and the entire CSVFileSortFilterProxyModel class which only has one function:
# code for CSVFileSortFilterProxyModel partially taken from
# https://github.com/ZhuangLab/storm-control/blob/master/steve/qtRegexFileDialog.py
class CSVFileSortFilterProxyModel(QSortFilterProxyModel):
def __init__(self,parent=None):
# print("initializing CSVFileSortFilterProxyModel")
super(CSVFileSortFilterProxyModel,self).__init__(parent)
# filterAcceptsRow - return True if row should be included in the model, False otherwise
#
# do not list files named *_fleetsync.csv or *_clueLog.csv
# do a case-insensitive comparison just in case
def filterAcceptsRow(self,source_row,source_parent):
# print("CSV filterAcceptsRow called")
source_model=self.sourceModel()
index0=source_model.index(source_row,0,source_parent)
# Always show directories
if source_model.isDir(index0):
return True
# filter files
filename=source_model.fileName(index0).lower()
# filename=self.sourceModel().index(row,0,parent).data().lower()
# print("testing lowercased filename:"+filename)
# never show non- .csv files
if filename.count(".csv")<1:
return False
if filename.count("_fleetsync.csv")+filename.count("_cluelog.csv")==0:
return True
else:
return False