如何在调整窗口大小时锁定宽高比?

时间:2017-12-31 14:58:14

标签: c++ qt opengl aspect-ratio

我有一个qt应用程序打开一个显示图像的窗口。我希望能够调整窗口大小并保持窗口的宽高比。窗口的原始大小为480x640(宽x高)。我想要的效果是,当我改变宽度时,我随之改变高度,当我改变高度时,我用它改变宽度。如何检测我是否正在改变窗口的宽度或高度。

我实现了下面的代码,当我改变宽度时它确实保持了宽高比,但是我无法改变窗口的高度。我无法将高度变小或变大。

下面的代码创建了窗口。

#ifndef VideoWidget_h
#define VideoWidget_h

#include <iostream>

// Qt libraries
#include <QApplication>
#include <QtCore>
#include <QWidget>
#include <QGLWidget>

using namespace cv;
using namespace std;

class VideoWidget : public QGLWidget
{
    Q_OBJECT

public:
    VideoWidget()
    {

    }

protected:

    void resizeGL(int width, int height)
    {
        const float ASPECT_RATIO = (float) WIDTH / (float) HEIGHT;
        const float aspect_ratio = (float) width / (float) height;

        if (aspect_ratio > ASPECT_RATIO) {
            height = (1.f / ASPECT_RATIO) * width;
            resize(width, height);
        } else if (aspect_ratio < ASPECT_RATIO) {
            height = ASPECT_RATIO * height;
            resize(width, height);
        }
    }

private:
    int WIDTH = 480;
    int HEIGHT = 640;

};


#endif /* VideoWidget_h */

以下代码是主要功能。

#include <iostream>

// Qt libraries
#include <QApplication>
#include <QtCore>
#include <QWidget>
#include <QGLWidget>

#include "VideoWidget.h"

using namespace cv;
using namespace std;

int main(int argc, char **argv)
{
    QApplication app (argc, argv);

    VideoWidget v;
    v.resize(480, 640);
    v.show();

    return app.exec();
}

1 个答案:

答案 0 :(得分:1)

  

如何在调整窗口大小时锁定宽高比?

在这种情况下,我们可以利用QWidget :: resizeEvent的重载:

void MyWidget::resizeEvent(QResizeEvent *event)
{
   static const float ratioY2X = (float) HEIGHT / (float) WIDTH;

   // QResizeEvent type has oldSize() and size()
   // and size() has an actual new size for the widget
   // so we can just take it and apply the ratio.

   // first try to detect the direction of the widget resize
   if (event->oldSize().width() != event->size().width())
      this->resize(event->size().width(),             // apply the correct ratio
                   event->size().width() * ratioY2X); // to either of width/height
   else
      this->resize(event->size().height() / ratioY2X, // apply the correct ratio
                   event->size().height());           // to either of width/height
   event->accept(); // we've finished processing resize event here
}

请注意,此解决方案没有应用大小调整提示(默认)。

P.S。在实际尝试调试之后,我使用if运算符更正了此解决方案。我们应该通过拖动它的角来调整窗口小部件的大小,那么宽度是优先级(需要选择一个,无论如何还能工作吗?)