Qtでウィジェットのアスペクト比を維持する方法は?
-
19-08-2019 - |
質問
Qtでウィジェットのアスペクト比を維持する方法と、ウィジェットの中央揃えについてはどうですか?
解決
独自のレイアウトマネージャーを実装する必要はありません。 QWidget
の継承と再実装
int QWidget::heightForWidth( int w ) { return w; }
正方形を維持します。ただし、X11のトップレベルウィンドウではheightForWidth()
は機能しません。X11プロトコルではサポートされていないようです。センタリングに関しては、Qt::AlignCenter
の3番目のパラメーターまたはQBoxLayout::addWidget()
の5番目のパラメーターとしてQGridLayout::addWidget()
を渡すことができます。
注:少なくともQtの新しいバージョンでは、QWidgetにはheightForWidth
またはwidthForHeight
がないため(オーバーライドできないため)、setWidthForHeight(true)
またはsetHeightForWidth(true)
QGraphicsLayoutの子孫に対してのみ効果があります。
他のヒント
正しい答えは、カスタムレイアウトマネージャーを作成することです。これは、 QLayout をサブクラス化することで可能です。
QLayoutをサブクラス化するときに実装するメソッド
- void addItem(QLayoutItem * item);
- レイアウトにアイテムを追加します。
- int count()const;
- アイテム数を返します。
- QLayoutItem * itemAt(int index)const;
- インデックスでアイテム参照を返します。ない場合は0を返します。
- QLayoutItem * takeAt(int index);
- インデックスからレイアウトのアイテムを取得して返すか、存在しない場合は0を返します。
- Qt :: Orientations expansionDirections()const;
- レイアウト展開方向を返します。
- bool hasHeightForWidth()const;
- 幅の計算のためにレイアウトが高さを処理するかどうかを伝えます。
- QSize minimumSize()const;
- レイアウトの最小サイズを返します。
- void setGeometry(const QRect <!> amp; rect);
- レイアウトのジオメトリとその中のアイテムを設定します。ここでは、アスペクト比を維持し、センタリングを行う必要があります。
- QSize sizeHint()const;
- レイアウトの推奨サイズを返します。
さらに読む
resize()
内からresizeEvent()
を呼び出すことはうまくいきませんでした-せいぜいウィンドウが2回リサイズされると(ちらつく)ちらつきを引き起こし、最悪の場合無限ループになります。
<!> quot; correct <!> quot;固定のアスペクト比を維持する方法は、カスタムレイアウトを作成することです。 QLayoutItem::hasHeightForWidth()
とQLayoutItem::heightForWidth()
の2つのメソッドのみをオーバーライドする必要があります。
私の場合、heightForWidth()のオーバーライドは機能しません。そして、誰かのために、サイズ変更イベントを使用した実例を得ることが役立つかもしれません。
最初にフィルターを作成するqObjectをサブクラス化します。 イベントフィルターの詳細
class FilterObject:public QObject{
public:
QWidget *target = nullptr;//it holds a pointer to target object
int goalHeight=0;
FilterObject(QObject *parent=nullptr):QObject(parent){}//uses QObject constructor
bool eventFilter(QObject *watched, QEvent *event) override;//and overrides eventFilter function
};
次に、eventFilter関数。警告を防ぐために、コードはFilterObject定義の外部で定義する必要があります。
bool FilterObject::eventFilter(QObject *watched, QEvent *event) {
if(watched!=target){//checks for correct target object.
return false;
}
if(event->type()!=QEvent::Resize){//and correct event
return false;
}
QResizeEvent *resEvent = static_cast<QResizeEvent*>(event);//then sets correct event type
goalHeight = 7*resEvent->size().width()/16;//calculates height, 7/16 of width in my case
if(target->height()!=goalHeight){
target->setFixedHeight(goalHeight);
}
return true;
};
そして、メインコードでFilterObjectを作成し、それをEventFilterリスナーとしてターゲットオブジェクトに設定します。 この回答に感謝します。
FilterObject *filter = new FilterObject();
QWidget *targetWidget = new QWidget();//let it be target object
filter->target=targetWidget;
targetWidget->installEventFilter(filter);
現在のフィルターは、すべてのtargetWidgetのイベントを受け取り、サイズ変更イベントで正しい高さを設定します。