问题是,您将小部件放置在一个布局中,然后尝试自己管理它们的几何图形。一个解决方法是在动画组完成后,通过交换两个小部件来更新布局。然后你的代码变成…
SwapItemsTest::SwapItemsTest(QWidget *parent)
: QMainWindow(parent)
{
ui.setupUi(this);
auto layout = new QHBoxLayout;
auto toolButton = new QToolButton;
auto left = new QLabel("Left");
left->setFixedSize(50, size().height());
left->setFrameShape(QFrame::Box);
left->setFrameShadow(QFrame::Plain);
left->setLineWidth(2);
left->setAlignment(Qt::AlignCenter);
auto right = new QLabel("Right");
right->setFixedSize(50, size().height());
right->setAlignment(Qt::AlignCenter);
right->setFrameShape(QFrame::Box);
right->setFrameShadow(QFrame::Plain);
right->setLineWidth(2);
layout->addWidget(left);
layout->addSpacerItem(new QSpacerItem(40, 40));
layout->addWidget(toolButton);
layout->addSpacerItem(new QSpacerItem(40, 40));
layout->addWidget(right);
ui.centralWidget->setLayout(layout);
auto widgets = std::array{left, right};
connect(toolButton, &QToolButton::clicked,
/*
* Note that layout has been added to the capture list for this lambda.
*/
[layout, widgets]()
{
QParallelAnimationGroup* animGroup = new QParallelAnimationGroup;
for (int i = 0; i < 2; ++i) {
//widgets is an array of 2 QLabels
QPropertyAnimation* anim = new QPropertyAnimation(widgets[i], "geometry");
anim->setDuration(750);
anim->setStartValue(widgets[i]->geometry());
widgets[i]->setProperty("animating", true);
anim->setEndValue(widgets[!i]->geometry());
anim->setEasingCurve(QEasingCurve::OutBack);
animGroup->addAnimation(anim);
}
/*
* This is the lambda that will be invoked when the
* QPropertyAnimation::finished signal is emitted. It simply
* swaps the positions of the two widgets in the layout.
*/
connect(animGroup, &QPropertyAnimation::finished,
[layout, widgets]()
{
auto index0 = layout->indexOf(widgets[0]);
auto index1 = layout->indexOf(widgets[1]);
if (index0 < index1) {
layout->takeAt(index1);
layout->takeAt(index0);
layout->insertWidget(index0, widgets[1]);
layout->insertWidget(index1, widgets[0]);
} else {
layout->takeAt(index0);
layout->takeAt(index1);
layout->insertWidget(index1, widgets[0]);
layout->insertWidget(index0, widgets[1]);
}
});
animGroup->start(QAbstractAnimation::DeleteWhenStopped);
});
}
注意,如果调整父窗口小部件的大小,您可能仍然会看到一些奇怪的行为。
在期间
动画。