我正在玩Qt教程中的一些代码并且因为我的一个QWidget继承类调用update(QRegion&)但它没有触发对paintEvent(..)的调用而被卡住了 - 基本上我试图在Qt教程的第12章中使用CannonShot类添加教程源代码的简单重构(参见链接:http://doc.trolltech.com/4.3/tutorial-t12.html)
CannonField update()仍然可以正常工作并导致其paintEvent重新实现被调用。它唯一没有调用自己的paintEvent的CannonShot的update()。 (我已经确认它确实在更新调用之前和之后获得)。以下是一些片段:
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的构造函数的片段,并且调用了update():
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();
}
最后,驱动程序看起来像:
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();
}
答案 0 :(得分:0)
如果QRegion :: isEmpty()为true,则不会调用QWidget :: paintEvent()。我怀疑你的情况可能会发生。
答案 1 :(得分:0)
paintEvent(QPaintEvent*)
函数应位于protected
部分,函数签名为:
void QWidget::paintEvent ( QPaintEvent * event ) [virtual protected]
目前你有:
private:
paintEvent(QPaintEvent*);
应该是:
protected:
virtual void paintEvent(QPaintEvent*);
代替。
答案 2 :(得分:0)
如果更新区域未与帧区域相交,则可能发生:
QRect frameRect = this->rect();
if( frameRect.intersected(updateRec).isEmpty())
{
}