我的目的是在特定位置(行,列)与值匹配时,在树视图列表中显示不同的图标。例如:(row,2)是dir或file,将显示不同的图标。因为这不用于本地文件系统,QDir或Qfilesystem模型不适用于此。
我知道MVC中有一点控制器在视图中显示,使模型成为数据接口api。但我不知道如何使它适用于我所期望的特定位置(行,col)。
我试图在ImageDelegate中添加args(就像传递图标文件名一样),但失败可能是因为它的父类不接受更多的args。 希望有人能给我一些启示。
class ImageDelegate(QtGui.QStyledItemDelegate):
def __init__(self, parent=None):
QtGui.QStyledItemDelegate.__init__(self, parent)
#self.icon =icon
def paint(self, painter, option, index):
#painter.fillRect(option.rect, QtGui.QColor(191,222,185))
# path = "path\to\my\image.jpg"
path = "icon1.png"
image = QtGui.QImage(str(path))
pixmap = QtGui.QPixmap.fromImage(image)
pixmap.scaled(16, 16, QtCore.Qt.KeepAspectRatio)
painter.drawPixmap(option.rect.x(), option.rect.y(), pixmap)
我可以在我的视图中使用此委托。但它会改变特定栏目中的所有行。
def init_remotetreeview(self):
self.model = myModel(self.remote_Treeview)
for therow in range(self.model.rowCount(QModelIndex())) :
print self.model.data(self.model.index(therow, 2, QtCore.QModelIndex()),Qt.DisplayRole).toString() # i do check the value will used to load correct icon.
self.remote_Treeview.setItemDelegate(ImageDelegate(self)) # this change all lines
self.remote_Treeview.setModel(self.model)
答案 0 :(得分:2)
事实上,您的代码中有some light
,不是吗? (开个玩笑。)
您有正确的方式使用QtGui.QStyledItemDelegate
。我已经参考了如何实现它(但是,仅限C ++)。 'Star Delegate Example','QItemDelegate Class Reference C++'和'QItemDelegate Class Reference PyQt4';
关键字:您必须实现paint
绘制您想要的元素(我认为这是您想要的。)
很少的例子,希望是有帮助的;
import sys
from PyQt4 import QtCore, QtGui
from functools import partial
class QCustomDelegate (QtGui.QItemDelegate):
signalNewPath = QtCore.pyqtSignal(object)
def createEditor (self, parentQWidget, optionQStyleOptionViewItem, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
editorQWidget = QtGui.QPushButton(parentQWidget)
editorQWidget.released.connect(partial(self.requestNewPath, indexQModelIndex))
return editorQWidget
else:
return QtGui.QItemDelegate.createEditor(self, parentQWidget, optionQStyleOptionViewItem, indexQModelIndex)
def setEditorData (self, editorQWidget, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
textQString = indexQModelIndex.model().data(indexQModelIndex, QtCore.Qt.EditRole).toString()
editorQWidget.setText(textQString)
else:
QtGui.QItemDelegate.setEditorData(self, editorQWidget, indexQModelIndex)
def setModelData (self, editorQWidget, modelQAbstractItemModel, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
textQString = editorQWidget.text()
modelQAbstractItemModel.setData(indexQModelIndex, textQString, QtCore.Qt.EditRole)
else:
QtGui.QItemDelegate.setModelData(self, editorQWidget, modelQAbstractItemModel, indexQModelIndex)
def updateEditorGeometry(self, editorQWidget, optionQStyleOptionViewItem, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
editorQWidget.setGeometry(optionQStyleOptionViewItem.rect)
else:
QtGui.QItemDelegate.updateEditorGeometry(self, editorQWidget, optionQStyleOptionViewItem, indexQModelIndex)
def requestNewPath (self, indexQModelIndex):
self.signalNewPath.emit(indexQModelIndex)
def paint (self, painterQPainter, optionQStyleOptionViewItem, indexQModelIndex):
column = indexQModelIndex.column()
if column == 0:
textQString = indexQModelIndex.model().data(indexQModelIndex, QtCore.Qt.EditRole).toString()
painterQPainter.drawPixmap (
optionQStyleOptionViewItem.rect.x(),
optionQStyleOptionViewItem.rect.y(),
QtGui.QPixmap(textQString).scaled(180, 180, QtCore.Qt.KeepAspectRatio))
else:
QtGui.QItemDelegate.paint(self, painterQPainter, optionQStyleOptionViewItem, indexQModelIndex)
class QCustomTreeWidget (QtGui.QTreeWidget):
def __init__(self, parent = None):
super(QCustomTreeWidget, self).__init__(parent)
self.setColumnCount(1)
myQCustomDelegate = QCustomDelegate()
self.setItemDelegate(myQCustomDelegate)
myQCustomDelegate.signalNewPath.connect(self.getNewPath)
def addMenu (self, path, parentQTreeWidgetItem = None):
if parentQTreeWidgetItem == None:
parentQTreeWidgetItem = self.invisibleRootItem()
currentQTreeWidgetItem = QtGui.QTreeWidgetItem(parentQTreeWidgetItem)
currentQTreeWidgetItem.setData(0, QtCore.Qt.EditRole, path)
currentQTreeWidgetItem.setFlags(currentQTreeWidgetItem.flags() | QtCore.Qt.ItemIsEditable)
for i in range(self.columnCount()):
currentQSize = currentQTreeWidgetItem.sizeHint(i)
currentQTreeWidgetItem.setSizeHint(i, QtCore.QSize(currentQSize.width(), currentQSize.height() + 200))
def getNewPath (self, indexQModelIndex):
currentQTreeWidgetItem = self.itemFromIndex(indexQModelIndex)
pathQStringList = QtGui.QFileDialog.getOpenFileNames()
if pathQStringList.count() > 0:
textQString = pathQStringList.first()
currentQTreeWidgetItem.setData(indexQModelIndex.column(), QtCore.Qt.EditRole, textQString)
print textQString
class QCustomQWidget (QtGui.QWidget):
def __init__ (self, parent = None):
super(QCustomQWidget, self).__init__(parent)
self.myQCustomTreeWidget = QCustomTreeWidget(self)
self.allQHBoxLayout = QtGui.QHBoxLayout()
self.allQHBoxLayout.addWidget(self.myQCustomTreeWidget)
self.setLayout(self.allQHBoxLayout)
self.myQCustomTreeWidget.addMenu(r'''C:\Users\Kitsune Meyoko\Desktop\twitter01.jpg''')
self.myQCustomTreeWidget.addMenu(r'''C:\Users\Kitsune Meyoko\Desktop\twitter02.jpg''')
self.myQCustomTreeWidget.addMenu(r'''C:\Users\Kitsune Meyoko\Desktop\twitter04.jpg''')
self.myQCustomTreeWidget.addMenu(r'''C:\Users\Kitsune Meyoko\Desktop\twitter05.jpg''')
app = QtGui.QApplication([])
myQCustomQWidget = QCustomQWidget()
myQCustomQWidget.show()
sys.exit(app.exec_())
注意:以同样的方式实现QTreeView
,但只有设置值不同。
如果您想在某个索引中按路径显示图像(在本例中为第2个)。你可以使用QModelIndex QAbstractItemModel.index (self, int row, int column, QModelIndex parent = QModelIndex())找到它,并且想要你想要的。
实施例
import sys
from PyQt4 import QtCore, QtGui
class QCustomDelegate (QtGui.QItemDelegate):
def paint (self, painterQPainter, optionQStyleOptionViewItem, indexQModelIndex):
column = indexQModelIndex.column()
if column == 3:
currentQAbstractItemModel = indexQModelIndex.model()
iconQModelIndex = currentQAbstractItemModel.index(indexQModelIndex.row(), 1, indexQModelIndex.parent())
pathQString = currentQAbstractItemModel.data(iconQModelIndex, QtCore.Qt.EditRole).toString()
iconQPixmap = QtGui.QPixmap(pathQString)
if not iconQPixmap.isNull():
painterQPainter.drawPixmap (
optionQStyleOptionViewItem.rect.x(),
optionQStyleOptionViewItem.rect.y(),
iconQPixmap.scaled(20, 20, QtCore.Qt.KeepAspectRatio))
else:
QtGui.QItemDelegate.paint(self, painterQPainter, optionQStyleOptionViewItem, indexQModelIndex)
myQApplication = QtGui.QApplication([])
myQTreeView = QtGui.QTreeView()
headerQStandardItemModel = QtGui.QStandardItemModel()
headerQStandardItemModel.setHorizontalHeaderLabels([''] * 4)
myQTreeView.setModel(headerQStandardItemModel)
# Set delegate
myQCustomDelegate = QCustomDelegate()
myQTreeView.setItemDelegate(myQCustomDelegate)
# Append data row 1
row1QStandardItem = QtGui.QStandardItem('ROW 1')
row1QStandardItem.appendRow([QtGui.QStandardItem(''), QtGui.QStandardItem('1.jpg'), QtGui.QStandardItem(''), QtGui.QStandardItem('')])
headerQStandardItemModel.appendRow(row1QStandardItem)
# Append data row 2
row2QStandardItem = QtGui.QStandardItem('ROW 2')
row2QStandardItem.appendRow([QtGui.QStandardItem(''), QtGui.QStandardItem('2.png'), QtGui.QStandardItem(''), QtGui.QStandardItem('')])
headerQStandardItemModel.appendRow(row2QStandardItem)
myQTreeView.show()
sys.exit(myQApplication.exec_())
实验结果:
注意:我有图像1.jpg,2.png。