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

Qt-interest Archive, October 2001
Pixmap Problems.


Message 1 in thread


<<< text/html: EXCLUDED >>>


Message 2 in thread


<<< text/html: EXCLUDED >>>


Message 3 in thread


<<< text/html: EXCLUDED >>>


Message 4 in thread

On Tue, 2 Oct 2001, Sonic & Knuckles wrote:

> I managed to put together some simple code below and I would like some
> pointers, tips, suggestions on how I could/should code my little,
> 'simple' example of basic animation.  All it does is move a ball
> (ellipse) back and forth across the screen.  The only way I found I

The source doesn't reveal how many ellipses you're actually
drawing. drawEllipses is probably not the fastest operation, so it would
be preferable to draw the ellipse once in an offscreen bitmap and simply
blit this one into your canvas when needed (instead of calling
drawEllipses each time).

> could get the code to call the drawing (update) code was to start a
> timer, nothing else I tried worked.  I would like to get the animation

This is because repaint events are queued, that way, if e.g. a dozen
listivew items call repaint on their listview then only one will actually
be executed (when Qt returns to the event processing loop).


Message 5 in thread

3 quick hints:
1.  You can't put your while loop in the constructor (see documentation
of QPainter and QWidget), it might be able to go in show(), but note
that you may have trouble processing X-events because control is never
returned to the QApplication object.  Leaving the timer in is an easy
solution, an alternative is to use threads.
2.  keep the pixmap that you are using as the back buffer around and
create it using QPixmap::BestOptim
3. Since you seem to draw the whole widget, you can
setBackgroundMode(Qt::NoBackground), to prevent qt from
drawing the background.

Sonic & Knuckles wrote:

> G'day Trolls, I found a small quick tutorial showing the best way to
> do quick screen redraws using QPainter and QPixmap (but not animation)
> using Qt and KDE for a Linux machine, whereas I use Windows and Qt
> 2.3.0 non-commercial edition (aka the poor man's version).  The
> tutorial as I mentioned did not discuss animation of any kind.  When I
> finally got the example to work I decided to add some simple
> animation. So I went the Qt's supplied doc pages, which I found to be
> a total nightmare, they always seem to show the most complicated way
> of doing the simplest of things.  So, I find the documentation a real
> headache. I managed to put together some simple code below and I would
> like some pointers, tips, suggestions on how I could/should code my
> little, 'simple' example of basic animation.  All it does is move a
> ball (ellipse) back and forth across the screen.  The only way I found
> I could get the code to call the drawing (update) code was to start a
> timer, nothing else I tried worked.  I would like to get the animation
> smoother and a lot faster (it runs very, very slow). If you can help
> here is big THANKYOU in advance.Sláinte (Irish for cheers).
> ------------------------------------------------------------------
> Vaughan Egan   ---   celtic@allstate.net.au
>
> ----------------------------------------------------------------- #include
> "pixmapwindow.h"
> #include <qapplication.h>
> #include <qmessagebox.h>
> #include <qpainter.h>
> #include <stdlib.h>
> #include <qcolor.h>
> #include <qbrush.h> PixMapWindow::PixMapWindow( QWidget* parent, const
> char* name, WFlags f )
>  : QMainWindow( parent, name, f )
> {
>  setCaption("PixMap Qt");
>  setMouseTracking(TRUE);
>
>  //set mimimum size here
>  setMinimumSize(700,300);  // setup the Menu
>  // first the items to go on the menubar - Popup Items
>  about = new QPopupMenu();
>  about->insertItem("&About",this, SLOT(mySlot() ));
>  // now the actual MenuBar itself
>  myMenu = new QMenuBar(this);
>  myMenu->insertItem("&About",about);  //colour agus brush stuff
>  windowColour = new QColor(255,158,19);
>  brush=new QBrush(Qt::SolidPattern);
>  // set this brush color
>  brush->setColor( *windowColour );
>  // from original program
>  // needRecreate not used now
>  needRecreate=true;
>  pixmap = 0;  for(int i=0;i<Ellipses;i++){
>   //x[i] = (qApp->random() %100 ) / 100;
>   x[i] = rand() % 200;
>   //y[i] = (qApp.random() %100 ) / 100;
>   y[i] = rand() % 200;
>   }
>
>  directionX = 1;  setBackgroundMode(NoBackground);  // timer stuff
>  // used to keep the animation moving
>  startTimer( 0 );
>  timer = new QTimer( this, "movementHandler" );
>     connect( timer, SIGNAL(timeout()),
>       this, SLOT(moveBall()) );
>     //timer->start(1000, FALSE );
>  timer->start(0,true);  repaint();
>
>  // tried while loop
>  // doesn't work
>  /*while(1){
>   moveEllipses();
>   repaint();
>  }*/
> }
> void PixMapWindow::moveEllipses(){
>  //for(int i=0;i<Ellipses; i++){
>  // x[i] += 1;
>  // }
>  // just move 1 ellipses'sss for now
>  // use only x-axis
>  if(x[1] > 400)directionX = -1;
>  else if(x[1] < 90)directionX = 1;
>
>  x[1] += directionX;
> } void PixMapWindow::mouseMoveEvent(QMouseEvent *e){
>  //moveEllipses();
>  //repaint();
> }
> void PixMapWindow::timerEvent( QTimerEvent * )
> {
>  moveEllipses();
>     repaint();
> }  void PixMapWindow::paintEvent(QPaintEvent *e){  //if
> (needRecreate){   pixmap = new QPixmap(width(), height() );
>   QPainter paint;
>   paint.begin(pixmap,this);   // a light blue colour
>   //QColor windowColour( 255, 158, 19 );
>   // make solid colour
>   //QBrush brush(Qt::SolidPattern );
>   // set this brush colour
>   //brush.setColor( windowColor );
> paint.fillRect(pixmap->rect(),*brush);
>   paint.setBrush(blue);
>   //int w = width()/10;
>   //int h = height()/10;   for(int i=0; i<Ellipses; i++){
>    paint.drawEllipse(x[i],y[i], 50, 50);
>   }   //needRecreate = true;
>  //}
>  bitBlt(this,0,0,pixmap);
>  delete pixmap;
> }   void PixMapWindow::mySlot(){
>  QString myString="The person who wrote this software in a genuis.";
>  myString += "\nNot!!!";
>  QMessageBox::about(0,"About",myString);
> } void PixMapWindow::moveBall(){
>  //QString myString="MoveBall.";
>  //myString += "\nYeah Right!!!";
>  //QMessageBox::about(0,"About",myString);
>   x[0] +=1;
>   repaint();
> }
> void PixMapWindow::keyPressEvent(QKeyEvent *e){
> } void PixMapWindow::resizeEvent(QResizeEvent *e){
> // QMessageBox::about(0,"Oops","Window Resized");
> // needRecreate=true;
> }


Message 6 in thread

Make a loop, where you:
1. draw pixmap
2. put on the screen with bitblt
3. call qApp->processEvents()
4. go back to point 1.

The point 3 (processing events) is needed if you want to interact with your 
application when it is doing the animation.

>  // tried while loop
>  // doesn't work
>  /*while(1){
>   moveEllipses();
>   repaint();
>  }*/


It doesn't work because you don't have processEvents() call in it. So there 
is no way the application can respond to you request of repainting it.

Jacek