JustWe
JustWe

Reputation: 4484

Why QResizeEvent & QWidget::size gives different when fullscreen?

The question is from https://stackoverflow.com/a/52151020/3308570. (contains an example to reproduce the problem)

I'm trying to get the widget size when it shows fullscreen. At first, I took the size from QResizeEvent::size. But the size only works correctly once. Like:

  1. show fullscreen
  2. QResizeEvent::size ⇒ 1920x1080
  3. show normal
  4. QResizeEvent::size ⇒ 500x400
  5. show fullscreen
  6. QResizeEvent::size ⇒ 516x439

Then I changed to using QWidget::size in QResizeEvent, it gives the correct result 1920x1080 always when fullscreen.

Is this a bug, or I did something wrong?

Env: Qt 5.10.1 Mingw32 Win10

Update:

I found the problem because the videoWidget show incorrect size. Then I check the size by debugging.

Thanks @Scheff ,I replaced the resizeEvent function part to observe the problem:

ushort i = 0;
void resizeEvent(QResizeEvent* event) {
    i++;
    const QSize sizeEventOld = event->oldSize();
    const QSize sizeEvent = event->size();
    const QSize sizeWidgetBefore = size();
    const QSize sizeWidgetAfter = size();
    qDebug() << "Widget::resizeEvent():" << i;
    qDebug() << "QResizeEvent::oldSize  :" << sizeEventOld;
    qDebug() << "QResizeEvent::size     :" << sizeEvent;
    qDebug() << "Widget::size() (before):" << sizeWidgetBefore;
    qDebug() << "Widget::size() (after) :" << sizeWidgetAfter;
    videoWidget->resize(size());
    event->accept();
}

Mingw32, MSVC2013 Output:

Widget::resizeEvent(): 1 // The window initilized
QResizeEvent::oldSize  : QSize(-1, -1)
QResizeEvent::size     : QSize(500, 400)
Widget::size() (before): QSize(500, 400)
Widget::size() (after) : QSize(500, 400)
Widget::resizeEvent(): 2 // Double click, show fullscreen.
QResizeEvent::oldSize  : QSize(500, 400)
QResizeEvent::size     : QSize(1920, 1080)
Widget::size() (before): QSize(1920, 1080)
Widget::size() (after) : QSize(1920, 1080)
Widget::resizeEvent(): 3 // Double click, show normal.
QResizeEvent::oldSize  : QSize(1920, 1080)
QResizeEvent::size     : QSize(500, 400)
Widget::size() (before): QSize(500, 400)
Widget::size() (after) : QSize(500, 400)
Widget::resizeEvent(): 4 // Double click, show fullscreen(2nd time)
QResizeEvent::oldSize  : QSize(500, 400)
QResizeEvent::size     : QSize(516, 439)
Widget::size() (before): QSize(1920, 1080)
Widget::size() (after) : QSize(1920, 1080)
Widget::resizeEvent(): 5 // Double click, show normal(2nd time)
QResizeEvent::oldSize  : QSize(1920, 1080)
QResizeEvent::size     : QSize(500, 400)
Widget::size() (before): QSize(500, 400)
Widget::size() (after) : QSize(500, 400)

Upvotes: 2

Views: 2763

Answers (1)

Scheff&#39;s Cat
Scheff&#39;s Cat

Reputation: 20141

The Qt doc. states clearly that QResizeEvent::size()

Returns the new size of the widget. This is the same as QWidget::size().

So, I believe the observed/reported behavior is a bug which might be limited to the MS Windows specific part of Qt.

I made the following MCVE to reproduce.

testQResize.cc:

#include <QtWidgets>

class Widget: public QWidget {
  private:
    unsigned _i; // event counter
    QPushButton _qBtn;
  public:
    Widget(QWidget *pQParent = nullptr);

  protected:
    virtual void resizeEvent(QResizeEvent *pQEvent);
  private:
    void toggleFullScreen();
};

Widget::Widget(QWidget *pQParent):
  QWidget(pQParent),
  _i(0), _qBtn("Click to toggle fullscreen mode", this)
{
  connect(&_qBtn, &QPushButton::clicked,
    [this](bool) { toggleFullScreen(); });
}

void Widget::resizeEvent(QResizeEvent *pQEvent)
{
  ++_i;
  const QSize sizeEventOld = pQEvent->oldSize();
  const QSize sizeEvent = pQEvent->size();
  const QSize sizeWidget = size();
  _qBtn.resize(pQEvent->size());
  //QWidget::resizeEvent(pQEvent);
  // report
  qDebug() << "Widget::resizeEvent():" << _i;
  qDebug() << "pQEvent->oldSize():" << sizeEventOld;
  qDebug() << "pQEvent->size()   :" << sizeEvent;
  qDebug() << "this->size()      :" << sizeWidget;
  qDebug() << "this->_qBtn.size():" << _qBtn.size();
}

void Widget::toggleFullScreen()
{
  if (!isFullScreen()) showFullScreen();
  else showNormal();
}

int main(int argc, char **argv)
{
  qDebug() << "Version:" << QT_VERSION_STR;
  QApplication app(argc, argv);
  Widget win;
  win.show();
  return app.exec();
}

testQResize.pro:

SOURCES = testQResize.cc

QT = widgets

First, I compiled and tested on cygwin64 on Windows 10 but I was not able to reproduce the issue. (Compiling on cygwin means in my case, this Qt depends on X11.)

Btw. I was a bit annoyed as the showFullScreen() hadn't any effect. I suspected the cygwin XWin manager (a very special thing which acts as intermediator to embed X windows in Windows. – However, I know it has certain weaknesses.)

So, I compiled and tested on VS2013 (platform 64 bit):

Version: 5.9.2
Widget::resizeEvent(): 1
pQEvent->oldSize(): QSize(-1, -1)
pQEvent->size()   : QSize(100, 30)
this->size()      : QSize(100, 30)
this->_qBtn.size(): QSize(100, 30)
Widget::resizeEvent(): 2
pQEvent->oldSize(): QSize(640, 480)
pQEvent->size()   : QSize(640, 480)
this->size()      : QSize(120, 30)
this->_qBtn.size(): QSize(640, 480)
Widget::resizeEvent(): 3
pQEvent->oldSize(): QSize(120, 30)
pQEvent->size()   : QSize(2560, 1440)
this->size()      : QSize(2560, 1440)
this->_qBtn.size(): QSize(2560, 1440)
Widget::resizeEvent(): 4
pQEvent->oldSize(): QSize(2560, 1440)
pQEvent->size()   : QSize(120, 30)
this->size()      : QSize(120, 30)
this->_qBtn.size(): QSize(120, 30)
Widget::resizeEvent(): 5
pQEvent->oldSize(): QSize(120, 30)
pQEvent->size()   : QSize(136, 69)
this->size()      : QSize(2560, 1440)
this->_qBtn.size(): QSize(136, 69)
Widget::resizeEvent(): 6
pQEvent->oldSize(): QSize(2560, 1440)
pQEvent->size()   : QSize(120, 30)
this->size()      : QSize(120, 30)
this->_qBtn.size(): QSize(120, 30)

(2560x1440 was full size in my case.)

The issue manifests after Widget::resizeEvent(): 5.

I have no idea why this happens but it seems to be limited to the Qt MS Windows specific code.

However, the OP presented already a work-around which appears very reasonable to me: not to rely on QResizeEvent::size but to use the QWidget::size property instead.

Upvotes: 3

Related Questions