Comment maintenir widgets rapport d'aspect dans Qt?

Comment est-il possible de maintenir le format des widgets dans Qt et qu'en est-il du centrage du widget?

31
demandé sur Bleadof 2009-01-17 01:50:35

4 réponses

vous n'avez pas à mettre en œuvre votre propre gestionnaire de mise en page. Vous pouvez faire avec l'héritage QWidget et la réimplantation

int QWidget::heightForWidth( int w ) { return w; }

pour rester en place. Cependant, heightForWidth() ne fonctionne pas sur windows de niveau supérieur sur X11, car apparemment le protocole X11 ne supporte pas cela. Comme pour le centrage, vous pouvez passer Qt::AlignCenter comme le troisième paramètre de QBoxLayout::addWidget() ou le cinquième paramètre de QGridLayout::addWidget() .

Note: Dans les versions plus récentes de Qt au moins, QWidget n'a plus le heightForWidth ou widthForHeight (donc ils ne peuvent pas être remplacés), et donc setWidthForHeight(true) ou setHeightForWidth(true) ont seulement un effet pour les descendants de QGraphicsLayout .

16
répondu Marc Mutz - mmutz 2015-11-23 09:38:05

la bonne réponse est de créer votre gestionnaire de mise en page personnalisé. Cela est possible en sous-classant QLayout .

les Méthodes à mettre en œuvre lorsque les sous-classement QLayout

void addItem (QLayoutItem* item); Ajoute l'élément de mise en page. int count () const; Retourne le nombre d'éléments. QLayoutItem* itemAt (int index) const; Renvoie la référence de l'article à l'index ou 0 s'il y a aucun. QLayoutItem* takeAt (int index); Prend et renvoie l'élément de la mise en page à partir de l'index ou renvoie 0 s'il n'y en a pas. Qt::Orientations expandingDirections () const; Renvoie les mises en page en expansion. bool hasHeightForWidth () const; Indique si la disposition traite de la hauteur pour le calcul de la largeur. QSize minimumSize () const; Retourne les dispositions de taille minimale. void setGeometry (const QRect& rect); Définit la géométrie de la mise en page et les éléments à l'intérieur. Ici vous devez maintenir le rapport d'aspect et faire le centrage. QSize sizeHint () const; Retourne la taille préférée pour la mise en page.

lire la suite

8
répondu Bleadof 2009-03-02 13:27:10

appelant resize() de l'intérieur de resizeEvent() n'a jamais bien fonctionné pour moi -- au mieux, il causera des scintillements que la fenêtre est redimensionnée deux fois (comme vous avez), au pire une boucle infinie.

je pense que la façon" correcte " de maintenir un rapport d'aspect fixe est de créer un layout personnalisé. Vous devrez remplacer seulement deux méthodes, QLayoutItem::hasHeightForWidth() et QLayoutItem::heightForWidth() .

5
répondu dF. 2009-01-17 00:13:34

dans mon cas, l'option overriding heightForWidth() ne fonctionne pas. Et, pour quelqu'un, il pourrait être utile d'obtenir de travail exemple de l'utilisation de l'événement de redimensionnement.

dans la première sous-classe qObject pour créer un filtre. plus sur les filtres d'événements.

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 fonction eventFilter. Son code doit être défini en dehors de la définition de FilterObject pour prévenir l'avertissement. 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 puis dans le code principal créer FilterObject et le mettre comme écouteur EventFilter à l'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);

maintenant le filtre recevra tous les événements de targetWidget et réglera la hauteur correcte à l'événement redimensionner.

0
répondu PolyGlot 2018-09-29 15:58:10