Back to Blog home

Multi-threaded text layout and printing

Published on Thursday September 27, 2007 by Bradley T. Hughes in Qt Painting Threads | Comments

I just integrated a series of changes that adds support for doing multi-threaded text layout and printing. So it is now safe to use QFont and QFontMetrics outside the GUI thread. This means QPainter::drawText() works too (when painting on QImage, QPrinter, and QPicture). We've also done changes to QTextDocument that allow it to be cloned and passed off to a thread, so that all the layouting and printing happens without blocking the GUI.

For those interested, you can checkout tonight's 4.4 snapshot. In tools/assistant/mainwindow.cpp, you'll see code like this:

void PrintThread::start(QTextDocument *document)
{
_document = document->clone();
_document->moveToThread(this);
QThread::start();
}

void PrintThread::run()
{
_document->print(printer());
delete _document;
_document = 0;
}

void MainWindow::on_actionFilePrint_triggered()
{
if (!QFontDatabase::supportsThreadedFontRendering()) {
QPrinter printer(QPrinter::HighResolution);
printer.setFullPage(true);

QPrintDialog dlg(&printer, this);
if (dlg.exec() == QDialog::Accepted) {
qApp->setOverrideCursor(Qt::WaitCursor);
tabs->currentBrowser()->document()->print(&printer);
qApp->restoreOverrideCursor();
}
return;
}

PrintThread *thread = new PrintThread(this);

QPrintDialog dlg(thread->printer(), this);
if (dlg.exec() == QDialog::Accepted) {
connect(thread, SIGNAL(finished()), SLOT(printingFinished()));
connect(thread, SIGNAL(finished()), thread, SLOT(deleteLater()));

qApp->setOverrideCursor(Qt::BusyCursor);
thread->start(tabs->currentBrowser()->document());
} else {
delete thread;
}
}

void MainWindow::printingFinished()
{
qApp->restoreOverrideCursor();
}

The Thread Support in Qt documentation has also been updated to show what is supported (Note, at the time of writing, the snapshot documentation has not been updated, check back later if you don't have a 4.4 snapshot after 27 Sep 2007).

And just to be clear, painting onto a QPixmap or a QWidget outside the GUI is not supported at all. We are looking at ways of making the GL paint engine safe for painting on to FrameBufferObjects and/or Pbuffers, which may or may not make it into 4.4.

Subscribe to Our Blog

Stay up to date with the latest marketing, sales and service tips and news.

The blog comment system has been migrated to a new platform. If you face any issues, please let us know via feedback@qt.io.