如何在 QFileSystemModel 和 QTreeView 中获取选中的项目

How to get selected item in QFileSystemModel and QTreeView

我想从 pyqt5 的树视图中获取文件路径和文件名。我让它工作了,但我想实现搜索,这是有效的,但这样做我牺牲了获取文件名和文件路径的能力。 这是我的树:

class Folder_Screeen(QDialog):
    def __init__(self, parent = None):
        super(Folder_Screeen, self).__init__(parent)
        self.path = expanduser(os.path.dirname(os.path.realpath(__file__)))
        self.pathRoot = QDir.rootPath()

        self.labelFileName = QLabel(self)
        self.labelFileName.setText("Search:")
        self.labelFileName.resize(100, 30)

        self.txtSearch = QLineEdit(self)
        self.txtSearch.textChanged.connect(self.on_textChanged)
        self.thumbnail = QLabel(self)

        self.model = QFileSystemModel()
        self.model.setRootPath(QDir.rootPath())
        self.model.setFilter(QDir.NoDotAndDotDot | QDir.AllEntries | QDir.Dirs | QDir.Files)
        self.proxy_model = QSortFilterProxyModel(recursiveFilteringEnabled = True, filterRole = QFileSystemModel.FileNameRole)
        self.proxy_model.setSourceModel(self.model)
        self.model.setReadOnly(False)
        self.model.setNameFilterDisables(False)

        self.indexRoot = self.model.index(self.model.rootPath())

        self.treeView = QTreeView(self)
        self.treeView.setModel(self.proxy_model)
        self.adjust_root_index()
        # self.treeView.setRootIndex(self.model.index(self.path))
        self.treeView.setRootIndex(self.proxy_model.mapFromSource(self.model.index(self.path)))
        self.treeView.clicked.connect(self.on_treeView_clicked)
        # self.treeView.setSelectionMode(self.SingleSelection)
        self.treeView.setDragDropMode(QAbstractItemView.InternalMove)
        self.treeView.setAnimated(True)
        self.treeView.setIndentation(20)
        self.treeView.setSortingEnabled(True)
        self.treeView.setDragEnabled(True)
        self.treeView.setAcceptDrops(True)
        self.treeView.setDropIndicatorShown(True)
        self.treeView.setEditTriggers(QTreeView.NoEditTriggers)
        self.treeView.setContextMenuPolicy(Qt.CustomContextMenu)
        self.treeView.customContextMenuRequested.connect(self.showContextMenu)

    @QtCore.pyqtSlot(str)
    def on_textChanged(self):
        self.proxy_model.setFilterWildcard("*{}*".format(self.txtSearch.text()))
        self.adjust_root_index() 

    def adjust_root_index(self):
        root_index = self.model.index(self.path)
        proxy_index = self.proxy_model.mapFromSource(root_index)
        self.treeView.setRootIndex(proxy_index)
    def btnAddFolder(self):
        options = QFileDialog.Options()
        fileName, _ = QFileDialog.getOpenFileName(self,"Create Folder", "","All Files (*)", options=options)
        if fileName:
            print(fileName)

    def keyPressEvent(self, event):
        if event.key() == Qt.Key_Delete:
            if self.lineEditFilePath.text() != '':
                os.remove(self.lineEditFilePath.text())

    @QtCore.pyqtSlot(QtCore.QModelIndex)
    def on_treeView_clicked(self, index):
        indexItem = self.model.index(index.row(), 0, index.parent())# print(indexItem)
        fileName = self.model.fileName(indexItem)
        filePath = self.model.filePath(indexItem)

        self.thumbnail.setPixmap(QPixmap(filePath))
        self.thumbnail.setAlignment(Qt.AlignRight | Qt.AlignBottom)

        print(fileName)
        print(filePath)

    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()

    def dragMoveEvent(self, event):
        if event.mimeData().hasUrls:
            event.setDropAction(Qt.CopyAction)
            event.accept()
        else:
            event.ignore()
    def showContextMenu(self, point):
        ix = self.treeView.indexAt(point)
        if ix.column() == 0:
            menu = QMenu()
            menu.addAction("Rename")
            action = menu.exec_(self.treeView.mapToGlobal(point))
            if action:
                if action.text() == "Rename":
                    self.treeView.edit(ix)
    # TREE VIEW END ====================================

我没有得到任何类型的输出,只有一个空字符串或主系统驱动器。

如果我在第 26 行更改这行代码,独奏会起作用

self.treeView.setModel(self.proxy_model)

self.treeView.setModel(self.model)

但是如果我这样做,我就不能再搜索文件了。

如果您已将 QSortFilterProxyModel 设置为模型,那么通过其信号发送 QTreeView 的 QModelIndex 将属于该模型,因此如果您想从 QFileSystemModel 获取信息,它们显然会失败,解决方案是获取使用 mapToSource() 方法的相应 QModelIndex:

@QtCore.pyqtSlot(QtCore.QModelIndex)
def on_treeView_clicked(self, index):
    <b>source_index = self.proxy_model.mapToSource(index)
    indexItem = self.model.index(source_index.row(), 0, source_index.parent())</b>
    fileName = self.model.fileName(indexItem)
    filePath = self.model.filePath(indexItem)

    self.thumbnail.setPixmap(QPixmap(filePath))
    self.thumbnail.setAlignment(Qt.AlignRight | Qt.AlignBottom)

    print(fileName)
    print(filePath)