在QFileDialog中如何选择多个文件和文件夹?

14

我正在使用pyQt4,希望在我的GUI中拥有一个浏览按钮,该按钮可以打开一个对话框,允许用户选择多个文件文件夹。

我已经进行了相当多的研究,但没有找到任何方法能够做到这一点。

QFileDialog.getOpenFileNames()只允许我选择文件,而QFileDialog.getExistingDirectory()只允许我选择目录。

是否有任何方式可以将它们的功能结合起来。理想情况下,我想使用nativeDialogs,但似乎不可能。因此,我愿意在外观上做出妥协。是否有任何方法可以实现所说的功能?

这里也有相同的问题,但答案是C++。我需要Python实现。 在QFileDialog中允许用户选择文件或文件夹


1
不幸的是,我怀疑答案是否定的。你提到的C++答案是无效的。选项有:1)向Qt开发人员提交愿望,2)编写自己的文件对话框,3)自行修复。如果您能想到一个实现此功能的Qt项目,那么看看它是如何实现的会很有趣。 - Luke
我进行了挖掘并发现问题出在操作系统(Windows)上。 你不能在一个窗口中同时打开文件和文件夹。 Mac可以做到。 悲伤,但却是事实。 - aleXela
2个回答

11

以下是一种可能适用的方法:创建一个QFileDialog的子类,断开“打开”按钮的连接,并将其重新连接到自定义的函数上。但不能保证在Qt的不同版本中都能起作用,因为它依赖于能够找到特定子小部件,这些部件在某些情况下可能会被重新配置。

class FileDialog(QtGui.QFileDialog):
    def __init__(self, *args):
        QtGui.QFileDialog.__init__(self, *args)
        self.setOption(self.DontUseNativeDialog, True)
        self.setFileMode(self.ExistingFiles)
        btns = self.findChildren(QtGui.QPushButton)
        self.openBtn = [x for x in btns if 'open' in str(x.text()).lower()][0]
        self.openBtn.clicked.disconnect()
        self.openBtn.clicked.connect(self.openClicked)
        self.tree = self.findChild(QtGui.QTreeView)

    def openClicked(self):
        inds = self.tree.selectionModel().selectedIndexes()
        files = []
        for i in inds:
            if i.column() == 0:
                files.append(os.path.join(str(self.directory().absolutePath()),str(i.data().toString())))
        self.selectedFiles = files
        self.hide()

    def filesSelected(self):
        return self.selectedFiles

1
非常感谢!它运行得很好。但是,我不得不更改一行代码以满足我的需求。files.append(os.path.join(str(self.directory().absolutePath()),str(i.data().toString()))) - sahilgupta
然而,我遇到了一个问题,即在对话框中选择的目录未在Files_name行编辑器中指示,而文件是,尽管两者都可以通过filesSelected()成功返回。是否有任何解决方法可避免用户感到困惑? - sahilgupta
我猜treeview的selectionmodel在选择改变时会发出一个信号,这个信号被捕获后更新lineedit中的文本。您可以断开该信号并重新连接到具有所期望行为的自定义函数。 - Luke
我无法让它工作。有人能提供一下调用的示例吗?像这样:mylist = FileDialog.getExistingDirectory(self, "选择文件和文件夹", "", QtGui.QFileDialog.DontConfirmOverwrite) - panofish
@Luke:我在C++中实现了你的想法,但它不起作用,这意味着selectedFiles将返回文件或目录(取决于ctor中设置的模式),但不能同时处理两者。这是我的片段。你能指出我做错了什么吗? - László Papp

2
在Qt5中,您可以简单地使用以下代码:
return QtWidgets.QFileDialog.getOpenFileNames(self, title, directory, filter=filterFile)

再说一遍...? - markling
@markling 注意 getOpenFileNames 中的 's':https://doc-snapshots.qt.io/qtforpython-5.15/PySide2/QtWidgets/QFileDialog.html?highlight=qfiledialog#PySide2.QtWidgets.PySide2.QtWidgets.QFileDialog.getOpenFileNames - Lorem Ipsum
@LoremIpsum 不过它不允许选择文件夹。OP想要同时选择文件和文件夹。 - Nevermore
无法同时使用。设置过滤器="Folder"或Directory,无法选择文件夹。只有文件。 - aleXela

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接