簡體   English   中英

在 QFileDialog pyqt5 中選擇文件或文件夾

[英]Select a file or a folder in QFileDialog pyqt5

我的腳本目前使用 QtWidgets.QFileDialog.getOpenFileNames() 讓用戶在 Windows 資源管理器中選擇文件。 現在我想知道是否有辦法讓他們也選擇文件夾,而不僅僅是文件。 有一些類似的帖子,但沒有一個提供有效的解決方案。 我真的不想使用 QFileDialog 文件資源管理器來解決這個問題。

QFileDialog 本身不允許這樣做。 唯一的解決方案是創建自己的實例,做一些小的“修補”。

請注意,為了實現這一點,您不能使用操作系統的本機對話框,因為 Qt 幾乎無法控制它們; 這就是dialog.DontUseNativeDialog標志的原因,這是強制性的。

下面的代碼和靜態方法一樣工作,並返回選定的項目(或不返回,如果對話框被取消)。

def getOpenFilesAndDirs(parent=None, caption='', directory='', 
                        filter='', initialFilter='', options=None):
    def updateText():
        # update the contents of the line edit widget with the selected files
        selected = []
        for index in view.selectionModel().selectedRows():
            selected.append('"{}"'.format(index.data()))
        lineEdit.setText(' '.join(selected))

    dialog = QtWidgets.QFileDialog(parent, windowTitle=caption)
    dialog.setFileMode(dialog.ExistingFiles)
    if options:
        dialog.setOptions(options)
    dialog.setOption(dialog.DontUseNativeDialog, True)
    if directory:
        dialog.setDirectory(directory)
    if filter:
        dialog.setNameFilter(filter)
        if initialFilter:
            dialog.selectNameFilter(initialFilter)

    # by default, if a directory is opened in file listing mode, 
    # QFileDialog.accept() shows the contents of that directory, but we 
    # need to be able to "open" directories as we can do with files, so we 
    # just override accept() with the default QDialog implementation which 
    # will just return exec_()
    dialog.accept = lambda: QtWidgets.QDialog.accept(dialog)

    # there are many item views in a non-native dialog, but the ones displaying 
    # the actual contents are created inside a QStackedWidget; they are a 
    # QTreeView and a QListView, and the tree is only used when the 
    # viewMode is set to QFileDialog.Details, which is not this case
    stackedWidget = dialog.findChild(QtWidgets.QStackedWidget)
    view = stackedWidget.findChild(QtWidgets.QListView)
    view.selectionModel().selectionChanged.connect(updateText)

    lineEdit = dialog.findChild(QtWidgets.QLineEdit)
    # clear the line edit contents whenever the current directory changes
    dialog.directoryEntered.connect(lambda: lineEdit.setText(''))

    dialog.exec_()
    return dialog.selectedFiles()

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM