PDA

View Full Version : QTextDocuments and QPlainTextEdits



JordyD
8th July 2009, 15:52
I'm using Qt Creator with Qt4. That's what I use to compile, build, and design the interface. This is in C++.

I have a simple problem. When I try to call setDocument on a QPlainTextEdit, it will compile, but during runtime, when I open a file it says:

QPlainTextEdit::setDocument: Document set does not support QPlainTextDocumentLayout

Here's the snippet of code that does this:

void CodeView::loadFile(QString filename)
{
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QString text = file.readAll();
QTextDocument document;
document.setPlainText(text);
ui->plainTextEdit->setDocument(&document);
}
file.close();
}

If I call the setPlainText method on my QTextDocument, should it not already be in QPlainTextDocumentLayout?

Thanks,
Jordy

nish
8th July 2009, 16:16
i think you should create the QTextDocument on heap instead of stack


QTextDocument* document = new QTextDocument(ui->plainTextEdit) ;
document->setPlainText(text);
ui->plainTextEdit->setDocument(document);

JordyD
8th July 2009, 16:29
Thank you for the tip, although it doesn't fix the problem and I still get the same error.

EDIT: This is my new function definition, by the way:

void CodeView::loadFile(QString filename)
{
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QString text = file.readAll();
QTextDocument *document = new QTextDocument(ui->plainTextEdit);
document->setPlainText(text);
ui->plainTextEdit->setDocument(document);
}
file.close();
}

Lykurg
8th July 2009, 18:41
Why do you want to set a QTextDocument anyway? Simple us:

void CodeView::loadFile(QString filename)
{
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
ui->plainTextEdit->setPlainText(file.readAll());
file.close();
}
}

Lykurg
8th July 2009, 18:45
äh, and to your original question:

when I open a file it says:

QPlainTextEdit::setDocument: Document set does not support QPlainTextDocumentLayout
see the docs where you can read:

The document must have a document layout that inherits QPlainTextDocumentLayout (see QTextDocument::setDocumentLayout()).
and you havn't set this.

JordyD
8th July 2009, 18:51
Why do you want to set a QTextDocument anyway? Simple us:

void CodeView::loadFile(QString filename)
{
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
ui->plainTextEdit->setPlainText(file.readAll());
file.close();
}
}

I also have a class that inherits from QSyntaxHighlighter, and it only accepts QTextDocuments to highlight.

JordyD
8th July 2009, 19:00
Thanks! I got it now.

Here's what it looks like:

void CodeView::loadFile(QString filename)
{
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
QString text = file.readAll();
QTextDocument *document = new QTextDocument(ui->plainTextEdit);
document->setPlainText(text);
QPlainTextDocumentLayout *layout = new QPlainTextDocumentLayout(document);
document->setDocumentLayout(layout);
ui->plainTextEdit->setDocument(document);
}
file.close();
}

Lykurg
8th July 2009, 19:31
I also have a class that inherits from QSyntaxHighlighter, and it only accepts QTextDocuments to highlight.
Might be, but in your function you create a local document and set it and then forget about it. And there is no need to do so. Really, better use setPlainText(). This also creates/alters the existing document. For your other class you can still use document().

EDIT: but if you really want use this, instead of creating a new one, just use the old one!

JordyD
8th July 2009, 19:49
Might be, but in your function you create a local document and set it and then forget about it. And there is no need to do so. Really, better use setPlainText(). This also creates/alters the existing document. For your other class you can still use document().

EDIT: but if you really want use this, instead of creating a new one, just use the old one!

I took that advice, and now my function is like this:

void CodeView::loadFile(QString filename)
{
QFile file(filename);
if (file.open(QIODevice::ReadOnly | QIODevice::Text)) {
ui->plainTextEdit->setPlainText(file.readAll());
}
file.close();
}

Question: Where do I throw the highlighter initialization (
Highlighter highlighter(ui->plainTextEdit->document());)? CodeView's constructor?

faldzip
8th July 2009, 20:07
wherever but only if you create it on heap:

new SuperDuperHighlighter(ui->plainTextEdit->document())
because QTextDocument becomes a parent so will delete highlighter in destructor.
And the parent of QTextDocument (QPlainTextEdit would be my guess) will delete QTextDocument, and so on, so if you just take care of passing parents correctly then you can make on stack only MainWindow and it would be grandgrandgrand...parent to any object so they can be created on heap and would be deleted at the end of main().

JordyD
8th July 2009, 20:38
wherever but only if you create it on heap:

new SuperDuperHighlighter(ui->plainTextEdit->document())
because QTextDocument becomes a parent so will delete highlighter in destructor.
And the parent of QTextDocument (QPlainTextEdit would be my guess) will delete QTextDocument, and so on, so if you just take care of passing parents correctly then you can make on stack only MainWindow and it would be grandgrandgrand...parent to any object so they can be created on heap and would be deleted at the end of main().
Neat.

I'll put it in CodeView's constructor, so whenever the contents are re-loaded it will be called to highlight.