行上的QTreeview更改图标单击图标

时间:2017-07-11 13:08:02

标签: python pyside qtreeview

当用户仅针对列表中属于File类型的项目/行单击Icon时,如何触发更改图标。树视图中的每一行都包含一个名为TreeItem的UserRole中的对象,该对象存储项目是否被标记为收藏夹以及文件路径。

简而言之,有一种方法可以知道用户是否点击了装饰'图标'?

该工具只是递归地遍历目录并收集文件和文件夹。

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

Dropbox指向图标的链接

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

请务必更改测试的目录路径

工具代码:

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

2 个答案:

答案 0 :(得分:1)

您必须实施mousePressEvent并将鼠标位置与图标位置进行比较并相应地进行。

答案 1 :(得分:0)

您可以使用QStandardItemModel.itemFromIndex来访问基础项目。该模型可以通过QModelIndex.model获得。所以下面会这样做:

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))

如果需要,您可以访问obj.filepath以检查点击的项目是否与文件相对应。