Niezrozumiałe zachowanie się obiektów w QVBoxLayout

0

Czołem Bracia programiści.

Wpierw obrazek ilustrujący:
mechdesignwidget.png
legenda:
czerwony prostokąt - inventoryLayout będący podmiotem pytania
zielony prostokąt - layout nadrzędny, zawierający powyższy
niebieskie znaki - QSpacerItem

Otóż do widgeta InventoryItem ilustrowanego przez te białe drabinki (ewentualnie pełniejsza definicja tutaj https://4programmers.net/Forum/1538413) dodałem pisany z palca QVBoxLayout:

    inventoryLayout = new QVBoxLayout;
    inventoryLayout->setDirection(QVBoxLayout::TopToBottom);
    inventoryLayout->setContentsMargins(0, 0, 0, 0);
    inventoryLayout->setSpacing(0);
    setLayout(inventoryLayout);

następnie do tegoż inventoryLayoutu wrzucam inne QWidgety:

    for (int cnt = 0; cnt < 6; cnt++)
    {
        InventoryItemWidget *item = new InventoryItemWidget(this);
        //item->move(0, cnt * slotHeight);
        inventoryLayout->addWidget(item);
    }    
    inventoryLayout->addStretch();

To działa dobrze, owe InventoryItemWidgety są dopychane do górnej krawędzi InventoryWidgeta.
Cyrki zaczynają się dziać kiedy zaczynam rozszerzać w pionie całe okno pokazane na screenie - otóż wychodzi na to, że QSpacerItem z tego InventoryLayoutu zaznaczonego na czerwonym prostokątem tak jakby wyłazi do tego zaznaczonego na zielono i pozycjonuje się między InventoryWidgetem a przyciskiem "Strip stuff", skutkiem czego przycisk zaczyna zmieniać swoje położenie zamiast być dociśnięte do InventoryWidgeta.
Jeśli usunę linię inventoryLayout->addStretch(); całość zachowywać poprawnie, tyle że obiekty M Laser oczywiście nie są wtedy dopychane do górnej krawędzi InventoryWidgeta.
Próbowałem nastawić maxSize dla InventoryWidgeta na ten zwracany przez sizeHint(), ale nie zadziałało :/

Bracia programiści, o jakim niuansie layoutów nie wiem?
Pytanie zwłaszcza do Was Bracia @MarekR22 i @tajny_agent, bo na tym forum jedynie Was kojarzę jako osoby mające styczność z Qt

EDIT:
Zgodnie z prośbą @tajny_agent dołączam efekt rozciągnięcia okna
MechDesignWidget rozciągnięty.PNG

0

Przydałyby się dwa obrazki. Jeden przed powiększeniem okna a drugi po powiększeniu. Bo nie wiem o co chodzi :P

0

Kolejna informacja jaka może mieć znaczenie - ten duży widget jest wrzucany do QMdiArea::addSubWindow(), i na jego podstawie tworzy się QMdiWindow.
Jak testowo w innym projekcie zrobiłem sobie QWidget, na niego wrzuciłem w layout pionowy dwa MechPartWidgety i od dołu QSpacerItem wertykalny to całość zachowywała się zgodnie z oczekiwaniami.

0

Łooo Panie!
Próbowałeś jakoś podglądać te layouty, jakie mają wartości? Może ten dodany 'z palca' padł ofiarą jakiegoś wstrętnego 'default'?

0

Zaczynam podejrzewać buga w Qt. Dzisiaj przeprowadziłem testy które wykluczyły wpływ QMdiWindow. Dałem widgety następująco:
+---------------------------------------+
| MechPartWidget1 |
| sizePolicyH/V - preffered |
+---------------------------------------+
+---------------------------------------+
| MechPartWidget1 |
| sizePolicyH/V - preffered |
+---------------------------------------+
| vertical spacer, expanding |
+---------------------------------------+ <--- i to wszystko siedzi w QVBoxLayout nastawionym na jakiś testowy QWidget
dodatkowo wywaliłem z InventoryWidgeta ten tworzony z palca layout, po czym wydłużałem w pionie widget testowy bardzo mocno (czytaj ze dwa ekrany 1980x1080 na wysokość).
Efekt był taki, jakby QSpacerItem nie zjadał całej dostępnej ekstra przestrzeni, a przypomnę żaden z widgetów potomnych nie miał ustawionego QSizePolicy na Expanding. Normalnie czary...albo jakiś niuans używania layoutów o którym zapomnieli się zająknąć w dokumentacji.

Jeśli powiększałem go w jakimś nieprzesadnym zakresie to ten układ widgetów i spacera zachowywał się zgodnie z oczekiwaniami.

0

W sumie w dokumentacji wspominają, że:

Normally, you don't need to use this class directly. Qt's built-in layout managers provide the following functions for manipulating empty space in layouts:(...)

Więc może faktycznie te spacery eymagają jakiejś specjalnej uwagi.
No i rzeczywiście addStretch czy addSpacing w zupełności mi wystarczają.
Zlap resizeEvent i wypisz na qDebug dane o tym QSpacerItem.Wtedy zobaczysz przy jakich wymiarach zaczyna wariować:-)

0

Co to za klasa, QSpacerItem?
addStretch() dodaje koniec końców QSpacerItem, addSpacing() dodaje odstęp między elementami umieszczonymi w layoucie. Natomiast problematyczne(?) QSpacerItemy są dodane w Designerze, to te 5 sztuk pionowych, bardzo długich QSpacerItemy

A teraz lepszy numer - to co opisałem w poprzednim poście dotyczyło wydzielonego, miniaturowego projektu jaki stworzyłem w celu analizy problemu. Tymczasem w głównym wywaliłem problematyczny layout z InventoryWidgeta, i dałem pozycjonowanie QWidgetów potomnych ręcznie. Następnie sobie rozciągnąłem okno MechDesignWIdget w pionie...i działa jak złoto, gdzieś do 5-7k pikseli powiększyłem (6 ekranów), i nie było problemu.

1 użytkowników online, w tym zalogowanych: 0, gości: 1