I've been working on a personal project for a file explorer that is very similar to the how for Ubuntu works. I currently have a problem with the address bar that would show the current directories path
import sys
from PyQt6.QtCore import QDir, QSize, Qt, QFile
from PyQt6.QtGui import QFileSystemModel, QGuiApplication
from PyQt6.QtWidgets import QMainWindow, QApplication, QListView, QHBoxLayout, QWidget, QLabel, QFrame, \
QToolBar, QPushButton
class MainWindow(QMainWindow):
def __init__(self):
super().__init__()
self.clipboard = QGuiApplication.clipboard()
self.homePath = QDir.homePath()
self.initUI()
def initUI(self):
self.setWindowTitle("Tanz")
self.setFixedSize(800, 500)
self.setupActions()
self.setupMainWindow()
self.show()
def setupMainWindow(self):
""" Toolabr """
self.core_toolbar = QToolBar()
self.core_toolbar.setContextMenuPolicy(Qt.ContextMenuPolicy.PreventContextMenu)
self.core_toolbar.setParent(self)
self.core_toolbar.setFixedSize(800, 45)
self.core_toolbar.setMovable(False)
self.core_toolbar.toggleViewAction().setEnabled(False)
self.core_toolbar.setIconSize(QSize(25, 25))
self.core_toolbar.setToolButtonStyle(Qt.ToolButtonStyle.ToolButtonIconOnly)
back = QPushButton("<")
back.setFixedSize(25,25)
forward = QPushButton(">")
forward.setFixedSize(25,25)
self.core_toolbar.addWidget(back)
self.core_toolbar.addWidget(forward)
self.frame = QFrame()
self.frame.setFixedSize(600, 35)
self.h_box = QHBoxLayout()
self.h_box.setAlignment(Qt.AlignmentFlag.AlignLeft)
self.frame.setLayout(self.h_box)
self.core_toolbar.addWidget(self.frame)
menu = QPushButton("Menu")
menu.setFixedSize(50,25)
search = QPushButton("Srch")
search.setFixedSize(75,25)
self.core_toolbar.addWidget(menu)
self.core_toolbar.addWidget(search)
self.addToolBar(self.core_toolbar)
self.addToolBarBreak()
self.core_file_model = QFileSystemModel()
self.core_file_model.setFilter(QDir.Filter.NoDotAndDotDot | QDir.Filter.AllEntries)
self.core_file_model.sort(0, Qt.SortOrder.AscendingOrder)
self.core_file_model.setRootPath(self.homePath)
self.core_f_list_view = QListView()
self.core_f_list_view.setModel(self.core_file_model)
self.core_f_list_view.setRootIndex(self.core_file_model.index(self.homePath))
self.core_f_list_view.setViewMode(QListView.ViewMode.IconMode)
self.core_f_list_view.setIconSize(QSize(60, 60))
self.core_f_list_view.setSpacing(5)
self.core_f_list_view.setWordWrap(True)
self.core_f_list_view.setFrameStyle(QListView.Shape.NoFrame)
self.core_f_list_view.setGridSize(QSize(100, 100))
self.core_f_list_view.doubleClicked.connect(self.load)
layout = QHBoxLayout()
layout.addWidget(self.core_f_list_view)
wid = QWidget()
wid.setLayout(layout)
self.setCentralWidget(wid)
def setupActions(self):
pass
def load(self):
cur_ind = self.core_f_list_view.currentIndex()
cur_ind_path = self.core_file_model.filePath(cur_ind)
if QDir(cur_ind_path).exists():
self.core_f_list_view.setRootIndex(self.core_file_model.index(cur_ind_path))
self.core_file_model.setRootPath(cur_ind_path)
self.updateAddressBar()
elif QFile(cur_ind_path).exists():
# Open the file.
pass
else:
pass
def updateAddressBar(self):
curr_path = self.core_file_model.filePath(self.core_f_list_view.rootIndex())
spl_curr_path = curr_path.split("/")[1:]
print(spl_curr_path)
for i in reversed(range(self.h_box.count())):
item = self.h_box.itemAt(i)
if item.widget():
self.h_box.removeWidget(item.widget())
# item.widget().deleteLater()
elif item.spacerItem():
self.h_box.removeItem(item.spacerItem())
else:
pass
for sub_dir in spl_curr_path:
sub_dir_l = QLabel(sub_dir)
self.h_box.addWidget(sub_dir_l)
if sub_dir == spl_curr_path[-1]:
pass
else:
sep = QLabel("/")
self.h_box.addWidget(sep)
if __name__ == '__main__':
app = QApplication(sys.argv)
window = MainWindow()
sys.exit(app.exec())
I have been unable to find a solution to the problem of:
- When the path is longer then the available view space: Remove the farthest path to the left -- first directory in full path
- if user clicks on the parent directory then load said directory; adjust the address bar accordingly
self.h_box.setAlignment(Qt.AlignmentFlag.AlignLeft)
This line allows the QLabels to align to the left in the QHBoxLayout. Which is along the lines of how it would look. Though once the path becomes to long it starts to cut the 2nd QLabel directory at the end. I've looked into adding a QScrollView to allow the horizontal scroll and align the current directory in view to be visible. I was unable to have this work out.
any help is minimizing the code and figuring this problem out would be grateful.
After spending some time figuring this out, on how to achieve this effect; An Address Bar or Breadcrumb Navigation for a file explorer that operates similarly to the Default (Nautilus) File Explorer on Ubuntu Jammy
To achieve this I had to create two custom classes:
AddressBarLabel(QLabel) & AddressBar(QFrame)
The original problem being, and now figured out is.
Along the way I did manage to have the QMenu that is triggered by a right click on the final QLabel in the address bar to be displayed on the QPushButton that is located on the QToolBar.
Full code to achieve this in the RME I provided in my original question is
I encourage that if anyone is to use this and find a simpler or cleaner way of achieving this, please add your answers below. This will be kept on GitHub for future reference at: https://github.com/ZoidEee/PyQT6-Address-Bar