Sharma, Ashish wrote:

Hello,

I am using Qt webkit Jambi API's to convert HTML to PDF.

My target is to create a jar for above conversion so that it could be used in a multithreading environment, but since QWebPage and QWebframe (QT webkit) are GUI classes, therefore the jar classes cannot be initialized from child threads.


It's true that certain actions are restricted to the gui thread (such as using widgets), but painting to a printer is allowed, as described here:

http://doc.trolltech.com/qtjambi-4.5.0_01/com/trolltech/qt/qtjambi-threads.html#painting-in-threads

A restriction on QWebPage is that it has to be constructed in the GUI thread, since it accesses QApplication. However, you can use QObject.moveToThread() to move QObjects over to a different thread than the one that created it.

See the attached example of how to make a thread-based web page renderer that renders into a .pdf. (it's a quick&dirty example, so please excuse any bugs, but it should at least illustrate how to achieve what you need.)

The example makes a widget which monitors the progress of loading the web page. The QWebPage is constructed in the gui thread, and made a child of the runnable object. Then the entire hierarchy is moved to the thread in question. The run() method in the runnable starts loading the web page, and when it completes, the web page is rendered into a .pdf-printer and the application is shut down.

Also i am a novice in QT , can anyone provide good reference about QT application's lifecycle, event loops and related stuff.


Threads and event loops are described here:

http://doc.trolltech.com/qtjambi-4.5.0_01/com/trolltech/qt/qtjambi-threads.html

And here are a few whitepapers which may contain more information:

   https://www.qtsoftware.com/files/pdf

-- Eskil


package com.trolltech.test;

import com.trolltech.qt.*;
import com.trolltech.qt.core.*;
import com.trolltech.qt.gui.*;
import com.trolltech.qt.webkit.*;

public class WebFrameInThread extends QLabel {

    public WebFrameInThread() {
        MyRunnable runnable = new MyRunnable();

        QThread thread = new QThread(runnable);
        runnable.moveToThread(thread);

        thread.start();
    }

    private class MyRunnable extends QObject implements Runnable {

        private QWebPage page;
        private QEventLoop loop;

        public MyRunnable() {
            page = new QWebPage(this);
        }

        public void run() {
            try {
                page.loadFinished.connect(this, "loadFinished()");
                page.loadProgress.connect(this,  "loadProgress(int)");
                page.mainFrame().load(new QUrl("http://www.qtsoftware.com";));
            } catch (Throwable e) {
                e.printStackTrace();
            }

            loop = new QEventLoop();
            loop.exec();
        }

        public void loadProgress(final int progress) {
            QApplication.invokeLater(new Runnable() {
                public void run() {
                    setText(progress + "%");
                }
            });
        }

        public void loadFinished() {
            page.setViewportSize(page.mainFrame().contentsSize());

            QPrinter printer = new QPrinter();
            printer.setOutputFileName("output.pdf");
            printer.setOutputFormat(QPrinter.OutputFormat.PdfFormat);

            QPainter painter = new QPainter();
            painter.begin(printer);
            page.mainFrame().render(painter);
            painter.end();

            loop.exit();

            QApplication.invokeLater(new Runnable() {
                public void run() {
                    close();
                }
            });            
        }
    }


    public static void main(String args[]) {
        QApplication.initialize(args);

        QWidget widget = new WebFrameInThread();
        widget.show();

        QApplication.exec();
    }

}
_______________________________________________
Qt-jambi-interest mailing list
[email protected]
http://lists.trolltech.com/mailman/listinfo/qt-jambi-interest

Reply via email to