gpt4 book ai didi

c++ - Qt QPropertyAnimation for widgets in layout - widgets shaking

转载 作者:太空宇宙 更新时间:2023-11-04 13:11:41 28 4
gpt4 key购买 nike

当使用 QVboxLayout 排列小部件时,我想使用 QPropertyAnimation 增加小部件的高度。问题是,当我打开多个小部件时,它们会在动画期间开始移动/摇动。

我在这里准备了最小的工作示例 tar gz project当您按下第一个、第二个、第三个小部件的“打开”按钮时出现问题,然后您可以看到它们在摇晃,在“打开”动画期间略微上下移动。

有人知道如何避免这种情况吗?我可以在主布局上设置 setSizeConstraint(QLayout::SetFixedSize) 并且它们不会抖动,但是然后调整大小和其他不起作用。

最好的问候

马立克

最佳答案

前段时间我写了一个布局,它为它包含的小部件位置设置动画。您应该以这样的方式构建您的布局,即每个应该动画的小部件都应该在此布局内(每个应该动画的小部件一个 AnimLayout):

#include <QLayout>

QT_FORWARD_DECLARE_CLASS(QPropertyAnimation)

class AnimLayout : public QLayout
{
Q_OBJECT

Q_PROPERTY(QPoint delta
READ delta
WRITE setDelta
NOTIFY deltaChanged)

Q_PROPERTY(QRect widgetRect
READ widgetRect
WRITE setWidgetRect
NOTIFY widgetRectChanged)

Q_PROPERTY(bool active
READ isDeltaActive
WRITE setDeltaActive
NOTIFY deltaActiveChanged)

public:
explicit AnimLayout(QWidget *parent = 0);
~AnimLayout();

QPoint delta() const;
void setDelta(const QPoint &value);

QSize sizeHint() const;
void setGeometry(const QRect &);
QSize minimumSize() const;
int count() const;
QSize deltaSize() const;

QRect widgetRect() const;
void setWidgetRect(const QRect &value);

bool isDeltaActive() const;
void setDeltaActive(bool active = true);

void updateItemPosition();
private:
void addItem(QLayoutItem *item);
QLayoutItem *itemAt(int index) const;
QLayoutItem *takeAt(int index);

signals:
void deltaChanged(const QPoint &value);
void widgetRectChanged(const QRect &value);
void deltaActiveChanged(bool active);

public slots:
void testIt();

private:
QLayoutItem *item;
QPropertyAnimation *animation;
QPoint mDelta;
bool mDeltaActive;
};
///////////////////////////////////////////////////////////
#include "animlayout.h"
#include <QPropertyAnimation>

AnimLayout::AnimLayout(QWidget *parent) :
QLayout(parent) ,
item(0)
{
animation = new QPropertyAnimation(this);
animation->setPropertyName("widgetRect");
animation->setDuration(400);
animation->setTargetObject(this);
mDeltaActive = false;
}

AnimLayout::~AnimLayout()
{
delete item;
}

QPoint AnimLayout::delta() const
{
return mDelta;
}

void AnimLayout::setDelta(const QPoint &value)
{
if (mDelta != value) {
mDelta = value;
emit deltaChanged(mDelta);
invalidate();
}
}

void AnimLayout::addItem(QLayoutItem *newItem)
{
Q_ASSERT(!item);
animation->stop();
item =newItem;
emit widgetRectChanged(item->geometry());
invalidate();
}

QSize AnimLayout::sizeHint() const
{
if (!item)
return QSize();
QSize result(item->sizeHint());
result += deltaSize();

int m = 2*margin();
result += QSize(m,m);

return result;
}

void AnimLayout::updateItemPosition()
{
QRect dest = contentsRect();

QPoint d = delta();
if (isDeltaActive()) {
d = -d;
}

if (d.x()!=0) {
if (d.x()>0) {
dest.setLeft(dest.left()+d.x());
} else {
dest.setRight(dest.right()+d.x());
}
}

if (d.y()) {
if (d.y()>0) {
dest.setTop(dest.top()+d.y());
} else {
dest.setBottom(dest.bottom()+d.y());
}
}

animation->setEndValue(dest);
if (widgetRect()!=dest) {
animation->start();
}
}

void AnimLayout::setGeometry(const QRect &rect)
{
QLayout::setGeometry(rect);

updateItemPosition();
}

QLayoutItem *AnimLayout::itemAt(int i) const
{
return i==0?item:0;
}

QLayoutItem *AnimLayout::takeAt(int i)
{
Q_ASSERT(i==0);
QLayoutItem *r = item;
item = 0;
return r;
}

void AnimLayout::testIt()
{
setDeltaActive(!isDeltaActive());
}

QRect AnimLayout::widgetRect() const
{
if (item)
return item->geometry();
return QRect();
}

void AnimLayout::setWidgetRect(const QRect &value)
{
if (item && item->geometry()!=value) {
item->setGeometry(value);
emit widgetRectChanged(item->geometry());
}
}

bool AnimLayout::isDeltaActive() const
{
return mDeltaActive;
}

void AnimLayout::setDeltaActive(bool active)
{
if (active!=mDeltaActive) {
mDeltaActive = active;
animation->stop();
updateItemPosition();
emit deltaActiveChanged(active);
}
}

QSize AnimLayout::minimumSize() const
{
QSize result(deltaSize());
if (item) {
result += item->minimumSize();
}
int m = 2*margin();
result += QSize(m,m);
return result;
}

int AnimLayout::count() const
{
return item?1:0;
}

QSize AnimLayout::deltaSize() const
{
return QSize(qAbs(mDelta.x()), qAbs(mDelta.y()));
}

它有一些您不需要的额外功能 (mDelta)。

关于c++ - Qt QPropertyAnimation for widgets in layout - widgets shaking,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39486336/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com