4

I have been reading in some of the forums about WordWrap not working for QTreeView (as in the text displays off screen), but I couldn't find any "hack" that fixed this. The bookTreeView is encapsulated inside another widget, this may be the problem...or it's just not supported?

    bookTreeView->setModel(standardModel);
    bookTreeView->setEditTriggers(QAbstractItemView::NoEditTriggers);
    bookTreeView->setWordWrap(true);
    bookTreeView->sizeHint();
    bookTreeView->setTextElideMode(Qt::ElideNone);
    bookTreeView->setExpandsOnDoubleClick(true);
    bookTreeView->setUniformRowHeights(true);
    bookTreeView->setHeaderHidden(true);
    bookTreeView->setStyleSheet("QTreeView { font-size: 27px; show-decoration-selected: 0; } QTreeView::branch:has-siblings:!adjoins-item { border-image: none; } QTreeView::branch:has-siblings:adjoins-item { border-image: none; } QTreeView::branch:!has-children:!has-siblings:adjoins-item { border-image: none;} QTreeView::branch:has-children:!has-siblings:closed, QTreeView::branch:closed:has-children:has-siblings { border-image: none; image: url(':images/images/right_arrow.png'); } QTreeView::branch:open:has-children:!has-siblings, QTreeView::branch:open:has-children:has-siblings  { border-image: none; image: url(':images/images/down_arrow.png'); } ");

    QVBoxLayout *layout = new QVBoxLayout;
    layout->addWidget(someWidget);
    layout->addWidget(bookTreeView);

    QWidget *page = new QWidget;
    page->setLayout(layout);

    return page;
  • 3
    You can achieve word wrap inside cell with your own item delegate. You will have to reimplement sizeHint and paint methods – Kamil Klimek Dec 08 '10 at 08:29
  • 1
    Has this been fixed? It's been almost five years. This is an important view type for displaying directory structures, seems like word wrap would be really useful in some contexts. – eric Nov 10 '15 at 13:55
  • 6 years now and I'm looking for the same things !! Qt5.6 – Phiber Jul 13 '17 at 13:51

2 Answers2

1

Only hack I know - it's QLable inside Tree Item.

RazrFalcon
  • 787
  • 7
  • 17
0

As suggested by a commenter, you can do this using a custom delegate. Unfortunately, QTreeView.setWordWrap(True) seems to have no effect (at least in Qt 4.8). In response to another question, we implemented word wrap functionality using a custom QStyledItemDelegate for a QTreeView:

Implementing a delegate for wordwrap in a QTreeView (Qt/PySide/PyQt)?

This is just one way to do it, there are other good ways I'm sure, and note this example is very basic, no editors or anything like that...

import sys
from PySide import QtGui, QtCore

class SimpleTree(QtGui.QTreeView):
    def __init__(self, parent = None):    
        QtGui.QTreeView.__init__(self, parent)
        self.setAttribute(QtCore.Qt.WA_DeleteOnClose)
        self.setGeometry(500,200, 400, 300)  
        self.setUniformRowHeights(False) #optimize: but for word wrap, we don't want this!
        self.model = QtGui.QStandardItemModel()
        self.model.setHorizontalHeaderLabels(['Task', 'Description'])
        self.setModel(self.model)
        self.rootItem = self.model.invisibleRootItem()
        item0 = [QtGui.QStandardItem('Sneeze'), QtGui.QStandardItem('You have been blocked up')]
        item00 = [QtGui.QStandardItem('Tickle nose, this is a very long entry. Row should resize.'), QtGui.QStandardItem('Key first step')]
        item1 = [QtGui.QStandardItem('<b>Get a job</b>'), QtGui.QStandardItem('Do not blow it')]
        item2  = [QtGui.QStandardItem("Now let's see how this one works. It is medium."), QtGui.QStandardItem('Do not blow it')]       
        self.rootItem.appendRow(item0)
        item0[0].appendRow(item00) 
        self.rootItem.appendRow(item1)
        self.rootItem.appendRow(item2)
        self.setColumnWidth(0,150)
        self.expandAll()
        self.setItemDelegate(ItemWordWrap(self))

class ItemWordWrap(QtGui.QStyledItemDelegate):
    def __init__(self, parent=None):
        QtGui.QStyledItemDelegate.__init__(self, parent)
        self.parent = parent
        
    def paint(self, painter, option, index):
        text = index.model().data(index) 
        document = QtGui.QTextDocument() # #print "dir(document)", dir(document)
        document.setHtml(text)       
        document.setTextWidth(option.rect.width())  #keeps text from spilling over into adjacent rect
        index.model().setData(index, option.rect.width(), QtCore.Qt.UserRole+1)
        painter.save() 
        painter.translate(option.rect.x(), option.rect.y()) 
        document.drawContents(painter)  #draw the document with the painter
        painter.restore()
        
    def sizeHint(self, option, index):
        #Size should depend on number of lines wrapped
        text = index.model().data(index)
        document = QtGui.QTextDocument()
        document.setHtml(text) 
        width = index.model().data(index, QtCore.Qt.UserRole+1)
        if not width:
            width = 20
        document.setTextWidth(width) 
        return QtCore.QSize(document.idealWidth() + 10,  document.size().height())       

def main():
    app = QtGui.QApplication(sys.argv)
    myTree = SimpleTree()
    myTree.show()
    sys.exit(app.exec_())
    
if __name__ == "__main__":
    main()
Ruslan
  • 18,162
  • 8
  • 67
  • 136
eric
  • 7,142
  • 12
  • 72
  • 138
  • Does [this attempt at porting your code to Python3/PySide2/Qt5](https://pastebin.com/raXwWXnZ) work exactly as your original code worked when you wrote it? On my system (Ubuntu 20.04) the "Tickle nose..." text gets rendered behind the "Get a job" item, without resizing the row. – Ruslan Nov 14 '20 at 15:40
  • Sorry Ruslan I haven't done much with Qt stuff in a while. – eric Nov 15 '20 at 20:15