QTreeview изменить значок в строке Icon click
Как я могу инициировать изменение значка, когда пользователь щелкает значок только для элементов / строк в списке, которые имеют тип File. Каждая строка в древовидной структуре содержит объект в UserRole с именем TreeItem, который сохраняет, если элемент отмечен как избранный, а также путь к файлу.
Короче говоря, есть ли способ узнать, нажал ли пользователь значок "Украшение"?
Инструмент просто рекурсивно просматривает каталог и собирает файлы и папки.
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_())
2 ответа
Вы должны реализовать mousePressEvent
и сравните положение мыши с положением значка и действуйте соответственно.
Ты можешь использовать 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
чтобы проверить, соответствует ли выбранный элемент файлу.