Qtでウィジェットのアスペクト比を維持するにはどうすればよいですか?ウィジェットを中央に配置するのはどうですか?
独自のレイアウトマネージャーを実装する必要はありません。 QWidget
を継承して再実装すると、
_int QWidget::heightForWidth( int w ) { return w; }
_
正方形を保つために。ただし、heightForWidth()
はX11のトップレベルウィンドウでは機能しません。X11プロトコルではサポートされていないためです。中央揃えについては、QBoxLayout::addWidget()
の3番目のパラメーターまたはQGridLayout::addWidget()
の5番目のパラメーターとして_Qt::AlignCenter
_を渡すことができます。
注:少なくとも新しいバージョンのQtでは、QWidgetにはheightForWidth
またはwidthForHeight
がありません(したがって、オーバーライドできません)。したがって、setWidthForHeight(true)
またはsetHeightForWidth(true)
QGraphicsLayoutの子孫に対してのみ効果があります 。
正解は、カスタムレイアウトマネージャーを作成することです。 QLayout をサブクラス化することで可能になります。
resize()
内からresizeEvent()
を呼び出すことは、私にとってはうまくいきませんでした-せいぜい、無限ループで、ウィンドウが2回リサイズされると、ちらつきが発生します。
アスペクト比を一定に保つ「正しい」方法は、カスタムレイアウトを作成することだと思います。 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のイベントを受け取り、サイズ変更イベントで正しい高さを設定します。