secokit123
secokit123

Reputation: 41

QFileDialog filter unknown file types only

QFileDialog.getOpenFileNames(self, 'Choose File', self.filelocation, filter="?" (*)")

When I try to select files with QFileDialog, it shows me all the files - but I want to filter only unknown file-types, as seen in below picture. Is it possible? Or how can I disable .txt files? enter image description here

Upvotes: 1

Views: 270

Answers (1)

ekhumoro
ekhumoro

Reputation: 120608

It looks like you must use a proxy model for this, because the name-filters use wildcard matching (which doesn't support negated patterns like !(*.*)), and the mime-filters don't seem to recognise any kind of "unknown" file-type.

Below is a working solution that uses a QSortFilterProxyModel. The logic in filterAcceptsRow just allows through all directories and any files with no dots, but you can easily adjust it as you see fit. (To get more details about a file, you could use e.g. info = model.fileInfo(index) to obtain a QFileInfo object).

from PyQt5 import QtCore, QtGui, QtWidgets

class ProxyModel(QtCore.QSortFilterProxyModel):
    def filterAcceptsRow(self, source_row, source_parent):
        model = self.sourceModel()
        index = model.index(source_row, 0, source_parent)
        return model.isDir(index) or '.' not in model.fileName(index)

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

app = QtWidgets.QApplication(['Test'])

dialog = QtWidgets.QFileDialog()
dialog.setFileMode(QtWidgets.QFileDialog.ExistingFiles)
dialog.setWindowTitle('Choose Files')
dialog.setProxyModel(ProxyModel())
dialog.exec()

A further refinement might be to check the mime-type, since the extension alone may be unreliable. The unknown file-type should be equivalent to the default mime-type (i.e. application/octet-stream), so a basic implementation would be:

class ProxyModel(QtCore.QSortFilterProxyModel):
    mimetypes = QtCore.QMimeDatabase()

    def filterAcceptsRow(self, source_row, source_parent):
        model = self.sourceModel()
        index = model.index(source_row, 0, source_parent)
        return model.isDir(index) or (
            '.' not in model.fileName(index) and
            self.mimetypes.mimeTypeForFile(
                model.fileInfo(index)).isDefault())

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

Upvotes: 1

Related Questions