Comment est-il possible de conserver le rapport hauteur/largeur des widgets dans Qt et qu’en est-il du centrage du widget?
Vous n'êtes pas obligé d'implémenter votre propre gestionnaire de disposition. Vous pouvez faire avec hériter de QWidget
et réimplémenter
int QWidget::heightForWidth( int w ) { return w; }
rester carré. Cependant, heightForWidth()
ne fonctionne pas sur les fenêtres de niveau supérieur sur X11, car apparemment le protocole X11 ne le supporte pas. En ce qui concerne le centrage, vous pouvez passer Qt::AlignCenter
en tant que troisième paramètre de QBoxLayout::addWidget()
ou cinquième paramètre de QGridLayout::addWidget()
.
Remarque: Dans les versions plus récentes de Qt au moins, QWidget n’a plus la valeur heightForWidth
ou widthForHeight
(elle ne peut donc pas être ignorée), et donc setWidthForHeight(true)
ou setHeightForWidth(true)
n’a d’effet que pour les descendants de QGraphicsLayout .
La bonne réponse est de créer votre gestionnaire de disposition personnalisé. Cela est possible en sous-classant QLayout .
Appeler resize()
depuis resizeEvent()
n'a jamais bien fonctionné pour moi. Au mieux, cela provoquera un scintillement lorsque la fenêtre est redimensionnée deux fois (comme vous l'avez déjà fait), au pire, une boucle infinie.
Je pense que le "bon" moyen de conserver un format d'image fixe consiste à créer une mise en page personnalisée. Vous devrez remplacer seulement deux méthodes, QLayoutItem::hasHeightForWidth()
et QLayoutItem::heightForWidth()
.
Dans mon cas, remplacer heightForWidth () ne fonctionne pas. Et, pour quelqu'un, il pourrait être utile d'avoir un exemple concret d'utilisation de l'événement resize.
Dans la première sous-classe, qObjet pour créer un filtre. En savoir plus sur les filtres d'événement.
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
};
Puis la fonction eventFilter. Son code doit être défini en dehors de la définition de FilterObject pour éviter les avertissements. Merci à cette réponse.
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;
};
Et ensuite, dans le code principal, créez FilterObject et définissez-le comme écouteur EventFilter comme objet cible. Merci à cette réponse.
FilterObject *filter = new FilterObject();
QWidget *targetWidget = new QWidget();//let it be target object
filter->target=targetWidget;
targetWidget->installEventFilter(filter);
Désormais, le filtre recevra tous les événements de targetWidget et définira la hauteur correcte lors d'un événement de redimensionnement.