2

I have the following snippet:

    class A : public QWidget
    {
       Q_OBJECT
   public:
     A(QWidget *parent = 0);

     void
     setGeometry(int x, int y, int w, int h);

      protected:
       virtual void
       resizeEvent(QResizeEvent *event);

    }

    class B : public A
    {
       Q_OBJECT
   public:
     B(A*parent = 0);   

     void
    setGeometry(int x, int y, int w, int h);

   protected:
     virtual void
     resizeEvent(QResizeEvent *event);
    }

void
A::setGeometry(int x, int y, int w, int h) 
{
    QWidget::setGeometry(x, y, w, h);
}

void
A::resizeEvent( QResizeEvent * event) 
{
    QWidget::resizeEvent(event);
    // common A and B stuff
}

void
B::setGeometry(int x, int y, int w, int h) 
{
    A::setGeometry(x, y, w, h);
}

void
B::resizeEvent( QResizeEvent * event) 
{
    A::resizeEvent(event);

}

Calling setGeometry on an instance of A will fire resizeEvent() . Invoke setGeometry on an instance of B will not fire resizeEvent(). Is there anything wrong with this?

EDIT: I could do the same calculation I need inside setGeometry successfully. Now, mine is only curiosity.

Blackbelt
  • 156,034
  • 29
  • 297
  • 305
  • does the implementation of B::resizeEvent() call A::resizeEvent()? – Frank Osterfeld Jul 30 '12 at 07:52
  • Yes In the implementation of B::resizeEvent() I call the A::resizeEvent() .B::resizeEvent() is not fired. It should be fired when I invoke B::setGeometry() according to the documentation. – Blackbelt Jul 30 '12 at 07:58

1 Answers1

3

There are a few problems with the snippet above, so I've altered it in a few places... the code below is the minimum necessary to produce the behaviour you want.

Header:

class TestA : public QWidget
{
  Q_OBJECT

  public:
    explicit TestA(QWidget *Parent = 0) : QWidget(Parent) {}
    ~TestA() {}

  protected:
    virtual void resizeEvent(QResizeEvent *);
};

class TestB : public TestA
{
  Q_OBJECT

  public:
    explicit TestB(QWidget *Parent = 0) : TestA(Parent) {}
    ~TestB() {}

  protected:
    virtual void resizeEvent(QResizeEvent *);
};

Implementation:

void TestA::resizeEvent(QResizeEvent *)
{
  qDebug() << "TestA Resize";
}

void TestB::resizeEvent(QResizeEvent *)
{
  qDebug() << "TestB Resize";
}

MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);

  TestA* A = new TestA(this);
  TestB* B = new TestB(this);

  A->setGeometry(0,0,100,100);
  B->setGeometry(200,200,100,100);
}

Changes:

  • Addition of Q_OBJECT macros to class definition:

    Tells the compiler to add Qt meta-object code for the class (not strictly necessary to ensure that resizeEvent()s are called, but should be included for objects which inherit QObject as a matter of course).

  • Addition of constructors which allow the passing in of a parent object and invoke the base class constructor with this parent object AND passing a parent object into the constructors of the two objects when they are created:

    From the docs:

    When changing the geometry, the widget, if visible, receives a move event (moveEvent()) and/or a resize event (resizeEvent()) immediately. If the widget is not currently visible, it is guaranteed to receive appropriate events before it is shown.

    If your widgets don't have parents setting the geometry is half meaningless, as the x and y parts refer to its position relative to a parent. On top of that, since the widgets have no parents they can't be visible as part of the application so Qt doesn't bother to call the appropriate resizeEvent().

Community
  • 1
  • 1
sam-w
  • 7,478
  • 1
  • 47
  • 77
  • Sorry, my post was not complete. I had already added the Q_OBJECT constant in both the subclass, and every constructor takes already a parent. I do not think is a parent issue becuse if it was I should have experimented the same behaviour on both classes, am I wrong? – Blackbelt Jul 30 '12 at 10:10
  • No worries :) If you're doing what I'm doing above though, you shouldn't have a problem - can you alter your post above to reflect your **exact** code please, including anything relevant from the implementation? – sam-w Jul 30 '12 at 10:17
  • Why are you overriding `setGeometry()`? This really isn't something you should need to do! Also your constructors look pretty strange - why does `B` need a parent of type `A`? Could you also please post the implementation for all of the functions you've defined above (including the constructors) as well as the part of the implementation where you create your instances of `A` and `B` and invoke `setGeometry()`. – sam-w Jul 30 '12 at 10:46
  • I need to ovveride because it does not call the resizeEvent callback on B. – Blackbelt Jul 30 '12 at 10:48
  • The reason it's not calling the `resizeEvent()` is because there is a bug in your code, not that `QWidget::setGeometry()` is wrong. Don't override `setGeometry()`. I've also made an edit to my comment above, requesting a couple more bits. Cheers :) – sam-w Jul 30 '12 at 10:50
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/14622/discussion-between-sjwarner-and-blackbelt) – sam-w Jul 30 '12 at 10:51