Search code examples
pythonpyqtpyqt5qtreewidget

PyQT5 QTreeWidget get full path of clicked element


I hope you all safe and healthy. My problem is simply I am trying to make a video player and I have QTreeWidget with elements (folders & files) from given path on it. I want to make play video when double clicked on element in QTreeWidget.

# How I create tree, fill and detect double click.
self.tree = QTreeWidget()
self.load_project_structure("resources/videos", self.tree)
self.tree.itemDoubleClicked.connect(self.handler)

def load_project_structure(self, startpath, tree):
    for element in os.listdir(startpath):
        path_info = startpath + "/" + element
        parent_itm = QTreeWidgetItem(tree, [os.path.basename(element)])
        if os.path.isdir(path_info):
            self.load_project_structure(path_info, parent_itm)
            parent_itm.setIcon(0, QIcon('img/folder.png'))
        else:
            parent_itm.setIcon(0, QIcon('img/file.png'))

def handler(item, column_no):
    print(item, column_no)

My Tree is simply like that:

  • Folder_1
    • Folder_1.1
      • File_1.1.1.mp4
      • File_1.1.2.mp4
    • Folder 1.2

When I double click to File_1.1.2 I want to get something like that (and thats how I can play video):

Folder_1/Folder_1.1/File_1.1.2.mp4

but I got this:

<main.Window object at 0x00000275AC0FD558> PyQt5.QtWidgets.QTreeWidgetItem object at 0x00000275AC0FD828>

Any help is welcome. Thank you in advance


Solution

  • What you have to do is iterate over the parents of the items and concatenate them:

    def handler(self, item, column_no):
        texts = []
        while item is not None:
            texts.append(item.text(0))
            item = item.parent()
        path = "/".join(texts)
        print(path)
    

    Another simpler method is to use a role to store the full path

    def load_project_structure(self, startpath, tree):
        for element in os.listdir(startpath):
            path_info = os.path.join(startpath, element)
            parent_itm = QTreeWidgetItem(tree, [os.path.basename(element)])
            parent_itm.setData(0, Qt.UserRole, path_info)
            if os.path.isdir(path_info):
                self.load_project_structure(path_info, parent_itm)
                parent_itm.setIcon(0, QIcon('img/folder.png'))
            else:
                parent_itm.setIcon(0, QIcon('img/file.png'))
    
    def handler(self, item, column_no):
        print(item.data(0, Qt.UserRole))