[Сниппеты Qt] Раздвижное меню (слайдер)

Дмитрий Филатов
Понадобилось мне написать программу для управления контроллером при помощи компьютера по протоколу ModBus. Встал вопрос - куда вынести меню настроек подключения? Хотелось сделать это меню ненавязчивым и симпатичным. Вот тут-то я и вспомнил про концепцию слайдеров и реализовал раздвижное меню.Чтобы сделать такую красоту, нужно поместить на форму компонент QFrame и кнопку QPushButton. Логично расположить фрейм прямо под кнопкой, будто бы наше меню разворачивается от неё. Внутри фрейма необходимо положить слой QFormLayout и все необходимые элементы разместить в нём. Я ещё прописал стиль для кнопки, чтобы она выглядела как ссылка:

Свойство styleSheet QPushButton

QPushButton { background-color: transparent; border: none; color:blue;}
QPushButton:pressed { background-color: transparent; border: none; }

И курсор поменял на cursor: Pointing Hand. Также я задал стиль для фрейма, чтобы он был белым с чёрной границей:

Свойство styleSheet QFrame

QFrame {background-color: white; border: 1px solid black;}
QLabel {border: none;}

В итоге, получилось вот так:Теперь оживим наш фрейм.

Раздвижное меню (слайдер) на Qt

#include <QStateMachine>
#include <QState>
#include <QPropertyAnimation>
#include <QSignalTransition>

...

//Этот код следует разместить в конструкторе формы
QStateMachine *machine = new QStateMachine(this);
QState *state_expand = new QState(machine);
QState *state_collapse = new QState(machine);

QPropertyAnimation *animation = new QPropertyAnimation(ui->frame, "size");

animation->setDuration(1000); //Скорость анимации, мс

state_expand->assignProperty(ui->frame, "size", QSize(ui->frame->width(), ui->frame->height())); //Раскрытое состояние

QSignalTransition *transition_expand = state_expand->addTransition(ui->setButton, SIGNAL(clicked()), state_collapse);
transition_expand->addAnimation(animation);

state_collapse->assignProperty(ui->frame, "size", QSize(ui->frame->width(), 0));

QSignalTransition *transition_collapse = state_collapse->addTransition(ui->setButton, SIGNAL(clicked()), state_expand); //Закрытое состояние (в данном примере анимируется высота фрейма, но вообще можно анимировать любое его измерение)
transition_collapse->addAnimation(animation);

machine->setInitialState(state_collapse); //По-умолчанию фрейм свёрнут
machine->start();
2015-08-25