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

Qt-interest Archive, January 2007
Painting animations


Message 1 in thread

I am porting an application from Qt3, in which the user could indicate 
placement of vertical lines on a graph with mouse clicks. In response to 
the mouse, in Qt3 I created a QPainter(this), then used bitBlt to first 
store the image underneath where the line was to be (so I can move the 
line later and restore what used to be there), then draw the line on the 
image.

This does not work in Qt4, 'cause you cannot create a QPainter(this) 
outside of a paintEvent. I just tried creating a QPainter(QPixmap), then 
initFrom(this), but I still get error messages "QPixmap oiperator =: 
cannot assign to Pixmap during painting", and "QPainter::begin: paint 
device returned engine = 0, type = 2". Does anyone know what these mean?

Is there another way to do this, without a full repaint of the image? I 
cant seem to sort this out, no specific examples are given, and nothing 
in documentation that I can find.

Here is some code that I think is being called here, in response to left 
mouse click:

QRect dr=GetDataRect(); // rectangular area containing graphical data
m_iVertLineXb=x; // x=coordinate of mouse
m_LineImage_b.resize(0,0);
int ht=dr.height();
m_LineImage_b.resize(3,ht);
QPainter dc(&m_LineImage_b);
dc.initFrom(this);
dc.drawPixmap(0,0,3,ht,m_LineImage_b,m_iVertLineXb-1,dr.top(),3,ht);

--
 [ signature omitted ] 

Message 2 in thread

Kenneth Beck wrote:
> I am porting an application from Qt3, in which the user could indicate 
> placement of vertical lines on a graph with mouse clicks. In response 
> to the mouse, in Qt3 I created a QPainter(this), then used bitBlt to 
> first store the image underneath where the line was to be (so I can 
> move the line later and restore what used to be there), then draw the 
> line on the image.
>
> This does not work in Qt4, 'cause you cannot create a QPainter(this) 
> outside of a paintEvent. I just tried creating a QPainter(QPixmap), 
> then initFrom(this), but I still get error messages "QPixmap oiperator 
> =: cannot assign to Pixmap during painting", and "QPainter::begin: 
> paint device returned engine = 0, type = 2". Does anyone know what 
> these mean?
>
> Is there another way to do this, without a full repaint of the image? 
> I cant seem to sort this out, no specific examples are given, and 
> nothing in documentation that I can find.
>
Well you could use a QGLWidget and draw in OpenGL. You then don't have 
Qt4's stupid
limit of not being able to paint outside paintEvents, you can render 
your graph to a texture,
then drawing this on the framebuffer gets done in the GPU, making it 
entirely practical to
redraw the background even in e.g. mouseMoveEvent.

- Keith

--
 [ signature omitted ] 

Message 3 in thread

In Qt 4, you should just do update() and let the paintEvent draw what is the 
next frame in the animation (with timing of course). If you really want to 
make that happen right away, call repaint().

The no painter outside paintEvent only applies to QWidget, so you are free to 
paint on a QPixmap. You do it this way:

QPixmap pixmap;
QPainter painter(&pixmap);
// draw code here

You can then store the pixmap and paint it in the next paintEvent.

And just a note to Keith Sabine: This limitation is not a stupid requirement, 
but one of the prices of cross platform coding. There is a difference. I 
don't like it either, but I'm not prepared to cut proper painting on Mac just 
to avoid the few cases where it would have been nice to paint outside the 
paintEvent.

Bo.

Thursday 04 January 2007 15:14 Kenneth Beck wrote:
> I am porting an application from Qt3, in which the user could indicate
> placement of vertical lines on a graph with mouse clicks. In response to
> the mouse, in Qt3 I created a QPainter(this), then used bitBlt to first
> store the image underneath where the line was to be (so I can move the
> line later and restore what used to be there), then draw the line on the
> image.
>
> This does not work in Qt4, 'cause you cannot create a QPainter(this)
> outside of a paintEvent. I just tried creating a QPainter(QPixmap), then
> initFrom(this), but I still get error messages "QPixmap oiperator =:
> cannot assign to Pixmap during painting", and "QPainter::begin: paint
> device returned engine = 0, type = 2". Does anyone know what these mean?
>
> Is there another way to do this, without a full repaint of the image? I
> cant seem to sort this out, no specific examples are given, and nothing
> in documentation that I can find.
>
> Here is some code that I think is being called here, in response to left
> mouse click:
>
> QRect dr=GetDataRect(); // rectangular area containing graphical data
> m_iVertLineXb=x; // x=coordinate of mouse
> m_LineImage_b.resize(0,0);
> int ht=dr.height();
> m_LineImage_b.resize(3,ht);
> QPainter dc(&m_LineImage_b);
> dc.initFrom(this);
> dc.drawPixmap(0,0,3,ht,m_LineImage_b,m_iVertLineXb-1,dr.top(),3,ht);
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/

-- 
 [ signature omitted ]