Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyQt: How Can I set row heights of QTreeView

In PyQt, I am looking for a way to set the height of rows in a QTreeView (similarly to QTableView.setRowHeight(row, row_height), but QTreeView does not have this function). QAbstractItemModel is used to set the tree model. I read some suggestions here using and sub-classing QAbstractItemDelegate.sizeHint(option, index) but I don't know exactly how to call them correctly within my tree model.

Any minimal code or suggestion would be greatly appreciated. Thanks.

like image 965
Ben Avatar asked Aug 26 '15 14:08

Ben


1 Answers

The QTreeView works out a height for each row based on the data and size hints returned for each item. I think you probably just need to return size hints, either for all your items, or at least the first row (if you have setUniformRowHeights(True)). Incidentally this can significantly improve performance and so you should set it if you can.

So you just need to implement your AbstractItemModel.data() method to return a size hint in the SizeHintRole. Something like this:

def data(self, index, role = QtCore.Qt.DisplayRole):
    #  Check the index, possibly return None
    if role == QtCore.Qt.DisplayRole:
        # Return the data
    elif role == QtCore.Qt.SizeHintRole:
        return QtCore.QSize(item_width,item_height)
    # Other roles - maybe return None if you don't use them.

EDIT: Big example

You say you are still having trouble so here is a complete working example, based on the standard QT itemviews example. Try varying the QSize returned in the data method to see how the view changes:

import sys
from PySide import QtCore,QtGui

class TreeItem(object):
    def __init__(self, data, parent=None):
        self.parentItem = parent
        self.data = data
        self.childItems = []

    def appendChild(self, item):
        self.childItems.append(item)

    def row(self):
        if self.parentItem:
            return self.parentItem.childItems.index(self)
        return 0


class TreeModel(QtCore.QAbstractItemModel):
    def __init__(self, parent=None):
        super(TreeModel, self).__init__(parent)
        self.rootItem = TreeItem(None)
        for i,c in enumerate("abcdefg"):
            child = TreeItem([i,c],self.rootItem)
            self.rootItem.appendChild(child)
        parent = self.rootItem.childItems[1]
        child = TreeItem(["down","down"],parent)
        parent.appendChild(child)

    def columnCount(self, parent):
        return 2

    def data(self, index, role):
        if not index.isValid():
            return None
        if role == QtCore.Qt.DisplayRole:
            item = index.internalPointer()
            return item.data[index.column()]
        elif role == QtCore.Qt.SizeHintRole:
            print "giving size hint"
            return QtCore.QSize(40,40)

        return None


    def flags(self, index):
        if not index.isValid():
            return QtCore.Qt.NoItemFlags
        return QtCore.Qt.ItemIsEnabled | QtCore.Qt.ItemIsSelectable

    def headerData(self, section, orientation, role):
        if orientation == QtCore.Qt.Horizontal and role == QtCore.Qt.DisplayRole:
            return ["A","B"][section]
        return None

    def index(self, row, column, parent):
        if not self.hasIndex(row, column, parent):
            return QtCore.QModelIndex()

        if not parent.isValid():
            parentItem = self.rootItem
        else:
            parentItem = parent.internalPointer()

        childItem = parentItem.childItems[row]
        if childItem:
            return self.createIndex(row, column, childItem)
        else:
            return QtCore.QModelIndex()

    def parent(self, index):
        if not index.isValid():
            return QtCore.QModelIndex()
        parentItem = index.internalPointer().parentItem
        if parentItem == self.rootItem:
            return QtCore.QModelIndex()
        return self.createIndex(parentItem.row(), 0, parentItem)

    def rowCount(self, parent):
        if parent.column() > 0:
            return 0
        if not parent.isValid():
            parentItem = self.rootItem
        else:
            parentItem = parent.internalPointer()
        return len(parentItem.childItems)



if __name__ == '__main__':

    app = QtGui.QApplication(sys.argv)
    model = TreeModel()

    view = QtGui.QTreeView()
    view.setModel(model)
    view.setWindowTitle("Simple Tree Model")
    view.show()
    sys.exit(app.exec_())
like image 155
strubbly Avatar answered Sep 20 '22 21:09

strubbly