PDA

View Full Version : QTextDocument Manual Line Breaks



mihnen
11th September 2012, 05:08
I have a QGraphicsTextItem that I am autosizing the font in, I can't let the document() line break automatically because in order to do my alignment i need to setTextWidth(boundingRect.width()) which makes it break when I don't want it to.

The expected behavior should be to autosize as large as possible and then shrink until the minimum font size is hit, then I want to insert a linebreak.

The way I am currently implementing this autosizing is by using fontmetrics inside of the documents contentsChange(int,int,int) handler and it causes a recursive loop by trying to insert a "\n"



if((f.pointSizeF() * factor) < m_minFontSize) {
f.setPointSizeF(m_minFontSize);
text.append("\n");
disconnect(this->document(), SIGNAL(contentsChange(int,int,int)),
this, SLOT(contentsChangedHandler(int,int,int)));
this->setPlainText(text);
connect(this->document(), SIGNAL(contentsChange(int,int,int)),
this, SLOT(contentsChangedHandler(int,int,int)));
}


I have tried both blockSignals(true) blockSignals(false) wrapper and a disconnect and connnect wrapper and neither one stops the recursion. What is the normal way to implement manual line wrapping in a textdocument?

mihnen
11th September 2012, 15:26
After looking into this for awhile it looks like it might be possible to do line breaking (word wrap) by reimplementing QAbstractTextDocument, however that looks like a lot of work with all of those virtual functions and not much documentation. Is there any easier way?

I would hate to have to reimplement all that code when all I want is access to do line breaks. What is class is the default layout for a QGraphicsTextItem, there has to be something derived from QAbstractTextDocument that I could subclass and override the documentChanged() instead of the abstract interface.

mihnen
11th September 2012, 17:45
Well I kind of got this figured out, guess I should read the documentation better. You need to use textCursor() to make modifications to the document. However now the line wrapping works but whenever you hit backspace it crashes in QTextLayout::lineCount(). Is this a bug in Qt?

here is what shows in gdb:

Program received signal SIGSEGV, Segmentation fault.
QTextLayout::lineCount (this=0x0) at text/qtextlayout.cpp:841
841 return d->lines.size();



if((f.pointSizeF() * factor) < m_minFontSize)
{
QTextCursor c(this->document());
f.setPointSizeF(m_minFontSize);

if(!c.isNull() )
{
c.movePosition(QTextCursor::End);
c.select(QTextCursor::LineUnderCursor);
QString lineText = c.selectedText();
qDebug() << "lineText: " << lineText;
qDebug() << "lineCount(): " << this->document()->lineCount();
c.clearSelection();
QFontMetrics fm2(f);

if(fm2.boundingRect(lineText).width() >= drawRect.width())
{
//c.insertText("\n");
c.insertBlock();
c.movePosition(QTextCursor::End);
}
}
}