如何使用 QFileDialog 过滤可执行文件? (跨平台解决方案)
How to filter executables using QFileDialog? (Cross-platform solution)
documentation for QFileDialog.getOpenFileName 没有提供任何关于如何使用 const QString &filter = QString()
过滤可执行文件的线索。这是我使用 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)
在 linux 上,当然,我没有可执行文件的文件扩展名,但我需要在 windows 上过滤 .exe 扩展名(我打算为其提供一个版本)。此外,没有允许 QDir::Executable 的重载方法。我如何使用 QFileDialog.getOpenFileName
同时只过滤可执行文件,无论它 运行 在哪个平台上?
如果你想要一个更个性化的过滤器,那么你必须使用 proxyModel 但为此你不能使用 getOpenFileName 方法,因为 QFileDialog 实例不容易访问,因为它是一个静态方法。
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)
documentation for QFileDialog.getOpenFileName 没有提供任何关于如何使用 const QString &filter = QString()
过滤可执行文件的线索。这是我使用 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)
在 linux 上,当然,我没有可执行文件的文件扩展名,但我需要在 windows 上过滤 .exe 扩展名(我打算为其提供一个版本)。此外,没有允许 QDir::Executable 的重载方法。我如何使用 QFileDialog.getOpenFileName
同时只过滤可执行文件,无论它 运行 在哪个平台上?
如果你想要一个更个性化的过滤器,那么你必须使用 proxyModel 但为此你不能使用 getOpenFileName 方法,因为 QFileDialog 实例不容易访问,因为它是一个静态方法。
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)