The documentation for QFileDialog.getOpenFileName does not provide any clue on how to filter only executables using a const QString &filter = QString()
. Here’s the code for my action using PyQt5:
from PyQt5.QtWidgets import QAction, QFileDialog from PyQt5.QtCore import QDir from os import path class OpenSourcePortAction(QAction): def __init__(self, widget, setSourcePort, config, saveSourcePortPath): super().__init__('&Open Source Port', widget) self.widget = widget self.setShortcut('Ctrl+O') self.setStatusTip('Select a source port') self.triggered.connect(self._open) self.setSourcePort = setSourcePort self.config = config self.saveSourcePortPath = saveSourcePortPath def _open(self): options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog fileName, _ = QFileDialog.getOpenFileName( self.widget, "Select a source port", self.config.get("sourcePortDir"), "Source Ports (gzdoom zandronum)", options=options) if fileName: self.saveSourcePortPath(fileName) self.setSourcePort(fileName)
On linux, naturally, I have no file extensions for executables, but I need to filter .exe extensions on windows (Which I intend to provide a version for). Also, there’s no overloaded method that allows QDir::Executable. How can I use QFileDialog.getOpenFileName
while filtering only executables, no matter which platform it’s running on?
Advertisement
Answer
If you want a more personalized filter then you have to use a proxyModel but for this you cannot use the getOpenFileName method since the QFileDialog instance is not easily accessible since it is a static method.
class ExecutableFilterModel(QSortFilterProxyModel): def filterAcceptsRow(self, source_row, source_index): if isinstance(self.sourceModel(), QFileSystemModel): index = self.sourceModel().index(source_row, 0, source_index) fi = self.sourceModel().fileInfo(index) return fi.isDir() or fi.isExecutable() return super().filterAcceptsRow(source_row, source_index) class OpenSourcePortAction(QAction): def __init__(self, widget, setSourcePort, config, saveSourcePortPath): super().__init__("&Open Source Port", widget) self.widget = widget self.setShortcut("Ctrl+O") self.setStatusTip("Select a source port") self.triggered.connect(self._open) self.setSourcePort = setSourcePort self.config = config self.saveSourcePortPath = saveSourcePortPath def _open(self): proxy_model = ExecutableFilterModel() options = QFileDialog.Options() options |= QFileDialog.DontUseNativeDialog dialog = QFileDialog( self.widget, "Select a source port", self.config.get("sourcePortDir") ) dialog.setOptions(options) dialog.setProxyModel(proxy_model) if dialog.exec_() == QDialog.Accepted: filename = dialog.selectedUrls()[0].toLocalFile() self.saveSourcePortPath(fileName) self.setSourcePort(fileName)