QWidget - изменить размер анимации - PullRequest
1 голос
/ 19 июля 2010

Скажите, у меня есть QHBoxLayout, где есть 2 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();
}

EDIT:

И у меня следующая проблема:

Когда я закрываю второй QTextEdit (нажав на кнопку) и изменяю размер MyWidget, тогда QTextEdit восстанавливает свое состояние (но, конечно, оно должно оставаться закрытым). Как я могу решить эту проблему?

Пожалуйста, предоставьте мне фрагмент кода.

Ответы [ 3 ]

3 голосов
/ 20 июля 2010

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.Я не компилировал коды, поэтому возможны незначительные ошибки, но вы должны понять.

3 голосов
/ 19 июля 2010

Фреймворк Qt's Animation звучит как хорошее место для начала. Вы можете просто попытаться следовать их учебным пособиям, адаптируясь к вашему случаю использования. Я уже использовал это, и это казалось довольно прямым.

2 голосов
/ 25 июля 2010

Вот что я хотел:

Заголовочный файл

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 );
}
...