[Qt-interest] QPaintEngine setSystemRect should not be changed while engine is active?

Kermit Mei kermit.mei at gmail.com
Wed Jul 1 03:27:24 CEST 2009


On Tue, 2009-06-30 at 16:36 +0200, Samuel Rødal wrote:
> Kermit Mei wrote:
<snip>
> > Rum it, the system tell me:
> > 
> > QPaintEngine::setSystemRect: Should not be changed while engine is
> > active
<snip>

> How does the paint function look?
> 
> --
> Samuel

Thank you, Samuel. I'd like to paste all the source file here so that
you can help me:)

////// AnimationWidget.cpp /////////////////////

/********************************
 ** This widget is used to show a animation using QPixmap.
 ** Because my program will run on ARM, so I can't use the 
 ** QAnimation* class for its bad efficiency.
 *******************************/


#include <QApplication>
#include <QPen>
#include <QPainter>
#include <QTimerEvent>
#include <QLabel>
#include <QPixmap>

#include "AnimationWidget.h"
#include "StackedWidget.h"
#include "Debug.h"


AnimationWidget::AnimationWidget(QWidget *parent) 
  : Widget(parent),pixmap(0),timerId(0),x(0),y(0)
{
  pixmap = new QPixmap();
  connect(this, SIGNAL(finished()), this,SLOT(showRealWidget()));
}

AnimationWidget::~AnimationWidget() {
  if(pixmap != 0)
    delete pixmap;
}

void AnimationWidget::showWidget(QWidget *widget, const MoveMode
&mymode) {
  hide();
  widget->show();
  /*  StackedWidget *stackedWidget = qobject_cast<StackedWidget
*>(parent());
  if(stackedWidget != 0)
    stackedWidget->setCurrentWidget(currWidget);
  
  mode = mymode;
  switch(mode) {
  case LeftToRight:
  case TopLeftToRight:
    x = -320;
    break;
  case RightToLeft:
  case TopRightToLeft:
    x = 320;
    break;
  }

  currWidget = widget;
  currWidget->hide();
  show();
  if(pixmap != 0)
    delete pixmap;
  if(timerId != 0)
    killTimer(timerId);
  if(mymode == LeftToRight || mymode == RightToLeft)
    pixmap = new QPixmap(QPixmap::grabWidget(currWidget,0,32,320,208));
  else  //Top Moving mode.
    pixmap = new QPixmap(QPixmap::grabWidget(currWidget,0,0,320,208));
  timerId = startTimer(32);
  */
}

void AnimationWidget::timerEvent(QTimerEvent *event) {
  if(event->timerId() == timerId)
    update();
  else
    showRealWidget();    
}

void AnimationWidget::paintEvent(QPaintEvent *event) {
  if(timerId == 0)
    Widget::paintEvent(event);
  else
    paint();
}

void AnimationWidget::paint() {
  //No timer started!
  if( timerId == 0)
    return ;
  int internal = 64;
  QPainter painter(this);
  switch(mode) {
  case LeftToRight:
  case TopLeftToRight:
    if(x < 0) {
      painter.drawPixmap(x+=internal,32,320,208,*pixmap);
      return;
    }
    break;
  case RightToLeft:
  case TopRightToLeft:
    if(x > 0) {
      painter.drawPixmap(x-=internal,32,320,208,*pixmap);
      return;
    }
    break;
  }
  showRealWidget();
  //  emit finished();
}

void AnimationWidget::showRealWidget() {
  //If the case hasn't return, then the animation is finished.
  QMetaObject::invokeMethod(this, "hide",Qt::QueuedConnection);
  //  hide();
  QMetaObject::invokeMethod(currWidget, "show",Qt::QueuedConnection);
  //  currWidget->show();

  killTimer(timerId);
  timerId = 0;
  StackedWidget *stackedWidget = qobject_cast<StackedWidget
*>(parent());
  if(stackedWidget != 0)
    stackedWidget->setCurrentWidget(currWidget);
  currWidget->setVisible(true);
  qDebug("curr is hidden %d",currWidget->isHidden());
  qDebug("ani is hidden %d",isHidden());
  qApp->processEvents();
}





More information about the Qt-interest-old mailing list