Trolltech Home | Qt-jambi-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 1

Qt-jambi-interest Archive, November 2007
Extending an ItemView


Message 1 in thread

Hi,

I'm just experimenting with QtJambi as well as Qt C++ and I was trying
to "port" the C++ Chart example to Jambi when I got into trouble.

When running my "ported" app I get a lot of these messages, and the
widget doesn't resize properly:
QPaintEngine::setSystemRect: Should not be changed while engine is active
QPaintEngine::setSystemClip: Should not be changed while engine is active


I then tried to create a simple class extending QListView in both Java
and C++ to try to figure this one out:
public class TestView extends QListView {
    protected void paintEvent(QPaintEvent e) {
        QPainter painter = new QPainter(viewport());
        super.paintEvent(e);
    }
}

And:
void TestView::paintEvent(QPaintEvent *event) {
	QPainter painter = QPainter(viewport());
	QListView::paintEvent(event);
}

The C++ code works just fine, but changing it to:
void TestView::paintEvent(QPaintEvent *event) {
	QPainter *painter = new QPainter(viewport());
	QListView::paintEvent(event);
}

produces the same behaviour as the Java code.


Beeing a Java programmer and not a C++ programmer I don't know what the
big difference is between the two C++ versions, but I would guess that
Jambi uses the latter version.

Is this a bug? Or how do I get around this problem in Jambi?


Regards

Trond GjÃlstad Ziarkowski


Message 2 in thread

Trond GjÃlstad Ziarkowski wrote:
> I then tried to create a simple class extending QListView in both Java
> and C++ to try to figure this one out:
> public class TestView extends QListView {
>     protected void paintEvent(QPaintEvent e) {
>         QPainter painter = new QPainter(viewport());
>         super.paintEvent(e);
>     }
> }
>
> And:
> void TestView::paintEvent(QPaintEvent *event) {
> 	QPainter painter = QPainter(viewport());
> 	QListView::paintEvent(event);
> }
>
> The C++ code works just fine, but changing it to:
> void TestView::paintEvent(QPaintEvent *event) {
> 	QPainter *painter = new QPainter(viewport());
> 	QListView::paintEvent(event);
> }
>
> produces the same behaviour as the Java code.
>
>
>
>   

Any QPainter opened (begin is called) on a paint device has to also be 
closed (end is called.) When you call the QPainter constructor and pass 
in a paint device, it automatically calls begin. When the object is 
destroyed, it automatically calls end.

The problem with the Java-code is that it does not call the end-method, 
and the destructor does not get called until the garbage collector 
decides to collect the painter. With the first C++ example, the object 
is allocated on the stack, and thus the destructor is called 
automatically when the object goes out of scope. With the second C++ 
example, the object is allocated on the heap, and will have to be 
manually deleted/ended. The second C++ example will also leak memory.

So, to fix your Java example, change the code to the following:

protected void paintEvent(QPaintEvent e) {
    QPainter painter = new QPainter(viewport());
    painter.end();
    super.paintEvent(e);
}

That should do the trick.

-- Eskil