97 lines
3.0 KiB
Python
97 lines
3.0 KiB
Python
|
|
import sys
|
||
|
|
import os
|
||
|
|
from PyQt6.QtCore import *
|
||
|
|
|
||
|
|
class FileSystemItem:
|
||
|
|
def __init__(self, path, parent=None):
|
||
|
|
self.parentItem = parent
|
||
|
|
self.itemPath = path
|
||
|
|
self.children = []
|
||
|
|
self.populated = False
|
||
|
|
|
||
|
|
def row(self):
|
||
|
|
if self.parentItem:
|
||
|
|
return self.parentItem.children.index(self)
|
||
|
|
return 0
|
||
|
|
|
||
|
|
class FileSystemModel(QAbstractItemModel):
|
||
|
|
rootPathChanged = pyqtSignal()
|
||
|
|
|
||
|
|
def __init__(self, parent=None):
|
||
|
|
super().__init__(parent)
|
||
|
|
self._rootPath = ''
|
||
|
|
self.rootItem = FileSystemItem(self._rootPath)
|
||
|
|
self.header = ['Name']
|
||
|
|
|
||
|
|
@pyqtProperty(str, notify=rootPathChanged)
|
||
|
|
def rootPath(self):
|
||
|
|
return self._rootPath
|
||
|
|
|
||
|
|
@rootPath.setter
|
||
|
|
def rootPath(self, path):
|
||
|
|
if self._rootPath != path:
|
||
|
|
self._rootPath = path
|
||
|
|
self.beginResetModel()
|
||
|
|
self.rootItem = FileSystemItem(self._rootPath)
|
||
|
|
self.endResetModel()
|
||
|
|
self.rootPathChanged.emit()
|
||
|
|
|
||
|
|
def columnCount(self, parent=QModelIndex()):
|
||
|
|
return 1
|
||
|
|
|
||
|
|
def rowCount(self, parent=QModelIndex()):
|
||
|
|
if not parent.isValid():
|
||
|
|
parentItem = self.rootItem
|
||
|
|
else:
|
||
|
|
parentItem = parent.internalPointer()
|
||
|
|
|
||
|
|
if not parentItem.populated:
|
||
|
|
self.populateItem(parentItem)
|
||
|
|
return len(parentItem.children)
|
||
|
|
|
||
|
|
def populateItem(self, item):
|
||
|
|
try:
|
||
|
|
if os.path.isdir(item.itemPath):
|
||
|
|
entries = os.listdir(item.itemPath)
|
||
|
|
for entry in entries:
|
||
|
|
fullPath = os.path.join(item.itemPath, entry)
|
||
|
|
item.children.append(FileSystemItem(fullPath, item))
|
||
|
|
item.populated = True
|
||
|
|
else:
|
||
|
|
item.populated = True
|
||
|
|
except (PermissionError, NotADirectoryError):
|
||
|
|
pass
|
||
|
|
|
||
|
|
def data(self, index, role=Qt.ItemDataRole.DisplayRole):
|
||
|
|
if not index.isValid():
|
||
|
|
return None
|
||
|
|
|
||
|
|
item = index.internalPointer()
|
||
|
|
if role == Qt.ItemDataRole.DisplayRole:
|
||
|
|
return os.path.basename(item.itemPath)
|
||
|
|
elif role == Qt.ItemDataRole.UserRole + 1: # isDirRole
|
||
|
|
return os.path.isdir(item.itemPath)
|
||
|
|
elif role == Qt.ItemDataRole.UserRole + 2: # isExpandedRole
|
||
|
|
return False
|
||
|
|
return None
|
||
|
|
|
||
|
|
def index(self, row, column, parent=QModelIndex()):
|
||
|
|
if not self.hasIndex(row, column, parent):
|
||
|
|
return QModelIndex()
|
||
|
|
|
||
|
|
parentItem = parent.internalPointer() if parent.isValid() else self.rootItem
|
||
|
|
childItem = parentItem.children[row]
|
||
|
|
return self.createIndex(row, column, childItem)
|
||
|
|
|
||
|
|
def parent(self, index):
|
||
|
|
if not index.isValid():
|
||
|
|
return QModelIndex()
|
||
|
|
|
||
|
|
childItem = index.internalPointer()
|
||
|
|
parentItem = childItem.parentItem
|
||
|
|
|
||
|
|
if parentItem == self.rootItem:
|
||
|
|
return QModelIndex()
|
||
|
|
|
||
|
|
return self.createIndex(parentItem.row(), 0, parentItem)
|
||
|
|
file_system_model = FileSystemModel()
|