如何在 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)
我想从 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)