Qt - QTreeView自动换行未生效

4

我在一些论坛中看到有关QTreeView的WordWrap不起作用(即文本显示超出屏幕)的讨论,但我找不到任何“hack”来解决这个问题。 bookTreeView被封装在另一个小部件中,这可能是问题所在...或者它只是不支持?

    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
您可以通过自己的项代理实现单元格内的自动换行。您需要重新实现sizeHint和paint函数。 - Kamil Klimek
1
这个问题已经解决了吗?已经过去将近五年了。这是一种显示目录结构的重要视图类型,在某些情况下,似乎自动换行会非常有用。 - eric
现在已经6年了,我正在寻找相同的东西!!Qt5.6 - Phiber
2个回答

1

我知道的唯一技巧 - 它可以在树形项目内部进行 QLable。


一样的情况..或者是一些疯狂的委托调用..所以就用QLabel吧,包括CSS;-) - PedroMorgan

0

正如评论者建议的那样,您可以使用自定义委托来实现此操作。不幸的是,QTreeView.setWordWrap(True)似乎没有效果(至少在Qt 4.8中)。作为对另一个问题的回答,我们使用自定义QStyledItemDelegate为QTreeView实现了换行功能:

在QTreeView(Qt/PySide/PyQt)中实现换行的委托?

这只是一种方法,还有其他好的方法,我相信,并且请注意,此示例非常基本,没有编辑器或类似的东西...

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()

尝试将您的代码移植到Python3 / PySide2 / Qt5,此处的尝试是否与您编写时的原始代码完全相同?在我的系统(Ubuntu 20.04)上,“Tickle nose…”文本被呈现在“Get a job”项目后面,而不调整行大小。 - Ruslan
抱歉Ruslan,我已经有一段时间没有使用Qt相关的东西了。 - eric

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接