PDA

View Full Version : Load new view (.ui) from the previous view



das.joyita
30th November 2016, 11:20
Hi,

I want to create an application whose content of the window will change after some time (like a time-lapse or timeout). E.g. I have created different .ui files for different content:

a.ui

b.ui

First the main view "a.ui" is visible and after some time I want to "b.ui" to load into the same window. Any idea how to do this?

(I tried to hiding one window and show another. But is there a better way of doing it where one view dissolves and the other one appears.)

d_stranz
30th November 2016, 15:33
I am sure you understand that .ui files are compiled into your program and are not used at runtime, right?

You can simulate fade in / fade out using the QWidget::windowOpacity() property and QPropertyAnimation. Animate the opacity for the widget you want to fade out to go from 1.0 to 0.0 and at the same time animate the opacity for the widget you want to fade in from 0.0 to 1.0. When you want to do a dissolve, set the opacity for the fade in widget to 0.0 and the fade out widget to 1.0, call QWidget::show() on both, then start the animations. You can connect the fade out widget's QWidget::hide() slot to the QAbstractAnimation::finished() signal to properly hide it once the animation ends.

das.joyita
30th November 2016, 17:04
Thank you. Yes i understand the ui files are compiled since they are being built on QT designer. Sorry, I am very new to QT. Is the below idea right , can you please correct me. Now when i run the application , it crashes.


void MainWindow::changeView(QWidget *parent){

//to load the second view after a time lapse
//parent->windowOpacity()
second = new secondView(this);
QPropertyAnimation *animation = new QPropertyAnimation(parent, "windowOpacity()");
QPropertyAnimation *animation2 = new QPropertyAnimation(second, "windowOpacity()");
animation->setDuration(5000);
animation2->setDuration(5000);
second->show();
animation->setStartValue(1.0);
animation2->setStartValue(0.0);
animation->setEndValue(0.0);
animation2->setEndValue(1.0);
parent->hide();
}

d_stranz
30th November 2016, 22:39
I think in lines 6 and 7 you want "windowOpacity", not "windowOpacity()". And it probably should be:



QString( "windowOpacity" ).toLatin1();
// or
QString( "windowOpacity" ).toUtf8();


since the property name is a QByteArray type. I don't know which version is appropriate; you'll have to check.

Each time you create the new "second" window, that's a memory leak. "second" should be a member variable of MainWindow, and you should create it once in the MainWindow constructor. You haven't given it a size. You should also set its opacity to 0 so that when it is first shown, it is invisible because it is totally transparent. You do not want to hide "parent" in line 15, because that makes it disappear immediately instead of fading out.

As I said in my original post, connect parent's hide() slot to the "animation" finished() signal. This will cause it to actually be hidden when its opacity animation ends (at which point it is totally transparent).

You will find the 5 seconds is much too long for this. 2 - 3 seconds will probably look better and lead to less impatience.

You might also want to disable both widget when you start the dissolve so the user can't click on anything inside them. In the slot connected to the "animation2" finished() signal, you should enable "second".

d_stranz
2nd December 2016, 01:00
I am sure you understand that .ui files are compiled into your program and are not used at runtime, right?

I was a bit wrong with this statement. See QUiLoader.

anda_skoa
2nd December 2016, 07:57
I was a bit wrong with this statement. See QUiLoader.

Sure, but you were still quite right as that is almost never used.
Basically only if the application supports some form of user scripting and needs a way for scripts to load UI.

Cheers,
_

d_stranz
2nd December 2016, 16:33
Agreed. I think it is a quite dangerous thing to put in the hands of a user who could make changes that destroy an app's GUI.

das.joyita
5th December 2016, 11:23
Hi, Thanks for the replies both of you. Sorry, but I am still confused. Not sure how to use QAbstractAnimation:: finished () linking to the hiding of parent view.



QPropertyAnimation *animation = new QPropertyAnimation(parent, QString("windowOpacity").toLatin1());//windowOpacity");
QPropertyAnimation *animation2 = new QPropertyAnimation(second, QString("windowOpacity").toLatin1());//"windowOpacity");
animation->setDuration(3000);
animation2->setDuration(3000);
animation2->setStartValue(0.0);
ui->centralWidget->setEnabled(true);
second->show();
animation->setStartValue(1.0);

animation->setEndValue(0.0);
animation2->setEndValue(1.0);


I am doing the above code, but now things are running very quickly and I cant see any animation, only the second view. The first parent view is visible but behind the second view.

d_stranz
5th December 2016, 17:16
void MainWindow::dissolve( QWidget * pFadeOut, QWidget * pFadeIn )
{
QByteArray opacityProp( QString( "windowOpacity" ).toLatin1() );
QPropertyAnimation * pFadeOutAnimation = new QPropertyAnimation( pFadeOut, opacityProp );
QPropertyAnimation * pFadeInAnimation = new QPropertyAnimation( pFadeIn, opacityProp );

int duration = 3000;
pFadeOutAnimation->setDuration( duration );
pDafeOutAnimation->setStartValue( 1.0 );
pFadeOutAnimation->setEndValue( 0.0 );

// Hide the fade out widget when the animation has stopped
connect( pFadeOutAnimation, &QPropertyAnimation::finished, pFadeOut, &QWidget::hide );

pFadeInAnimation->setDuration( duration );
pFadeInAnimation->setStartValue( 0.0 );
pFadeInAnimation->setEndValue( 1.0 );

// Ensure the fade in widget is showing, but make it invisible by setting opacity to 0
if ( !pFadeIn->isVisible() )
{
pFadeIn->setWindowOpacity( 0.0 );
pFadeIn->show();
}

pFadeOutAnimation->start( QAbstractAnimation::DeleteWhenStopped );
pFadeInAnimation->start( QAbstractAnimation::DeleteWhenStopped );
}


Not tested, so may require some edits.

das.joyita
6th December 2016, 11:49
Thanks so much. Its works beautifully. You are a savior :)