2014-09-01 291 views
0

我的目的是在树状列表中显示不同的图标当特定位置(行,列)匹配值时。例如:(行,2)是目录或文件,将显示不同的图标。因为这不在本地文件系统中使用,所以QDir或Qfilesystem模型不适用于此。如何委托PyQt中的特定位置(行,列)QTreeView

我知道MVC上的一点控制器显示在视图中,使模型作为数据接口API。但我不知道如何让它在特定位置(row,col)工作,正如我所期望的那样。

我试图在ImageDelegate中添加参数(如通过图标文件名称),但可能由于其父类不接受更多的参数而失败。希望有人能给我点亮。

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

如果我理解你是正确的,你只是希望colunm 4中的图标(我假设每行有一个图标?)取决于第2列的内容?如果是这种情况,你根本不需要委托。你只需要改变模型的行为方式。你能提供一些代码来显示你的模型的实现吗? – 2014-09-02 02:52:37

回答

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,但不同的是,仅设定值。

如果你想在某些索引(在这种情况下:第二)通过路径显示图像。你可以通过使用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。

+1

是的,我知道如何使用基本的setDelegateForColumn,我的问题是,我在TreeView中有4列显示,第4列显示图标,但实际上我需要在第2列值显示不同的基本图标。 treewidget也许有点容易把图标,我卡在树视图 – soneedu 2014-09-02 02:01:22

+0

好吧,对不起,错误的问题。请阅读我最后的回答。 – 2014-09-02 08:59:11

+0

感谢,QstandarditemModel,应该很容易和coorect方式来做到这一点。感谢你的样品。 – soneedu 2014-09-04 03:24:43