Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

QTreeview change icon on row Icon click

How can I trigger the changing of an icon when the user clicks the Icon only for the items/rows in the list which are of type File. Each row in the treeview contains an object in the UserRole called TreeItem which stores if the item is marked as a favorite and also the filepath.

In short is there a way to know if a the Decoration 'icon' is clicked by the user?

The tool simply just goes through a directory recursively and collects the files and folders.

class TreeItem(object):
    def __init__(self, filepath):
        self.filepath = filepath
        self.isFavorite = False

Dropbox links to icons

https://www.dropbox.com/s/3pt0ev2un7eoswh/file_off.svg?dl=0 https://www.dropbox.com/s/xext3m9d4atd3i6/file_on.svg?dl=0 https://www.dropbox.com/s/6d750av0y77hq0g/folder.svg?dl=0

enter image description here

Be sure to change the directory path for testing

Tool Code:

import sys
import os
from PySide import QtGui, QtCore, QtSvg

DIR_ICON_PATH = 'folder.svg'
FILE_ICON_OFF = 'file_off.svg'
FILE_ICON_ON = 'file_on.svg'

class TreeItem(object):
    def __init__(self, filepath):
        self.filepath = filepath
        self.isFavorite = False

class Example(QtGui.QWidget):
    def __init__(self):
        super(Example, self).__init__()
        self.initUI()

    def initUI(self):      
        # formatting
        self.resize(550, 400)
        self.setWindowTitle("Toychest")

        # widgets
        self.treeview = QtGui.QTreeView()
        self.treeview.setHeaderHidden(True)
        self.treeview.setUniformRowHeights(True)
        self.treeview.setEditTriggers(QtGui.QAbstractItemView.NoEditTriggers)
        self.source_model = QtGui.QStandardItemModel()
        self.treeview.setModel(self.source_model)

        # signals
        self.treeview.doubleClicked.connect(self.doubleClickedItem)

        # main layout
        mainLayout = QtGui.QGridLayout()
        mainLayout.setContentsMargins(0,0,0,0)
        mainLayout.addWidget(self.treeview)
        self.setLayout(mainLayout)

        self.initDirectory('C:/Users/jmartini/Downloads')

# Functions
# ------------------------------------------------------------------------------
    def initDirectory(self, path):
        new_item = self.newItem(path)
        self.readDirectory(path, new_item)
        self.source_model.appendRow(new_item)

    def readDirectory(self, path, parent_item):
        directory = os.listdir(path)
        for file_name in directory:
            file_path = path + '/' + file_name
            new_item = self.newItem(file_path)
            parent_item.appendRow(new_item)
            if os.path.isdir(file_path):
                self.readDirectory(file_path, new_item)

    def newItem(self, path):
        # create Object
        obj = TreeItem(path)

        title = os.path.basename(path)
        item = QtGui.QStandardItem()
        item.setData(obj, role=QtCore.Qt.UserRole)
        icon_path = FILE_ICON_OFF
        if os.path.isdir(path):
            icon_path = DIR_ICON_PATH
        icon = QtGui.QIcon(icon_path)
        item.setText(title)
        item.setIcon(icon)
        return item

    def doubleClickedItem(self, idx):
        if not idx.isValid():
            return
        obj = idx.data(QtCore.Qt.UserRole)
        print obj.filepath, obj.isFavorite
        # print idx.parent(), idx.parent().isValid()
        # model = idx.model()
        # print model.index(idx.row(), 0, parent=idx.parent()).data()


# Main
# ------------------------------------------------------------------------------
if __name__ == '__main__':
    app = QtGui.QApplication(sys.argv)
    ex = Example()
    ex.show()
    sys.exit(app.exec_())
like image 687
JokerMartini Avatar asked Jul 11 '17 13:07

JokerMartini


1 Answers

You have to implement the mousePressEvent and compare the mouse position with icon position and proceed accordingly.

like image 187
Balu Avatar answered Nov 12 '22 03:11

Balu