Introduction
The Simple File List App initially presented users with a hierarchical view of files and directories, allowing them to select files for inspection. While this provided a functional interface, there was room for enhancement to offer a more intuitive and versatile user experience. By introducing a tab widget, we can enable users to view each file's contents in a separate tab, akin to a modern text editor or file explorer application.
Components
To implement this enhancement, we'll introduce the following components:
- QTabWidget: This widget will serve as the container for displaying individual files in separate tabs, providing users with a tabbed interface for easier navigation and organization of file contents.
- QPushButton: We'll add a button to each tab to allow users to close individual tabs, providing flexibility and control over their workspace.
- Signal-Slot Connections: We'll connect signals emitted by the file tree view to dynamically create tabs and display file contents when files are selected.
Functionality
With the introduction of the tab widget, the application's functionality will be expanded as follows:
- Tabbed Interface: Each file selected in the file tree view will be displayed in a separate tab within the tab widget. This allows users to switch between files seamlessly and view multiple files simultaneously.
- Dynamic Tab Creation: Tabs will be created dynamically as users select files, ensuring an efficient use of screen real estate and providing a clutter-free workspace.
- Tab Close Button: A close button will be added to each tab, allowing users to close individual tabs when they are no longer needed, enhancing the application's usability and flexibility.
Conclusion
By enhancing the Simple File List App with a tab widget to display files individually, we've elevated its usability and functionality, providing users with a more intuitive and versatile interface for file browsing and inspection. This enhancement not only improves the user experience but also demonstrates the flexibility and power of PyQt6 and Python in developing rich desktop applications. With further iterations and refinements, the application can continue to evolve to meet the needs and preferences of its users, making it a valuable tool for file management and exploration.
Here is the complete code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 | import sys from PyQt6.QtWidgets import QApplication, QMainWindow, QVBoxLayout, QFileDialog, QTreeView, QPushButton, QWidget, QTextEdit, QSplitter, QTabWidget from PyQt6.QtGui import QStandardItemModel, QStandardItem, QFileSystemModel from PyQt6.QtCore import Qt, QDir, QModelIndex # Global variable to store the folder path folder_path = "" class FileListApp(QMainWindow): def __init__(self): super().__init__() self.initUI() def initUI(self): self.setWindowTitle('File List App') self.setGeometry(100, 100, 800, 600) # Create widgets self.tree_view = QTreeView() self.open_button = QPushButton('Open Folder', self) self.tab_widget = QTabWidget(self) # Create a splitter to separate the tree view, tab widget, and the text edit self.splitter = QSplitter(Qt.Orientation.Horizontal) self.splitter.addWidget(self.tree_view) self.splitter.addWidget(self.tab_widget) # Create a close button self.close_button = QPushButton("X") self.close_button.clicked.connect(self.closeActiveTab) # Add the close button to the corner of the tab bar self.tab_widget.setCornerWidget(self.close_button) # Create layout layout = QVBoxLayout() layout.addWidget(self.open_button) layout.addWidget(self.splitter) # Create central widget and set layout central_widget = QWidget() central_widget.setLayout(layout) self.setCentralWidget(central_widget) # Connect the openFolder button to the openFolder slot self.open_button.clicked.connect(self.openFolder) # Connect tabCloseRequested signal to closeTab slot self.tab_widget.tabCloseRequested.connect(self.closeTab) def closeActiveTab(self): current_index = self.tab_widget.currentIndex() self.tab_widget.removeTab(current_index) def openFolder(self): global folder_path folder_path = QFileDialog.getExistingDirectory(self, 'Open Folder') if folder_path: self.setWindowTitle(f'File List App - {folder_path}') self.displayFolderContent(folder_path) def displayFolderContent(self, folder_path): # Set up the file system model model = QFileSystemModel() model.setRootPath(folder_path) model.setFilter(QDir.Filter.NoDotAndDotDot | QDir.Filter.AllEntries) # Set the model to the tree view self.tree_view.setModel(model) self.tree_view.setRootIndex(model.index(folder_path)) self.tree_view.setColumnWidth(0, 250) # Adjust column width # Connect itemClicked signal to displayFileContent self.tree_view.clicked.connect(self.displayFileContent) # Adjust the sizes of the splitter self.splitter.setSizes([int(self.width() * 0.3), int(self.width() * 0.4), int(self.width() * 0.3)]) def resizeEvent(self, event): super().resizeEvent(event) # Calculate the width of the button widget button_width = self.tab_widget.cornerWidget().sizeHint().width() # Update splitter sizes when window is resized self.splitter.setSizes([int(self.width() * 0.3), int(self.width() * 0.4) - button_width, int(self.width() * 0.3)]) def displayFileContent(self, index: QModelIndex): global folder_path # Get the file path from the selected index file_path = self.tree_view.model().filePath(index) # Check if the file is already open in a tab for i in range(self.tab_widget.count()): if self.tab_widget.widget(i).objectName() == file_path: # Switch to the tab containing the file self.tab_widget.setCurrentIndex(i) return # Read the content of the file using utf-8 encoding try: with open(file_path, 'r', encoding='utf-8') as file: content = file.read() # Create a new tab and display file content text_edit = QTextEdit() text_edit.setReadOnly(True) text_edit.setText(content) text_edit.setObjectName(file_path) # Set object name to file path self.tab_widget.addTab(text_edit, file_path.split('/')[-1]) except Exception as e: self.text_edit.setText(f"Error reading file: {str(e)}") def closeTab(self, index): widget = self.tab_widget.widget(index) if widget is not None: widget.deleteLater() self.tab_widget.removeTab(index) def main(): app = QApplication(sys.argv) window = FileListApp() window.show() sys.exit(app.exec()) if __name__ == '__main__': main() |
No comments:
Post a Comment