2017-12-31 325 views
1

イメージを表示するウィンドウを開く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(); 
} 
+0

幅や高さを変更するかどうかを検出したい場合は、 。幅を変更すると、前の高さが残り、その逆もあります。新しい高さが元の高さと同じであるかどうかを確認して、幅を変更してください。 –

+0

この古いQの下にある興味深いものがあります:https://stackoverflow.com/questions/40419768/how-to-stop-window-size-jumping-around-when-forcing-fixed-aspect-ratio – hyde

答えて

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オペレータで修正しました。ウィジェットの角をドラッグしてウィジェットのサイズを変更する必要があります(どれかを選択する必要がありますが、それ以外はどのように機能するのでしょうか)。

+0

好奇心から、そのコードは無限ループを生成しないのですか? – eyllanesc

+0

私は多分それを2、3年行っていないし、それはうまくいった。場合によっては、必要な場合には、処理するイベントのソースを区別することができます:http://doc.qt.io/qt-5/qevent.html#spontaneousしたがって、「自発的」として扱います。とにかく、Qtはそれが実際のイベントからのイベントループから来ていないことを知っています。 – AlexanderVX

+0

アプローチは、半分作業であり、より良いロジックが必要でした。 – AlexanderVX

関連する問題