いわゆるファイルエクスプローラーを表示します。

Untitled

恐らく、Windowsは「UNCパス」(ネットワークパス)が扱えないので、ローカルネットワークパスに割り当てたパスをsetRootする必要がありそうです。

PySide2 Reference : https://doc.qt.io/qtforpython-5/PySide2/QtWidgets/QFileSystemModel.html

Example

※モデルを使うので、TreeView(Widgetが無いやつ)に登録して使います。

Untitled

以下コードをクラス等で実装。

import os
import sys
import subprocess
import webbrowser
import platform

from PySide2 import QtCore, QtGui, QtWidgets

# ついでに開く色々サンプル
def openDir(path):
    if path.startswith('https://'):
         webbrowser.open( path, new=2 )

    if os.path.exists(path):
        if os.path.isfile(path):
            path = os.path.dirname(path)

        if platform.system() == 'Windows':
            cmd = 'explorer {}'.format(path.replace('/', '\\\\\\\\'))
            subprocess.Popen(cmd)
        elif platform.system() == 'Darwin':
            subprocess.call(['open', path])
        else:
            subprocess.Popen(["xdg-open", path])

    else:
        pass

# クリック用関数
def clicked(index):
    print('Clicked', index)

# ダブルクリック用関数
def doubleClicked(index):
    print('Double Clieced', index)
    # index = tree_view.currentIndex()でも多分OK
    path = file_system_model.filePath(index)
    print(path)
    openDir(path)

# ルートパス指定
PATH = 'C:/Program Files'

# アプリケーション作成
app = QtWidgets.QApplication(sys.argv)

# Setup Model
tree_view = QtWidgets.QTreeView()
file_system_model = QtWidgets.QFileSystemModel()
tree_view.setModel(file_system_model)
# ソートオン
tree_view.setSortingEnabled(True)
tree_view.sortByColumn(0, QtCore.Qt.AscendingOrder)

# Setup HeadrSize
header = tree_view.header()
header.resizeSection(0, 200) # Column, width

# Set Path
file_system_model.setRootPath(PATH)
tree_view.setRootIndex(file_system_model.index(PATH))

# Signals
tree_view.clicked[QtCore.QModelIndex].connect(clicked)
tree_view.doubleClicked[QtCore.QModelIndex].connect(doubleClicked)

# Show
tree_view.resize(500,500)
tree_view.show()
sys.exit(app.exec_())

CGソフトでは

app = QtWidgets.QApplication(sys.argv)
sys.exit(app.exec_())

の2行を削除し、parentなどを指定してあげて下さい。

MultiSelection:

# 複数選択。詳しくはselectionMode参照
# tree_view.MultiSelection等がある
tree_view.setSelectionMode(tree_view.ExtendedSelection)

# 複数選択しているパスを収集
selected_files = [model.filePath(index) for index in tree_view.selectedIndexes()]

Reference From; https://forum.qt.io/topic/119210/treeview-qfilesystemmodel-how-can-i-retrieve-multi-selection-list/16

from PySide2 import QtCore
from PySide2 import QtWidgets
from PySide2 import QtGui
import sys
import os

def selectionChanged(selected, deselected):
    index = qtreeview_files.currentIndex()
    print model.filePath(index)

qtreeview_files = QtWidgets.QTreeView()
model = QtWidgets.QFileSystemModel()
model.setRootPath("")
qtreeview_files.setModel(model)
qtreeview_files.hideColumn(1)
qtreeview_files.hideColumn(2)
qtreeview_files.hideColumn(3)
qtreeview_files.setSelectionMode(QtWidgets.QAbstractItemView.ExtendedSelection)
selectionModel  = qtreeview_files.selectionModel()
win_wid = QtWidgets.QWidget()
layout = QtWidgets.QVBoxLayout()
layout.addWidget(qtreeview_files)
win_wid.setLayout(layout)
#win_wid.resize(200, 50)

win_wid.show()

##after you confirm the selection run this to get final selection list
list_of_sel_files = []
all = qtreeview_files.selectedIndexes()
for x in all:
    print model.filePath(x)
    list_of_sel_files.append(model.filePath(x))
##########################################

selectionModel.selectionChanged.connect(selectionChanged)

参考

https://stackoverflow.com/questions/48121711/drag-and-drop-within-pyqt5-treeview

class Tree(QTreeView):
    def __init__(self):
        QTreeView.__init__(self)
        model = QFileSystemModel()
        model.setRootPath(QDir.currentPath())

        self.setModel(model)
        self.setRootIndex(model.index(QDir.currentPath()))
        model.setReadOnly(False)

        self.setSelectionMode(self.SingleSelection)
        self.setDragDropMode(QAbstractItemView.InternalMove)
        self.setDragEnabled(True)
        self.setAcceptDrops(True)
        self.setDropIndicatorShown(True)

    def dragEnterEvent(self, event):
        m = event.mimeData()
        if m.hasUrls():
            for url in m.urls():
                if url.isLocalFile():
                    event.accept()
                    return
        event.ignore()

    def dropEvent(self, event):
        if event.source():
            QTreeView.dropEvent(self, event)
        else:
            ix = self.indexAt(event.pos())
            if not self.model().isDir(ix):
                ix = ix.parent()
            pathDir = self.model().filePath(ix)
            m = event.mimeData()
            if m.hasUrls():
                urlLocals = [url for url in m.urls() if url.isLocalFile()]
                accepted = False
                for urlLocal in urlLocals:
                    path = urlLocal.toLocalFile()
                    info = QFileInfo(path)
                    n_path = QDir(pathDir).filePath(info.fileName())
                    o_path = info.absoluteFilePath()
                    if n_path == o_path:
                        continue
                    if info.isDir():
                        QDir().rename(o_path, n_path)
                    else:
                        qfile = QFile(o_path)
                        if QFile(n_path).exists():
                            n_path += "(copy)"
                        qfile.rename(n_path)
                    accepted = True
                if accepted:
                    event.acceptProposedAction()