QWidget - 调整动画大小
Posted
技术标签:
【中文标题】QWidget - 调整动画大小【英文标题】:QWidget - resize animation 【发布时间】:2010-07-19 17:49:47 【问题描述】:假设我有一个QHBoxLayout
,其中有 2 个QTextEdit
s,它们之间有一个带有向右箭头的按钮。当您单击按钮时,右侧的QTextEdit
会通过移动左边框逐渐关闭,直到与右侧边框相遇。同时,左侧QTextEdit
的右边框取代了右侧QTextEdit
释放的位置。并且在按下按钮后,系统的状态又回到了之前的状态。
编辑:为了组织这个,我做了以下事情:
1) 在头文件中:
class MyWidget : public QWidget
Q_OBJECT
QTextEdit *m_textEditor1;
QTextEdit *m_textEditor2;
QPushButton *m_pushButton;
QHBoxLayout *m_layout;
int m_deltaX;
public:
MyWidget(QWidget * parent = 0);
~MyWidget()
private slots:
void closeOrOpenTextEdit2(bool isClosing);
;
2) 在源文件中:
MyWidget::MyWidget(QWidget * parent):QWidget(parent),m_deltaX(0)
m_pushButton = new QPushButton(this);
m_pushButton->setText(">");
m_pushButton->setCheckable(true);
connect(m_pushButton, SIGNAL(clicked(bool)), this, SLOT(closeOrOpenTextEdit2(bool)));
m_textEditor1 = new QTextEdit(this);
m_textEditor1->setText("AAAAA AAAAAAAAAAA AAAAAAAAAAA AAAAAAA AAAAAAAAAAA AAAAAAAAAAA AA");
m_textEditor2 = new QTextEdit(this);
m_layout = new QHBoxLayout;
m_layout->addWidget(m_textEditor1);
m_layout->addWidget(m_pushButton);
m_layout->addWidget(m_textEditor2);
setLayout(m_layout);
void MyWidget::closeOrOpenTextEdit2(bool isClosing)
QPropertyAnimation *animation1 = new QPropertyAnimation(m_textEditor2, "geometry");
QPropertyAnimation *animation2 = new QPropertyAnimation(m_pushButton, "geometry");
QPropertyAnimation *animation3 = new QPropertyAnimation(m_textEditor1, "geometry");
if(isClosing) //close the second textEdit
m_pushButton->setText("<");
QRect te2_1 = m_textEditor2->geometry();
m_deltaX = te2_1.width()-3;
QRect te2_2(te2_1.x()+m_deltaX, te2_1.y(), 3 ,te2_1.height());
QRect pb_1 = m_pushButton->geometry();
QRect pb_2(pb_1.x()+m_deltaX, pb_1.y(), pb_1.width() ,pb_1.height());
QRect te1_1 = m_textEditor1->geometry();
QRect te1_2(te1_1.x(), te1_1.y(), te1_1.width()+m_deltaX, te1_1.height());
//animation->setDuration(10000);
animation1->setStartValue(te2_1);
animation1->setEndValue(te2_2);
animation2->setStartValue(pb_1);
animation2->setEndValue(pb_2);
animation3->setStartValue(te1_1);
animation3->setEndValue(te1_2);
else //open
m_pushButton->setText(">");
QRect te2_1 = m_textEditor2->geometry();
QRect te2_2(te2_1.x()-m_deltaX, te2_1.y(), 3+m_deltaX ,te2_1.height());
QRect pb_1 = m_pushButton->geometry();
QRect pb_2(pb_1.x()-m_deltaX, pb_1.y(), pb_1.width() ,pb_1.height());
QRect te1_1 = m_textEditor1->geometry();
QRect te1_2(te1_1.x(), te1_1.y(), te1_1.width()-m_deltaX, te1_1.height());
//animation->setDuration(10000);
animation1->setStartValue(te2_1);
animation1->setEndValue(te2_2);
animation2->setStartValue(pb_1);
animation2->setEndValue(pb_2);
animation3->setStartValue(te1_1);
animation3->setEndValue(te1_2);
animation1->start();
animation2->start();
animation3->start();
编辑:
我有以下问题:
当我关闭第二个QTextEdit
(通过单击按钮)并调整MyWidget
的大小时,QTextEdit
会恢复其状态(但它当然应该保持关闭状态)。我该如何解决这个问题?
请给我一个代码 sn-p。
【问题讨论】:
【参考方案1】:Qt's Animation framework 听起来是个不错的起点。您可以尝试按照他们的教程进行调整,以适应您的用例。我已经用过它,而且看起来很简单。
【讨论】:
我已阅读并熟悉这些示例。不幸的是,我的经验不允许我实施这种情况。 @Narek 为什么?你能详细说明吗?出了什么问题? 好的,我已经改变了我的问题。请参见上文。【参考方案2】:1) 您可以将按钮替换为垂直布局,将按钮放置在此布局内,最后在按钮下方添加一个垂直间隔(与布局相同)。
...
QVBoxLayout* m_buttonLayout = new QVBoxLayout();
m_layout = new QHBoxLayout();
m_layout->addWidget(m_textEditor1);
m_layout->addLayout(m_buttonLayout);
m_layout->addWidget(m_textEditor2);
m_buttonLayout->addWidget(m_pushButton);
m_buttonLayout->addItem( new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding) );
2) 我想您可以(并且应该)为小部件的 maximumSize(或只是 maximumWidth)属性设置动画,并让布局负责计算实际的几何图形。这也将简化您的计算。例如
QPropertyAnimation *animation1 = new QPropertyAnimation(m_textEditor2, "maximumWidth");
QPropertyAnimation *animation2 = new QPropertyAnimation(m_textEditor, "maximumWidth");
if (isClosing)
int textEdit2_start = m_textEditor2->maximumWidth();
int textEdit2_end = 0;
int textEdit_start = m_textEditor->maximumWidth();
int textEdit_end = textEdit_start + textEdit2_start;
animation1->setStartValue(textEdit2_start);
...
此外,现在您根本不必为按钮几何图形设置动画(假设您已为其设置了固定大小)。
PS。我没有编译代码,所以可能会有一些小错误,但你应该明白。
【讨论】:
如何去掉按钮和右边QTextEdit之间的距离(原来存在于QHBoxLayout中)? 您解决第二个问题的逻辑很好,但这是一个小问题:它稍等片刻,然后立即关闭第二个 QTextEdit。当我添加 animation1->setDuration(3000); 时,它等待了更多,然后,同样的行为,immediatley 关闭了。我们如何逐步做到这一点? 您可以使用 QBoxLayout::setStretchFactor 消除布局中元素之间的间隙(即,将每个小部件的拉伸因子设置为零)。对于另一个问题,您也可以尝试为 minimumWidth 设置动画。 minimumWidth 有效,但 maxmimuWidth 没有。因此我在bugreports.qt.nokia.com 上打开了一个错误。 你可以在这里看到这个错误:bugreports.qt.nokia.com/browse/QTCREATORBUG-1916【参考方案3】:这是我想要的:
头文件
class MyWidget : public QWidget
Q_OBJECT
QTextEdit *m_textEditor1;
QTextEdit *m_textEditor2;
QPushButton *m_pushButton;
QHBoxLayout *m_layout;
QVBoxLayout *m_buttonLayout;
int m_deltaX;
bool m_isClosed;
public:
MyWidget(QWidget * parent = 0);
~MyWidget()
void resizeEvent( QResizeEvent * event );
private slots:
void closeOrOpenTextEdit2(bool isClosing);
;
源文件
MyWidget::MyWidget(QWidget * parent):QWidget(parent),m_deltaX(0)
m_pushButton = new QPushButton(this);
m_pushButton->setText(">");
m_pushButton->setCheckable(true);
m_pushButton->setFixedSize(16,16);
connect(m_pushButton, SIGNAL(clicked(bool)), this, SLOT(closeOrOpenTextEdit2(bool)));
m_textEditor1 = new QTextEdit(this);
m_textEditor1->setText("AAAAA AAAAAAAAAAA AAAAAAAAAAA AAAAAAA AAAAAAAAAAA AAAAAAAAAAA AA");
m_textEditor2 = new QTextEdit(this);
m_buttonLayout = new QVBoxLayout();
m_buttonLayout->addWidget(m_pushButton);
m_buttonLayout->addItem( new QSpacerItem(1, 1, QSizePolicy::Minimum, QSizePolicy::Expanding) );
m_layout = new QHBoxLayout;
m_layout->addWidget(m_textEditor1, 10);
m_layout->addSpacing(15);
m_layout->addLayout(m_buttonLayout);
m_layout->setSpacing(0);
m_layout->addWidget(m_textEditor2, 4);
setLayout(m_layout);
resize(800,500);
void MyWidget::closeOrOpenTextEdit2(bool isClosing)
m_isClosed = isClosing;
QPropertyAnimation *animation1 = new QPropertyAnimation(m_textEditor2, "maximumWidth");
if(isClosing) //close the second textEdit
m_textEditor2->setMaximumWidth(m_textEditor2->width());
int textEdit2_start = m_textEditor2->maximumWidth();
m_deltaX = textEdit2_start;
int textEdit2_end = 3;
animation1->setDuration(500);
animation1->setStartValue(textEdit2_start);
animation1->setEndValue(textEdit2_end);
m_pushButton->setText("<");
else //open
int textEdit2_start = m_textEditor2->maximumWidth();
int textEdit2_end = m_deltaX;
animation1->setDuration(500);
animation1->setStartValue(textEdit2_start);
animation1->setEndValue(textEdit2_end);
m_pushButton->setText(">");
animation1->start();
void MyWidget::resizeEvent( QResizeEvent * event )
if(!m_isClosed)
m_textEditor2->setMaximumWidth( QWIDGETSIZE_MAX );
【讨论】:
也许对您的解决方案的描述,而不是高度特定于您的情况代码,对 SO 上的其他人更有帮助以上是关于QWidget - 调整动画大小的主要内容,如果未能解决你的问题,请参考以下文章
当小部件集更改时,调整 QWidget 的大小以仅保存当前小部件