Search code examples
pythonpython-3.xpyqtpyqt5qfiledialog

Is there an option to rename a QUrl/shortcut in a SideBar of a QFileDialog?


I use the SideBar of a QFileDialog which gets it's QUrls from several folder strings.

I use the method fromLocalFile(dir) and it works great. My problem is, those two paths have the same last folder name. For example:

place1 = "C:\publicDirectories\software\temp"
place2 = "D:\personalUserDirectories\software\temp"

dialog = QtWidgets.QFileDialog(self, 'search', directory, filter)
dialog.setFileMode(QtWidgets.QFileDialog.DirectoryOnly)
dialog.setSidebarUrls([QtCore.QUrl.fromLocalFile(place1), QtCore.QUrl.fromLocalFile(place2)])

Qt takes the last folder name of the QUrl and name the shortcut like that. So when the dialog opens, I have two entries called "temp". Is there any chance to dig into the Qt code of the SideBar to rename the shortcuts although they still point to the same folders as shown above? I mean something like you are doing to rename the Yes/No buttons of a QMessageBox...

I heaven't found anything about it in the qt documentation.


Solution

  • A possible solution is to set a delegate that changes the text displayed in the sidebar:

    from PyQt5 import QtCore, QtWidgets
    
    UrlRole = QtCore.Qt.UserRole + 1
    EnabledRole = QtCore.Qt.UserRole + 2
    
    
    class StyledItemDelegate(QtWidgets.QStyledItemDelegate):
        mapping = dict()
    
        def initStyleOption(self, option, index):
            super().initStyleOption(option, index)
            url = index.data(UrlRole)
            text = self.mapping.get(url)
            if isinstance(text, str):
                option.text = text
            is_enabled = index.data(EnabledRole)
            if is_enabled is not None and not is_enabled:
                option.state &= ~QtWidgets.QStyle.State_Enabled
    
    app = QtWidgets.QApplication([])
    
    places = {
        QtCore.QUrl.fromLocalFile("/home/eyllanesc"): "Foo",
        QtCore.QUrl.fromLocalFile("/home/eyllanesc/Pictures"): "Bar",
    }
    
    dialog = QtWidgets.QFileDialog(
        caption="search",
        options=QtWidgets.QFileDialog.DontUseNativeDialog,
        fileMode=QtWidgets.QFileDialog.DirectoryOnly,
    )
    dialog.setSidebarUrls(places.keys())
    sidebar = dialog.findChild(QtWidgets.QListView, "sidebar")
    delegate = StyledItemDelegate(sidebar)
    delegate.mapping = places
    sidebar.setItemDelegate(delegate)
    dialog.exec_()