PDA

View Full Version : Animate an hidden widget



AlbertoN
9th October 2014, 16:38
Hi all,

I'd like to animate (show and hide) a widget when a toggle button is pressed.
I wrote this code:


MainWindow::MainWindow
{
[...]
//ui->widget->hide();//[1]
//ui->button->setChecked(false);//[2]
startgeometry = QRect(0,0,0,0);
connect(ui->button,SIGNAL(toggled(bool)),this,SLOT(togglePyShe ll(bool)));
}

void MainWindow::togglePyShell(bool show)
{
QRect formerGeometry = QRect(ui->widget->geometry());
if(startgeometry==QRect(0,0,0,0)){
startgeometry = formerGeometry;
}
if(show){
//ui->widget->show();//[3]
QPropertyAnimation *showAnimation = new QPropertyAnimation(ui->widget, "geometry");
showAnimation->setDuration(100);
showAnimation->setEasingCurve(QEasingCurve::Linear);
showAnimation->setStartValue(formerGeometry);
showAnimation->setEndValue(startgeometry);
showAnimation->start(QPropertyAnimation::DeleteWhenStopped);
}else{
QPropertyAnimation *hideAnimation = new QPropertyAnimation(ui->widget, "geometry");
hideAnimation->setDuration(100);
hideAnimation->setEasingCurve(QEasingCurve::Linear);
hideAnimation->setStartValue(formerGeometry);
QPoint endTopLeftCorner = QPoint(ui->widget->pos() + QPoint(0, ui->widget->height()));
QRect finalGeometry = QRect(endTopLeftCorner, QSize(ui->widget->width(), 0));
hideAnimation->setEndValue(finalGeometry);
hideAnimation->start(QPropertyAnimation::DeleteWhenStopped);
//ui->widget->hide();//[4]
}
}


It works if the widget is visible after costructor (and button pressed), but I'd like to start with the widget invisible (and button not checked).

I don't know how to hide the widget.
If i try to uncomment from [1] up to [4] or subset of them I have strange behaviour, because (i guess) I can't save original widget's size into startgeometry.

Any help is appreciated,
Thanks in advance.

anda_skoa
9th October 2014, 17:38
If you don't have a start geometry and you show, wouldn't the animation go from "0,0,0,0" to "current geometry"?

Cheers,
_

AlbertoN
9th October 2014, 17:47
Maybe i didn't understand your reply.

But if i remove startgeometry QRect and I show the widget I wouldn't have what I want: start with a hidden widget.

On the other hand if I hide the widget (ui->widget->hide() ) how can I get final widget's geometry of widget (for "show transition")?

AlbertoN
10th October 2014, 17:55
Thanks to anda_skoa I solved in this way, maybe it could be useful for someone else.



void MainWindow::resizeEvent(QResizeEvent *)
{
//in case of window resize we have to hide widget so we'll fall in first case(see below) and set push button as unchecked
if(ui->widget->isVisible()){
ui->widget->setHidden(true);
ui->button->setChecked(false);
}
}

void MainWindow::showWidget()
{
QRect fo;
QRect fi;

//There are 2 cases:
// 1. Widget was never shown before,
// 2.Widget was shown (at least) once and then hide again,
if(ui->widget->isHidden()){
//If the widget is hidden then we're in the first case.

//We set up y coord of starting transition to a bigger value than height coord and all other
//coords at the widget's coords; while we have to set up final transition coords to widget's coords.
//In this way it'll look like upward motion.


//PLEASE NOTE: before you have to perform ui->widget->show() and then get widget's size() and pos(), else you'll get wrong values.

ui->widget->show();
QPoint pos = ui->widget->pos();
QSize size = ui->widget->size();

fo = QRect(pos.x(),pos.y()+size.height(),size.width(),s ize.height());
fi = QRect(pos,size);
}else{
//in second case: we have to set up start transition coords at actual coords of widget, as it's hidden
//we would have y = y + height, and we set up y coord of final transition coords to y = y - height.
fo = ui->widget->geometry();
fi = QRect(fo.x(),fo.y()-fo.height(),fo.width(),fo.height());
}
QPropertyAnimation *showAnimation = new QPropertyAnimation(ui->widget, "geometry");
showAnimation->setDuration(100);
showAnimation->setEasingCurve(QEasingCurve::Linear);
showAnimation->setStartValue(fo);
showAnimation->setEndValue(fi);
showAnimation->start(QPropertyAnimation::DeleteWhenStopped);
}

void MainWindow::hideWidget()
{
//coords of starting transition must be set up at actual widget's coords, as it's visible; while final
//transition coords must be set up with: y = y + height.

QRect fo = QRect(ui->widget->geometry());
QRect fi = QRect(fo.x(),fo.y()+fo.height(),fo.width(),fo.heig ht());

QPropertyAnimation *hideAnimation = new QPropertyAnimation(ui->widget, "geometry");
hideAnimation->setDuration(100);
hideAnimation->setEasingCurve(QEasingCurve::Linear);

hideAnimation->setStartValue(fo);
hideAnimation->setEndValue(fi);
hideAnimation->start(QPropertyAnimation::DeleteWhenStopped);
}

void MainWindow::togglePyShell(bool show)
{
if(show){
showWidget();
}else{
hideWidget();
}
}