2015-05-02 15 views
5

Tworzę nowy widżet, podklasy klasy QWidget. Chciałbym móc ustawić współczynnik (dla jego wysokości i szerokości) dla tego widgetu, który zawsze będzie utrzymywany.Zachowywanie proporcji podrzędnego QWidget podczas zmiany rozmiaru

Do tego zawsze szukałem, korzystając z dokumentacji Qt5, Google i Stackoverflow. Oczywiście znalazłem odpowiedzi: w szczególności this one. Ale, niestety, nawet jedna jest w pełni skuteczna:

  • Ustawianie sizeIncrement robi całkowicie nic, nawet jeśli widżet jest okno
  • Próbowałem przeciążać resizeEvent, ale ja naprawdę nie wiem, jak to zrobić to ...
  • Jeśli śledzę this answer, dwie rzeczy:

    1. Jeśli widżet jest okno najwyższego poziomu, proporcja nie jest utrzymana w ogóle, mogę zmienić jego rozmiar, jak chcę.
    2. Po umieszczeniu tego widgetu w układzie, jeśli tylko zwiększę zarówno szerokość, jak i wysokość okna, proporcja zostanie zachowana. Ale gdy tylko zwiększę szerokość lub wysokość, widget zostanie spłaszczony. Zamiast tego chciałbym, aby układ automatycznie dostosowywał swój rozmiar, aby zachować proporcje widżetu.

Tak, jak uda mi się zachować proporcje na podklasy QWidget?

+0

Oto kolejny wpis, nad którym pracowałem, który działa dobrze, przynajmniej dla 'QLabel's. http://stackoverflow.com/questions/8211982/qt-resizing-a-qlabel-containing-a-qpixmap-while-keeping-its-aspect-ratio – phyatt

+0

Czy próbowałeś reimplementacji 'QWidget :: heightForWidth()'? To pozwala określić współczynnik kształtu. Jeśli to nie wystarczy, utwórz macierzysty "dummy" QWidget, aby trzymać widżet w 3G3 QGridLayout, z widżetem w środku i QSpacerItem wokół krawędzi (patrz 'QGridLayout :: addItem()'). QSpacerItem może zapewnić dodatkowe odstępy (lub mieć rozmiar do 0) w razie potrzeby podczas zmiany rozmiaru. Prawdopodobnie będziesz musiał użyć 'QGridLayout :: setColumnStretch()' i 'QGridLayout :: setRowStretch()'. – Anthony

+0

Dziękuję wam, wasze rozwiązania działają, ale pozostaje ten sam problem: jeśli spróbuję zwiększyć wyłącznie szerokość widżetu, współczynnik proporcji nie będzie już dłużej utrzymywany. – Spirine

Odpowiedz

5

Utwórz widżet nadrzędny (np. AspectRatioWidget), w którym chcesz umieścić swój widget. Dla widgetu nadrzędnego podklasę QWidget i nadaj mu QBoxLayout. Umieść widget na środku, a QSpacerItems po obu stronach. Następnie w widżecie nadrzędnym QWidget::resizeEvent dostosuj kierunek i rozciągnij w razie potrzeby. Podałem przykład poniżej. Aby użyć, wystarczy utworzyć instancję AspectRatioWidget i przekazać konstruktorowi wskaźnik do widgetu i pożądany współczynnik proporcji.

// header 
class AspectRatioWidget : public QWidget 
{ 
public: 
    AspectRatioWidget(QWidget *widget, float width, float height, QWidget *parent = 0); 
    void resizeEvent(QResizeEvent *event); 

private: 
    QBoxLayout *layout; 
    float arWidth; // aspect ratio width 
    float arHeight; // aspect ratio height 
}; 

// cpp 
AspectRatioWidget::AspectRatioWidget(QWidget *widget, float width, float height, QWidget *parent) : 
    QWidget(parent), arWidth(width), arHeight(height) 
{ 
    layout = new QBoxLayout(QBoxLayout::LeftToRight, this); 

    // add spacer, then your widget, then spacer 
    layout->addItem(new QSpacerItem(0, 0)); 
    layout->addWidget(widget); 
    layout->addItem(new QSpacerItem(0, 0)); 
} 

void AspectRatioWidget::resizeEvent(QResizeEvent *event) 
{ 
    float thisAspectRatio = (float)event->size().width()/event->size().height(); 
    int widgetStretch, outerStretch; 

    if (thisAspectRatio > (arWidth/arHeight)) // too wide 
    { 
     layout->setDirection(QBoxLayout::LeftToRight); 
     widgetStretch = height() * (arWidth/arHeight); // i.e., my width 
     outerStretch = (width() - widgetStretch)/2 + 0.5; 
    } 
    else // too tall 
    { 
     layout->setDirection(QBoxLayout::TopToBottom); 
     widgetStretch = width() * (arHeight/arWidth); // i.e., my height 
     outerStretch = (height() - widgetStretch)/2 + 0.5; 
    } 

    layout->setStretch(0, outerStretch); 
    layout->setStretch(1, widgetStretch); 
    layout->setStretch(2, outerStretch); 
}