Created
April 19, 2018 17:40
-
-
Save altendky/482f32d971755eb49b66c1d1f569646a to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import sys | |
import os | |
from pathlib import Path | |
from PyQt5.Qt import * # noqa | |
class FileSystemModel(QFileSystemModel): | |
filename_changed = pyqtSignal(object) | |
filename_opened = pyqtSignal(object) | |
home_changed = pyqtSignal(object) | |
def __init__(self, files, parent=None): | |
super().__init__(parent) | |
if not files: | |
self.setFilter(QDir.NoDotAndDotDot | QDir.AllDirs) | |
else: | |
self.setFilter(QDir.Files) | |
self._path = None | |
self._home = None | |
@property | |
def home(self): | |
return self._home | |
@home.setter | |
def home(self, path): | |
new_path = Path(path) | |
if not self._home or (self._home and self._home.resolve() != new_path.resolve()): | |
if sys.platform == "win32": | |
self.setRootPath(os.path.splitdrive(path)[0]) | |
else: | |
self.setRootPath(QDir.rootPath()) | |
self._home = new_path | |
self.home_changed.emit(new_path) | |
@property | |
def path(self): | |
return self._path | |
@path.setter | |
def path(self, path): | |
new_path = Path(path) | |
if not self._path or (self._path and self._path.resolve() != new_path.resolve()): | |
self._path = new_path | |
self.filename_changed.emit(new_path) | |
class DirTreeView(QTreeView): | |
def __init__(self, model, parent=None): | |
super().__init__(parent) | |
model.home_changed.connect(self.on_home_changed) | |
self.setModel(model) | |
self.clicked.connect(self.on_clicked) | |
def on_home_changed(self, path): | |
model = self.model() | |
basedir = path.parent if path.is_file() else path | |
self.setRootIndex(model.setRootPath(str(basedir))) | |
index = model.index(str(basedir)) | |
self.setCurrentIndex(index) | |
def mousePressEvent(self, event): | |
item = self.indexAt(event.pos()) | |
super().mousePressEvent(event) | |
model = self.model() | |
if item.row() == -1 and item.column() == -1 and model.home: | |
self.clearSelection() | |
model.path = model.home | |
def on_clicked(self, index): | |
model = self.model() | |
if self.isExpanded(index): | |
self.collapse(index) | |
else: | |
self.expand(index) | |
path = model.fileInfo(index).absoluteFilePath() | |
model.path = path | |
class FileTableView(QTableView): | |
def __init__(self, model, parent=None): | |
super().__init__(parent) | |
model.filename_changed.connect(self.on_filename_changed) | |
# model.home_changed.connect(self.on_filename_changed) | |
model.home_changed.connect(self.on_dir_changed) | |
self.setModel(model) | |
def on_filename_changed(self, path): | |
model = self.model() | |
basedir = os.path.dirname(path) if os.path.isfile(path) else path | |
root_index = model.setRootPath(str(basedir)) | |
self.setRootIndex(root_index) | |
index = model.index(str(path)) | |
self.setCurrentIndex(index) | |
# self.scrollTo(index, QAbstractItemView.PositionAtCenter) | |
self.scrollTo(index) | |
def on_dir_changed(self, path): | |
model = self.model() | |
basedir = os.path.dirname(path) if os.path.isfile(path) else path | |
# index = model.index(str(basedir)) | |
index = model.setRootPath(str(basedir)) | |
self.setRootIndex(index) | |
class FileBrowser(QWidget): | |
def __init__(self, model_dir, model_files, parent=None): | |
super().__init__(parent) | |
os.environ["QT_FILESYSTEMMODEL_WATCH_FILES"] = '1' | |
self.dir_view = DirTreeView(model_dir) | |
self.file_view = FileTableView(model_files) | |
model_dir.filename_changed.connect(self.file_view.on_dir_changed) | |
# Layout | |
layout = QHBoxLayout() | |
layout.addWidget(self.dir_view) | |
layout.addWidget(self.file_view) | |
self.setLayout(layout) | |
def change_home(self, home): | |
model_dir = self.dir_view.model() | |
model_files = self.file_view.model() | |
model_dir.home = home | |
model_files.home = home | |
def change_path(self, path): | |
model_dir = self.dir_view.model() | |
model_files = self.file_view.model() | |
model_dir.path = path | |
model_files.path = path | |
files = [ | |
os.path.join(os.getcwd(), *p) for p in ( | |
('bug', 'bug_1.txt'), | |
('bug', 'bug_2.txt'), | |
('bug', 'bug_3.txt'), | |
('bug', 'bug_4.txt'), | |
('bug', 'fooa', 'fooa_1.txt'), | |
('bug', 'fooa', 'fooa_2.txt'), | |
('bug', 'fooa', 'fooa_3.txt'), | |
('bug', 'fooa', 'fooa_4.txt'), | |
('bug', 'fooa', 'fooa_5.txt'), | |
('bug', 'fooa', 'fooa_6.txt'), | |
('bug', 'fooa', 'fooa_7.txt'), | |
('bug', 'fooa', 'fooa_8.txt'), | |
('bug', 'fooa', 'fooa_9.txt'), | |
('bug', 'fooa', 'foob', 'foo_b_1.txt'), | |
('bug', 'fooa', 'foob', 'foo_b_2.txt'), | |
('bug', 'fooc', 'fooc_1.txt'), | |
('bug', 'fooc', 'fooc_2.txt'), | |
('bug', 'fooc', 'fooc_3.txt'), | |
('bug', 'fooc', 'food', 'food_1.txt'), | |
('bug', 'fooc', 'food', 'food_2.txt'), | |
('bug', 'fooc', 'food', 'food_3.txt'), | |
) | |
] | |
bug = os.path.join(os.getcwd(), 'bug') | |
def main(): | |
def create_data_bug(): | |
for filename in files: | |
try: | |
os.makedirs(os.path.dirname(filename)) | |
except FileExistsError: | |
pass | |
with open(filename, "w") as f: | |
f.write(filename) | |
class Foo(QMainWindow): | |
def __init__(self): | |
super().__init__() | |
self.model_dir = FileSystemModel( | |
False, parent=self) | |
self.model_files = FileSystemModel( | |
True, parent=self) | |
self.explorer = FileBrowser( | |
self.model_dir, | |
self.model_files, | |
parent=self | |
) | |
self.model_dir.filename_changed.connect(self.on_filename_changed) | |
self.model_files.filename_changed.connect(self.on_filename_changed) | |
basedir = os.path.dirname(__file__) | |
self.explorer.change_home(os.path.join(basedir, "bug")) | |
layout = QVBoxLayout() | |
layout.addWidget(self.explorer) | |
w = QWidget() | |
w.setLayout(layout) | |
self.setCentralWidget(w) | |
def on_filename_changed(self, path): | |
self.statusBar().showMessage("filename_changed: {0}".format(path)) | |
create_data_bug() | |
app = QApplication(sys.argv) | |
foo = Foo() | |
foo.setMinimumSize(1024, 480) | |
foo.show() | |
sys.exit(app.exec_()) | |
if __name__ == "__main__": | |
main() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment