Implementing a delegate for wordwrap in a QTreeView (Qt/PySide/PyQt)? -
i have tree view custom delegate trying add word wrap functionality. word wrapping working fine, sizehint() seems not work, when text wraps, relevant row not expand include it.
i thought taking care of in sizehint() returning document.size().height().
def sizehint(self, option, index): text = index.model().data(index) document = qtgui.qtextdocument() document.sethtml(text) document.settextwidth(option.rect.width()) return qtcore.qsize(document.idealwidth(), document.size().height()) however, when print out document.size().height() same every item.
also, if manually set height (say, 75) check things reasonable, tree looks goldfish got shot bazooka (that is, it's mess):
as can see, text in each row not aligned in tree.
similar posts
similar issues have come before, no solutions problem (people reimplement sizehint(), , that's trying):
qtreewidget set height of each row depending on content
qtreeview custom row height of individual rows
http://www.qtcentre.org/threads/1289-qt4-qtreeview-and-rows-with-multiple-lines
sscce
import sys 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: word wrap, don't want this! print "uniform heights in tree?", self.uniformrowheights() 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, long entry. row should resize.'), qtgui.qstandarditem('key first step')] item1 = [qtgui.qstandarditem('<b>get job</b>'), qtgui.qstandarditem('do not blow it')] self.rootitem.appendrow(item0) item0[0].appendrow(item00) self.rootitem.appendrow(item1) self.setcolumnwidth(0,150) self.expandall() self.setwordwrap(true) 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 spilling on adjacent rect painter.save() painter.translate(option.rect.x(), option.rect.y()) document.drawcontents(painter) #draw document 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) document.settextwidth(option.rect.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()
the issue seems stem fact value option.rect.width() passed qstyleditemdelegate.sizehint() -1. bogus!
i've solved storing width in model within paint() method , accessing sizehint().
so in paint() method add line:
index.model().setdata(index, option.rect.width(), qtcore.qt.userrole+1) and in sizehint() method, replace document.settextwidth(option.rect.width()) with:
width = index.model().data(index, qtcore.qt.userrole+1) if not width: width = 20 document.settextwidth(width) 
Comments
Post a Comment