QWidget - 调整动画大小

时间:2010-07-19 17:49:47

标签: c++ qt animation qwidget

假设我有一个QHBoxLayout,其中有QTextEdit个,其间有一个带右箭头的按钮。当您单击按钮时,右侧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会恢复其状态(但当然应保持关闭状态)。我该如何解决这个问题?

请向我提供一个代码段。

3 个答案:

答案 0 :(得分:3)

Qt's Animation framework听起来像个好地方。你可以尝试按照他们的教程,适应你的用例。我已经使用过了,看起来很简单。

答案 1 :(得分:3)

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)我猜你可以(并且应该)为widget的maximumSize(或者只是maximumWidth)属性设置动画,让布局负责计算实际几何。这也可以简化您的计算。 E.g。

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。我没有编译代码所以可能会有一些小错误,但你应该明白这个想法。

答案 2 :(得分:2)