QFileDialog с прокси-моделью сортировки по дате фактически использует алфавитный порядок даты - PullRequest
0 голосов
/ 15 декабря 2018

В PyQt 5.11.2 (в Windows 10) QFileDialog с установленным параметром DontUseNativeDialog имеет ошибку при сортировке по столбцу «Дата изменения»: он не сортируется по фактической дате - он сортирует по алфавиту по ненулевому значениюдополненная строка MM-DD-YYYY, означающая, что 9-12-2018 более поздняя, ​​чем 12-12-2018.enter image description here Есть ли обходной путь или исправление?

Собственное диалоговое окно выполняет сортировку по дате правильно, но мотивация для использования не родного диалогового окна состоит в том, что собственное диалоговое окно неуважать fileDialog.setProxyModel (используется для фильтрации определенных файлов по более сложным правилам регулярных выражений), описанным здесь и здесь , которые, я думаю, прописаны / упоминаются этой строкой в ​​документации:

По умолчанию будет использоваться диалоговое окно с собственным файлом платформы, если оно есть у платформы.В этом случае не будут созданы экземпляры виджетов, которые в противном случае использовались бы для создания диалога, поэтому связанные средства доступа, такие как layout () и itemDelegate (), будут возвращать ноль.Вы можете установить опцию DontUseNativeDialog, чтобы гарантировать, что реализация на основе виджетов будет использоваться вместо собственного диалога.

Код: диалог порождается вызовом self.load () (без аргументов)

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]

... и весь класс CSVFileSortFilterProxyModel, который имеет только одну функцию:

# 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

1 Ответ

0 голосов
/ 16 декабря 2018

Проблема вызвана пользовательским QSortFilterProxyModel, поскольку в методе lessThan значения являются строками, решение заключается в преобразовании в соответствующий тип для сравнения:

class CSVFileSortFilterProxyModel(QtCore.QSortFilterProxyModel):
    def filterAcceptsRow(self,source_row,source_parent):
        source_model = self.sourceModel()
        index0=source_model.index(source_row,0,source_parent)
        if source_model.isDir(index0):
            return True
        filename = source_model.fileName(index0).lower()
        if filename.count(".csv")<1:
            return False
        return filename.count("_fleetsync.csv")+filename.count("_cluelog.csv") == 0

    def lessThan(self, left, right):
        source_model = self.sourceModel()

        if left.column() == right.column() == 1: 
            if source_model.isDir(left) and not source_model.isDir(right):
                return True
            return source_model.size(left) < source_model.size(right)

        if left.column() == right.column() == 2:
            return source_model.type(left) < source_model.type(right)

        if left.column() == right.column() == 3:
            return source_model.lastModified(left) < source_model.lastModified(right)
        return super(CSVFileSortFilterProxyModel, self).lessThan(left, right)

Как указано @ ekhumoro более простой вариант - переписать прокси-сортировку:

class CSVFileSortFilterProxyModel(QtCore.QSortFilterProxyModel):
    def filterAcceptsRow(self,source_row,source_parent):
        source_model = self.sourceModel()
        index0=source_model.index(source_row,0,source_parent)
        if source_model.isDir(index0):
            return True
        filename = source_model.fileName(index0).lower()
        if filename.count(".csv")<1:
            return False
        return filename.count("_fleetsync.csv")+filename.count("_cluelog.csv") == 0

    def sort(self, column, order):
        self.sourceModel().sort(column, order)
...