LINUX.ORG.RU

Qt5 анимация и qhboxlayout


0

1

Все привет

Сделал анимацию по свойству size класса QFrame

QPropertyAnimation *animation = new QPropertyAnimation(bufferFrame, "size");
    animation -> setDuration(400);
    animation -> setEasingCurve(QEasingCurve(QEasingCurve::OutCubic));

    if(bufferButton -> arrowType() == Qt::LeftArrow) {
        animation -> setEndValue(QSize(bufferFrame -> minimumWidth(), bufferFrame -> height()));
        bufferButton -> setArrowType(Qt::RightArrow);
    }
    else {
        animation -> setEndValue(QSize(bufferFrame -> maximumWidth(), bufferFrame -> height()));
        bufferButton -> setArrowType(Qt::LeftArrow);
    }
    animation -> start(QAbstractAnimation::DeleteWhenStopped);
Здесь bufferFrame это QFrame, а bufferButton кнопка, по которой запускается анимация. Сам виджет bufferFrame добавляется в менеджер компоновки QHBoxLayout. Анимация работает превосходно, если бы не одно «НО». После завершения анимации, если, например, изменить размер окна программы (любое действие, которое приводит к перерисовке), bufferFrame сбрасывает свое состояние = состоянию до начала анимации. Ясно, что это делает менеджер компоновки. Я пошел дальше, унаследовал QFrame и переопределил метод sizeHint() а так же добавил метод setSizeHint.
class SizeHintFrame : public QFrame {
    public:
        SizeHintFrame(QWidget * = 0);
        virtual ~SizeHintFrame();
        void setSizeHint(QSize);
        void setSizeHint(int, int);

    protected:
        virtual QSize sizeHint();

    private:
        QSize   _sizeHint;
};

SizeHintFrame::SizeHintFrame(QWidget *parent)
    : QFrame(parent) {
    // setSizeHint(QFrame::sizeHint());
}

SizeHintFrame::~SizeHintFrame() {
}

void SizeHintFrame::setSizeHint(QSize s) {
    _sizeHint = s;
}

void SizeHintFrame::setSizeHint(int h, int w) {
    _sizeHint = QSize(h, w);
}

QSize SizeHintFrame::sizeHint() {
    return _sizeHint;
}

и добавил обработку завершения анимации

void MainWindow::bufferAnimationFinneshed() {
    bufferFrame -> setSizeHint(bufferFrame -> size());
}

В консоль, по завершении анимации размеры виджета выводятся такие, какие и должны быть до и после анимации. Однако поведение не изменилось, размер виджета все-равно сбрасывается в исходный. P.S. После проделанного пробовал выставлять политику размера в QSizePolicy::Fixed, но это не помогло

Попробуй maximumSize:

#include <QApplication>

#include <QFrame>
#include <QHBoxLayout>
#include <QPushButton>
#include <QPropertyAnimation>

QFrame* bufferFrame;
QPushButton* bufferButton;

void click()
{
    QPropertyAnimation *animation = new QPropertyAnimation(bufferFrame, "maximumSize");
    animation -> setDuration(1000);
    animation -> setEasingCurve(QEasingCurve(QEasingCurve::OutCubic));

    int width;
    if(bufferButton->text() == "min") {
        width = 200;
        bufferButton->setText("max");
    }
    else {
        width = 100;
        bufferButton->setText("min");
    }
    animation -> setEndValue(QSize(width, bufferFrame -> maximumHeight()));
    animation -> start(QAbstractAnimation::DeleteWhenStopped);
}

int main(int argc, char *argv[])
{
    QApplication a(argc, argv);

    QFrame* base = new QFrame;
    QHBoxLayout* hb = new QHBoxLayout;

    base->setLayout(hb);

    bufferButton = new QPushButton("min");
    hb->addWidget(bufferButton);
    bufferButton->connect(bufferButton, &QPushButton::clicked, click);

    bufferFrame = new QFrame();
    hb->addWidget(bufferFrame);
    bufferFrame->setStyleSheet("background-color:red");

    bufferFrame->setSizePolicy(QSizePolicy::MinimumExpanding, QSizePolicy::Expanding);

    base->resize(400,100);
    base->show();

    return a.exec();
}

anonymous
()
Ответ на: комментарий от anonymous

У меня наконец то получилось то, что я хотел. Очень долго не мог понять, почему метод sizeHint не вызывался... Оказывается я забыл добавить в определение функции const...Ну да ладно, в итоге, поменял значение size на maximumSize, и все заработало...Спасибо за помощь. Вот результат

class HideShowContentAnimation : public QFrame {
    Q_OBJECT
    public:
        HideShowContentAnimation(int = 400, QEasingCurve = QEasingCurve::Linear, QWidget * = 0);
        virtual ~HideShowContentAnimation();

        void setObjectName(QString);
        void setLayout(QLayout *);
        void animate();

    protected:
        virtual void showEvent(QShowEvent*);

    private:
        int                 _duration;
        QEasingCurve        _easingCurve;
        int                 _maximum_width;
        int                 _minimum_width;
        QToolButton         *button;
        QScrollArea         *area;
        QWidget             *content;
};

HideShowContentAnimation::HideShowContentAnimation(int d, QEasingCurve e, QWidget *parent)
    : QFrame(parent), _duration(d), _easingCurve(e) {
    content = new QWidget();

    button = new QToolButton();
    button -> setArrowType(Qt::LeftArrow);

    area = new QScrollArea();
    area -> setWidget(content);
    area -> setWidgetResizable(true);
    area -> setHorizontalScrollBarPolicy(Qt::ScrollBarAlwaysOff);

    QHBoxLayout *buttonLay = new QHBoxLayout();
    buttonLay -> addStretch();
    buttonLay -> addWidget(button);

    QVBoxLayout *mainLay = new QVBoxLayout(this);
    mainLay -> setMargin(0);
    mainLay -> addLayout(buttonLay);
    mainLay -> addWidget(area);

    connect(button, &QToolButton::clicked, this, &HideShowContentAnimation::animate);
}

HideShowContentAnimation::~HideShowContentAnimation() {
}

void HideShowContentAnimation::setObjectName(QString name) {
    button -> setObjectName(name + "Button");
    area -> setObjectName(name + "Area");
    content -> setObjectName(name + "Content");
    QFrame::setObjectName(name);
}

void HideShowContentAnimation::setLayout(QLayout *lay) {
    content -> setLayout(lay);
}

void HideShowContentAnimation::animate() {
    QPropertyAnimation *animation = new QPropertyAnimation(this, "maximumSize");
    animation -> setDuration(_duration);
    animation -> setEasingCurve(QEasingCurve(_easingCurve));

    if(button -> arrowType() == Qt::LeftArrow) {
        animation -> setEndValue(QSize(0, this -> maximumHeight()));
        button -> setArrowType(Qt::RightArrow);
    }
    else {
        animation -> setEndValue(QSize(160, this -> maximumHeight()));
        button -> setArrowType(Qt::LeftArrow);
    }
    animation -> start(QAbstractAnimation::DeleteWhenStopped);
}

void HideShowContentAnimation::showEvent(QShowEvent * event) {
    QFrame::showEvent(event);
    _maximum_width = maximumWidth();
    _minimum_width = minimumWidth();
}


energyclab
() автор топика
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.