Jak utrzymać proporcje widgetów w Qt?

Jak można utrzymać proporcje widgetów w Qt i co z centrowaniem widgetu?

Author: Bleadof, 2009-01-17

4 answers

Nie musisz implementować własnego layout managera. Możesz zrobić z dziedziczeniem QWidget i reimplementacją

int QWidget::heightForWidth( int w ) { return w; }
/ Align = "left" / Jednak heightForWidth() nie działa na najwyższych poziomach windows na X11, ponieważ najwyraźniej protokół X11 tego nie obsługuje. Jeśli chodzi o centrowanie, możesz przekazać Qt::AlignCenter jako trzeci parametr QBoxLayout::addWidget() lub piąty parametr QGridLayout::addWidget().

Uwaga: przynajmniej w nowszych wersjach Qt, QWidget nie ma już heightForWidth ani widthForHeight (więc nie mogą być nadpisane), a zatem setWidthForHeight(true) lub setHeightForWidth(true) mają wpływ tylko na Potomków QGraphicsLayout .

 16
Author: Marc Mutz - mmutz,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-11-23 09:38:05

Właściwą odpowiedzią jest utworzenie niestandardowego menedżera układu. Jest to możliwe dzięki podklasowaniu QLayout.

Metody implementacji przy podklasowaniu QLayout

void addItem (QLayoutItem * item); Dodaje element do układu. int count () const; Zwraca liczbę elementów. QLayoutItem * itemAt (int index) const; Zwraca odniesienie do elementu w indeksie lub 0, jeśli nie ma żadnego. QLayoutItem* takeAt (int index); Pobiera i zwraca element z układu from index lub zwraca 0, jeśli nie ma żadnego. Qt:: Orientations expandingDirections () const; Zwraca rozszerzające się kierunki układów. bool hasHeightForWidth () const; Informuje, czy układ obsługuje wysokość do obliczania szerokości. QSize minimumSize () const; Zwraca minimalny rozmiar układów. void setGeometry (const QRect& rect); Ustawia geometrię układu i elementów wewnątrz niego. Tutaj musisz zachować proporcje i zrobić centrowanie. QSize sizeHint () const; Zwraca preferowany rozmiar układu.

Czytaj dalej

 8
Author: Bleadof,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-03-02 13:27:10

Wywołanie resize() from within resizeEvent() nigdy nie działało dobrze dla mnie-w najlepszym wypadku spowoduje migotanie, gdy okno zostanie dwukrotnie zmienione (tak jak ty), w najgorszym nieskończoną pętlę.

Myślę, że "poprawnym" sposobem na utrzymanie stałego współczynnika proporcji jest stworzenie niestandardowego układu. Musisz nadpisać tylko dwie metody, QLayoutItem::hasHeightForWidth() i QLayoutItem::heightForWidth().

 5
Author: dF.,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-01-17 00:13:34

W moim przypadku nadrzędna funkcja heightForWidth () nie działa. A dla kogoś pomocne może być uzyskanie roboczego przykładu użycia zdarzenia resize.

Na początku podklasy qObject do utworzenia filtra. więcej o filtrach zdarzeń.

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
};

Następnie funkcja eventFilter. Jego kod powinien być zdefiniowany poza definicją FilterObject, aby zapobiec ostrzeganiu. Dzięki tej odpowiedzi.

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;
};

A następnie w kodzie głównym Utwórz FilterObject i ustaw go jako słuchacz EventFilter na obiekt docelowy. Dzięki tej odpowiedzi.

FilterObject *filter = new FilterObject();
QWidget *targetWidget = new QWidget();//let it be target object
filter->target=targetWidget;
targetWidget->installEventFilter(filter);

Teraz filter odbierze wszystkie zdarzenia targetWidget i ustawi prawidłową wysokość przy zdarzeniu resize.

 0
Author: PolyGlot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-09-29 15:58:10