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

时间:2019-11-15 17:17:19

标签: python pyqt5 qtreeview qfilesystemmodel

我想从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行更改此行代码,则solotuons可以工作

self.treeView.setModel(self.proxy_model)

self.treeView.setModel(self.model)

但是,如果这样做,我将无法搜索文件。

1 个答案:

答案 0 :(得分:1)

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

@QtCore.pyqtSlot(QtCore.QModelIndex)
def on_treeView_clicked(self, index):
    source_index = self.proxy_model.mapToSource(index)
    indexItem = self.model.index(source_index.row(), 0, source_index.parent())
    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)