QTreeview change icon on line Icon click

How can I cause the icon to change when the user clicks the icon only for items / rows in the list that are of type File. Each row in the tree contains an object in a UserRole called a TreeItem that stores, if the item is marked as a favorite, as well as the path to the file.

In short, is there a way to tell if the user has clicked the Decoration icon?

The tool just simply loops over the directory recursively and collects files and folders.

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

      

Links to Dropbox for badges

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

Make 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_())

      

+3


source to share


2 answers


You need to implement mousePressEvent

and compare the position of the mouse with the position of the icon and proceed accordingly.



+1


source


You can use QStandardItemModel.itemFromIndex

to access the base item. The model can be obtained through QModelIndex.model

. So the following:

item = idx.model().itemFromIndex(idx)
obj = idx.data(QtCore.Qt.UserRole).toPyObject()
obj.isFavorite = (obj.isFavorite + 1) % 2
if obj.isFavorite:
    item.setIcon(QtGui.QIcon(FILE_ICON_ON))
else:
    item.setIcon(QtGui.QIcon(FILE_ICON_OFF))

      



Optionally, you can access to obj.filepath

check if the element associated with the click matches the file.

0


source







All Articles