Как сохранить соотношение сторон виджетов в Qt? - PullRequest
32 голосов
/ 17 января 2009

Как можно сохранить соотношение сторон виджетов в Qt и как насчет центрирования виджета?

Ответы [ 4 ]

16 голосов
/ 21 июля 2009

Вам не нужно реализовывать свой собственный менеджер раскладки. Вы можете сделать с наследованием QWidget и переопределением

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

чтобы оставаться на месте. Однако heightForWidth() не работает на окнах верхнего уровня на X11, поскольку, очевидно, протокол X11 этого не поддерживает. Что касается центрирования, вы можете передать Qt::AlignCenter в качестве третьего параметра QBoxLayout::addWidget() или пятого параметра QGridLayout::addWidget().

Примечание: По крайней мере в более новых версиях Qt QWidget больше не имеет heightForWidth или widthForHeight (поэтому их нельзя переопределить), и поэтому setWidthForHeight(true) или setHeightForWidth(true) действует только для потомков QGraphicsLayout .

8 голосов
/ 18 февраля 2009

Правильный ответ - создать свой собственный менеджер раскладки. Это возможно путем создания подкласса QLayout .

Методы реализации при создании подкласса QLayout

void addItem (QLayoutItem * item);
Добавляет элемент в макет.
int count () const;
Возвращает количество предметов.
QLayoutItem * itemAt (int index) const;
Возвращает ссылку на элемент по индексу или 0, если его нет.
QLayoutItem * takeAt (int index);
Принимает и возвращает элемент из макета из индекса или возвращает 0, если его нет.
Qt :: Orientations expandingDirections () const;
Возвращает макеты, расширяющие направления.
bool hasHeightForWidth () const;
Сообщает, обрабатывает ли макет высоту для расчета ширины.
QSizeimumSize () const;
Возвращает минимальный размер макетов.
void setGeometry (const QRect & rect);
Устанавливает геометрию макета и элементов внутри него. Здесь вы должны сохранить соотношение сторон и выполнить центрирование.
QSize sizeHint () const;
Возвращает предпочтительный размер для макета.

Дальнейшее чтение

5 голосов
/ 17 января 2009

Вызов resize() изнутри resizeEvent() никогда не работал для меня хорошо - в лучшем случае это вызовет мерцание, поскольку окно изменено в два раза (как у вас), в худшем случае - бесконечный цикл.

Я думаю, что «правильный» способ сохранить фиксированное соотношение сторон - это создать собственный макет. Вам придется переопределить только два метода, QLayoutItem::hasHeightForWidth() и QLayoutItem::heightForWidth().

1 голос
/ 29 сентября 2018

В моем случае переопределение heightForWidth () не работает. И кому-то может быть полезно получить рабочий пример использования события resize.

Сначала подкласс qObject для создания фильтра. Подробнее о фильтрах событий.

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

Тогда функция eventFilter. Этот код должен быть определен вне определения FilterObject, чтобы предотвратить предупреждение. Благодаря этому ответу.

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

А затем в основном коде создайте FilterObject и установите его в качестве прослушивателя EventFilter для целевого объекта. Благодаря этому ответу.

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

Теперь фильтр будет получать все события targetWidget и устанавливать правильную высоту при изменении размера.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...