Qt вызов для обновления (QRegion &), не вызывающий вызов paintEvent (..) - PullRequest
1 голос
/ 17 апреля 2011

Я играл с некоторым кодом из учебника Qt, и я застрял, потому что один из моих наследуемых классов QWidget вызывает обновление (QRegion &), но он не вызывает вызов paintEvent (..) - по сути, я пытаюсь сделатьпростой рефакторинг исходного кода учебника для добавления нескольких снимков с использованием класса CannonShot в 12-й главе учебника Qt (см. ссылку: http://doc.trolltech.com/4.3/tutorial-t12.html)

Обновление CannonField () по-прежнему работает правильно и вызывает его paintEventвызывается повторная реализация. Единственное обновление () CannonShot, которое не вызывает свой собственный paintEvent (я подтвердил, что оно получает до и после вызова обновления). Вот некоторые фрагменты:

class CannonShot : public QWidget
{
   Q_OBJECT
public:
   CannonShot(QWidget *parent = 0);
   int angle() const { return shotAngle; }
   int force() const { return shotForce; }
   void shoot();
private slots:
   void moveShot();
   void plotShot();

signals:
   void hit();
   void missed();
   void angleChanged(int);
   void forceChanged(int);
...
...
protected:
   paintEvent(QPaintEvent*);

private:
   int shotTimerCount;
   QTimer* autoShotTimer;
   float shotAngle;
   float shotForce;
};

Вот фрагмент конструктора CannonShot и где вызывается его обновление ():

CannonShot::CannonShot(QWidget *parent): QWidget(parent)
{
   shotTimerCount = 0;
   autoShotTimer = new QTimer(this);
   connect(autoShotTimer, SIGNAL(timeout()), this, SLOT(moveShot()));
}

void CannonShot::shoot()
{
   if (autoShotTimer->isActive())
   return;
   shotTimerCount = 0;
   shotAngle = CannonField::angle();
   shotForce = CannonField::force();
   autoShotTimer->start(5);
}

void CannonShot::moveShot()
{
   QRegion region = shotRect();
   ++shotTimerCount;

   QRect shotR = shotRect();
   if (shotR.x() > width() || shotR.y() > height()) {
      autoShotTimer->stop();
      emit missed();
   }
   else {
      region = region.unite(shotR);
   }
   update(region); //-Checked that code reaches before and after this call!
}

void CannonShot::paintEvent(QPaintEvent*)
{
   //-Never gets here!!
   QPainter painter(this);
   QColor color;
   //-Do whatever
}

Здесь также приведен краткий фрагмент CannonField, который содержит кадры и вызывает Shoot () для их запуска.

class CannonField : public QWidget
{
   Q_OBJECT

public:
   CannonField(QWidget *parent = 0);
   ~CannonField();
   static int angle() { return currentAngle; }
   static int force() { return currentForce; }

public slots:
   void setAngle(int angle);
   void setForce(int force);
   void shoot();

signals:
   void hit();
   void missed();
...
...

protected:
   void paintEvent(QPaintEvent *event);

public:
   static int currentAngle;
   static int currentForce;

private:
   QVector<CannonShot*> shots;
};

А вот фрагмент источника CannonField, из которого стреляют выстрелы.

void CannonField::shoot()
{
   //-Added this argument since I though after searching that CannonShot 
   // needs to have a QWidget with some dimensions..
   shots.push_back(new CannonShot(this));
   (shots.back())->shoot();
}

FinalВодитель выглядит так:

class MyWidget : public QWidget {
public:
   MyWidget(QWidget *parent = 0);
};

MyWidget::MyWidget(QWidget *parent): QWidget(parent)
{
   QPushButton *quit = new QPushButton(tr("&Quit"));
   quit->setFont(QFont("Times", 18, QFont::Bold));
   connect(quit, SIGNAL(clicked()), qApp, SLOT(quit()));
   LCDRange *angle = new LCDRange(tr("&ANGLE"));
   angle->setRange(0, 90);
   LCDRange *force = new LCDRange(tr("&FORCE"));
   force->setRange(10, 50);
   CannonField *cannonField = new CannonField(this);
   connect(angle, SIGNAL(valueChanged(int)),
          cannonField, SLOT(setAngle(int)));
   connect(cannonField, SIGNAL(angleChanged(int)),
          angle, SLOT(setValue(int)));
   connect(force, SIGNAL(valueChanged(int)),
          cannonField, SLOT(setForce(int)));
   connect(cannonField, SIGNAL(forceChanged(int)),
          force, SLOT(setValue(int)));
   QPushButton *shoot = new QPushButton(tr("&Shoot"));
   shoot->setFont(QFont("Times", 18, QFont::Bold));
   connect(shoot, SIGNAL(clicked()), cannonField, SLOT(shoot()));      
   ...
   ...
   //-Other layout stuff
}

int main(int argc, char *argv[])
{
   QApplication app(argc, argv);
   MyWidget widget;
   widget.setMinimumSize(300, 300);
   widget.setSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed);
   widget.setGeometry(100, 100, 500, 355);
   widget.show();
   return app.exec();
}

Ответы [ 3 ]

0 голосов
/ 19 апреля 2011

paintEvent(QPaintEvent*) функция должна быть в разделе protected, сигнатура функции:

void QWidget::paintEvent ( QPaintEvent * event )   [virtual protected]

В настоящее время у вас есть:

private:
paintEvent(QPaintEvent*);

должно быть:

protected:
virtual void paintEvent(QPaintEvent*);

вместо.

0 голосов
/ 06 июня 2013

Может произойти, если область обновления не пересекается с областью кадра:

QRect frameRect = this->rect();

if( frameRect.intersected(updateRec).isEmpty())
{

}
0 голосов
/ 18 апреля 2011

Если QRegion :: isEmpty () имеет значение true, он не будет вызывать QWidget :: paintEvent (). Я подозреваю, что это может произойти в вашем случае.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...