【问题标题】:QWidget::resizeEvent() not called in a sub subclassQWidget::resizeEvent() 未在子类中调用
【发布时间】:2012-07-27 20:24:55
【问题描述】:

我有以下sn-p:

    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);

}

A 的实例上调用 setGeometry 将触发 resizeEvent() 。在 B 的实例上调用 setGeometry 不会触发 resizeEvent()。这有什么问题吗?

编辑: 我可以在setGeometry 中成功地进行我需要的相同计算。现在,我的只是好奇。

【问题讨论】:

  • B::resizeEvent()的实现是否调用了A::resizeEvent()?
  • 是在 B::resizeEvent() 的实现中,我调用了 A::resizeEvent() .B::resizeEvent() 没有被触发。当我根据文档调用 B::setGeometry() 时应该触发它。

标签: qt qwidget


【解决方案1】:

上面的 sn-p 存在一些问题,所以我在几个地方对其进行了更改……下面的代码是产生您想要的行为所必需的最低限度。

标题:

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 *);
};

实施:

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);
}

变化:

  • 在类定义中添加Q_OBJECT macros

    告诉编译器为类添加 Qt 元对象代码(对于确保调用 resizeEvent()s 不是绝对必要的,但对于继承 QObject 的对象当然应该包括在内)。

  • 添加构造函数,允许传入父对象并使用该父对象调用基类构造函数,并在创建两个对象时将父对象传递给它们的构造函数

    来自the docs

    更改几何图形时,小部件如果可见会立即接收移动事件 (moveEvent()) 和/或调整大小事件 (resizeEvent())。如果小部件当前不可见,则保证在显示之前接收到适当的事件。

    如果您的小部件没有父级设置几何是一半毫无意义,因为xy 部分指的是它相对于父级的位置。最重要的是,由于小部件没有父级,它们不能作为应用程序的一部分可见,因此 Qt 不会费心调用适当的 resizeEvent()

【讨论】:

  • 对不起,我的帖子没有完成。我已经在两个子类中添加了 Q_OBJECT 常量,并且每个构造函数都已经有了一个父类。我不认为是父母的问题,因为如果是我应该在两个班级上试验相同的行为,我错了吗?
  • 不用担心 :) 如果您正在做我上面所做的事情,那么您应该没有问题 - 您可以更改您上面的帖子以反映您的确切请提供代码,包括与实现相关的任何内容?
  • 你为什么要覆盖setGeometry()?这真的不是你应该做的事情!你的构造函数看起来也很奇怪——为什么B 需要A 类型的父级?您能否也请发布您在上面定义的所有函数(包括构造函数)的实现以及创建AB 实例并调用setGeometry() 的实现部分。
  • 我需要 ovveride 因为它不会调用 B 上的 resizeEvent 回调。
  • 之所以没有调用resizeEvent() 是因为您的代码中存在错误,而不是QWidget::setGeometry() 是错误的。不要覆盖setGeometry()。我还对上面的评论进行了编辑,要求提供更多信息。干杯:)
猜你喜欢
  • 1970-01-01
  • 2020-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2010-12-18
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多