PDF Viewing Support (poppler-qt4)
Gunnar Sletta
gunnar at trolltech.com
Fri Feb 15 10:17:33 CET 2008
Adam Batkin wrote:
> Pages get constructed on-the-fly by (for example) calling
> Document->page(n). You can then do various useful things, in my case
> just page->renderToImage() is enough, and out pops a nice QImage. But:
> my PdfDocument could get garbage collected (and the underlying Document
> deleted) while there are still outstanding PdfPage (and Page) objects
> lying about.
>
> I'm thinking that I'll solve this by replacing my bare pointer to the
> Document (in my PdfDocument class) with a reference counted proxy, then
> make sure that each PdfPage also keeps a copy of its underlying
> Document. Does this sound reasonable? Are there other common patterns to
> solving patterns like this? I know that in the C++ world this type of
> solution is common, but I was kind-of hoping that the generator would
> have some magic to make that all go away.
We cover this exact case because it doesn't appear in Qt. It does, but
in that case the objects are QObjects and then they are covered by other
rules ;-)
We have the <reference-count> attribute which is documented here:
http://doc.trolltech.com/qtjambi-4.3.3_01/com/trolltech/qt/qtjambi-typesystem.html#reference-count
which can do a lot with ownership handling. For instance when you have
lineEdit.setCompleter(completer)
we have a reference-count node where the lineEdit java object gets a
private completer member and thus keeps a java reference to it. When the
lineedit is collected this reference goes away and the completer can be
collected on the next pass. Of course doing:
lineEdit.setCompleter(null)
will in turn reset the private reference to null allowing the original
completer to be deleted.
I would suggest that you do a similar approach with your page object,
namely let the java Page object keep hold of a private member to the
document assuring you that it will be alive. The way we normally do this
is by "hiding the original page() function" and replacing it with one
that does the right thing. In pseudo code:
// Insert a Document member into the page object.
<object-type name="Page">
<inject-code class="java">
Document theDocument;
</inject-code>
</object-type>
// hide the original Document.page() function and replace it
// with one that sets the "theDocument" ref on the returned page
<object-type name="Document">
<modify-function signature="page()const"
access="private"
rename="page_helper" />
<inject-code class="java">
public Page page() {
Page page = page_helper();
page.theDocument = this;
return page;
}
</inject-code>
</object-type>
So, when the page() function gets called it you'll call you own version
of it which sets up the reference. As long as the Page object is alive
there will be a reference to the Document object and it cannot be
collected. I hope this helps you a little bit.
best regards,
Gunnar
More information about the Qt-jambi-interest
mailing list