当用户仅针对列表中属于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
请务必更改测试的目录路径
工具代码:
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_())
答案 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
以检查点击的项目是否与文件相对应。