Call a function at a dialog execution
I'm writing an application in which I need to open a dialog and execute automatically (without clicking on a push button for example) some animation function.
For opening the dialog, the main windows has a push button that is connected to a slot, which contains
Code:
//Open the dialog
dialog dlg=new Dlg ;
dlg.exec();
//Get data from the dialog after it is closed
...
My dialog class is something like the following, where functionToBeCalled() is the function to be called:
Code:
{
/* ...other attributes and methods here... */
public:
void functionToBeCalled();
}
Could anybody tell me how to do that please?
Thank you in advance for your help.
Re: Call a function at a dialog execution
Re: Call a function at a dialog execution
Thank you wysota for your reply.
But could you please be more specific?
Someone suggested me with the following code:
Code:
int Dlg::exec()
{
functionToBeCalled();
}
but the problem is that, my functionToBeCalled() is a function that does some animation (inside a QGraphicsView), so if we call this function before the exec() function, the user will not see the animation.
I have got an idea but could not make it work. In the following code, I re-implement completely the exec() function, by just copying the source code of QDialog::exec() and adding functionToBeCalled() after show():
Code:
int Dlg::exec()
{
if (d->eventLoop) {
qWarning("QDialog::exec: Recursive call detected");
return -1;
}
bool deleteOnClose = testAttribute(Qt::WA_DeleteOnClose);
setAttribute(Qt::WA_DeleteOnClose, false);
d->resetModalitySetByOpen();
bool wasShowModal = testAttribute(Qt::WA_ShowModal);
setAttribute(Qt::WA_ShowModal, true);
setResult(0);
//On Windows Mobile we create an empty menu to hide the current menu
#ifdef Q_WS_WINCE_WM
#ifndef QT_NO_MENUBAR
if (!findChild<QMenuBar *>())
if (qt_wince_is_smartphone()) {
menuBar->setDefaultAction(doneAction);
connect(doneAction, SIGNAL(triggered()), this, SLOT(_q_doneAction()));
}
#endif //QT_NO_MENUBAR
#endif //Q_WS_WINCE_WM
bool showSystemDialogFullScreen = false;
#ifdef Q_OS_SYMBIAN
if (qobject_cast<QFileDialog *>(this) || qobject_cast<QFontDialog *>(this) ||
qobject_cast<QWizard *>(this)) {
showSystemDialogFullScreen = true;
}
#endif // Q_OS_SYMBIAN
if (showSystemDialogFullScreen) {
setWindowFlags(windowFlags() | Qt::WindowSoftkeysVisibleHint);
setWindowState(Qt::WindowFullScreen);
}
show();
/****** MY ANIMATION HERE *******/
functionToBeCalled();
#ifdef Q_WS_MAC
d->mac_nativeDialogModalHelp();
#endif
d->eventLoop = &eventLoop;
QPointer<QDialog> guard = this;
if (guard.isNull())
d->eventLoop = 0;
setAttribute(Qt::WA_ShowModal, wasShowModal);
int res = result();
if (deleteOnClose)
delete this;
#ifdef Q_WS_WINCE_WM
#ifndef QT_NO_MENUBAR
else if (menuBar)
delete menuBar;
#endif //QT_NO_MENUBAR
#endif //Q_WS_WINCE_WM
return res;
}
The first error I got is _'QDialog::d_func' : cannot access private member declared in class 'QDialog'_.
Hope somebody can help.
Have a nice day !
Re: Call a function at a dialog execution
Quote:
Originally Posted by
Nesbit
but the problem is that, my functionToBeCalled() is a function that does some animation (inside a QGraphicsView), so if we call this function before the exec() function, the user will not see the animation.
The function should only start the animation and not "perform" it. I'm not going to explain it here how Qt event system works, you should read that in the docs.
Re: Call a function at a dialog execution
Hmm... did you mean we cannot do what I wanted to do, wysota?
I tried something like
Code:
dialog.display();
animation();
It works, but lacks some features I need from dialog.exec() :(
P/s: You replied so quickly wysota, thank you so much :D
Re: Call a function at a dialog execution
Qt is an event-driven framework. If you say "show me that dialog", it does not mean the dialog is actually shown at this particular moment in time. Instead an event is generated that at some point in future will be processed and will result in initializing surface for the widget and eventually showing it on screen. The same goes with animations -- an animation usually behaves in such a way that it changes some property (like position or color) of an object. If you want to visualize such a change, you call update() on the widget which again causes an event to be generated that at some later point in time is processed and the widget is redrawn. Some time later you have to change that property again to have an effect of smoothly changing that value. The way to do this is again through events, this time triggered by a timer that tells you a specified period of time has passed. Thus your "animation()" call doesn't actually perform the animation but only schedules the first frame of the animation and subsequent frames are scheduled and performed "some time later". Thus the order of calls (like starting the animation and calling exec) does not matter since both of them are not processed immediately.
If you were thinking of doing the animation this way:
Code:
for(int i=0;i<1000;++i) item->setPos(i, 200);
then obviously this will not work since by the time the widget is updated through events, the item will already have position set to (999,200) and thus you will only see the last frame of the animation.