PDA

View Full Version : To get the program execution back to main gui ?



Krish
8th April 2008, 10:02
Hello Friends,
I am working in windows.In my gui am calling a function say do_something(); which is implemented in the outer class. Now sometimes its implementation takes too much time so i want the user to stop that outer execution, i mean i want the program execution back to my gui so that user can do few other things.

I tried it but its not returning back until the function implementation is not over. Like i tired to click some other buttons in my gui but those slots are implemented after program execution returns back !!

Can anyone please help me out in this?:) I will be thankful.

wysota
8th April 2008, 10:04
You can either use QCoreApplication::processEvents() or redesign your function to consist of many small steps that will be called from the event loop one after another.

Krish
8th April 2008, 11:14
Thank you Wysota Sir,
I went through QCoreApplication documentation from where i came to know that QCoreApplication object has to be created in main() of Non-GUI application. Also as QCoreApplication:: processEvents() function is static.

Ok now for informing i have sample.cpp where all my gui slots are implemented. Now i called do_something(); in this as: -


///////////Sample.cpp/////////
....
......
void sample::do_something()
{
....
.....
Do::do_something(); // This is function in Do class which is Non-gui & doesn't have main() function.
}
..
...
....

I think i can't use QCoreApplication:: processEvents(proper_flags) just after Do::do_something();OR before it, right?
Because even after trying it its not working.:confused:

So am i doing it wrong or will i have to drop the plan of stopping its execution & let it run till it finishes. And go with your 2nd option i.e. to create small functions so that i can from time to time get back to gui ?

Thanks again.

ChristianEhrlicher
8th April 2008, 12:10
When you need to call another lib/app where you've no control of, I would recommend to move this call into an own thread.

wysota
8th April 2008, 12:46
You see... in C++ we have a concept called "inheritance" which among other things says that objects from classes inheriting other classes have their methods available. Now QApplication inherits QCoreApplication. Does that ring a bell?

Krish
8th April 2008, 13:35
Thanks Christian for taking out time & suggesting me QThread, I will look into that .

Thanks Wysota, sorry i just missed to see the inheritance property between them. Yes sir I know that we can use the functions of inherited class. But Sir i tried to call the function but the execution is not coming back at user's request. Can you please tell me like from where to call QCoreApplication:: processEvents(proper_flags) function. I mean i know that it allows to process the events of only the calling class/thread, but from where like before calling do_something(); or ..

Thanks again.

wysota
8th April 2008, 13:38
void mylongfunction(){
for(int i=0;i<1000000000;i++){
doSomething();
qApp->processEvents();
}
}

Krish
8th April 2008, 14:29
Thanks Wysota,
As i can't use qapp->processEvents(); because qapp is declared in main.cpp and am calling do_something(); from sample.cpp.
So as processEvents() is static i used it as: -


/////Sample.cpp//////
void sample::Do() // This is the slot which gets connected when user click Start pushbutton.
{
Start->setEnabled(FALSE);
sqr.do_something();// This is the function of outer class.
QCoreApplication::processEvents ();
}

Now below is the function implementation: -


/////Square.cpp/////
void Square::do_something()
{
for(int i=0;i<1000000000;i++){
...
....}
}


By this am getting the executable but i can't execute any other gui slot before execution doesn't return from Square.cpp. Please help.:)

Thanks again.

wysota
8th April 2008, 15:53
Thanks Wysota,
As i can't use qapp->processEvents(); because qapp is declared in main.cpp and am calling do_something(); from sample.cpp.
Yes you can, qApp is a global pointer to the application instance.





/////Sample.cpp//////
void sample::Do() // This is the slot which gets connected when user click Start pushbutton.
{
Start->setEnabled(FALSE);
sqr.do_something();// This is the function of outer class.
QCoreApplication::processEvents ();
}

Now below is the function implementation: -


/////Square.cpp/////
void Square::do_something()
{
for(int i=0;i<1000000000;i++){
...
....}
}

It won't work that way. processEvents() has to be called inside your do_something function inside the loop at each (well... not each as in every but as in sometimes) iteration.

There is no magic here. processEvents() performs a one time scan over pending events and processes them. You have to call it every time you want pending events to be processed.

Krish
8th April 2008, 17:35
Thanks Sir,

Yes you can, qApp is a global pointer to the application instance.
I have tried this i mean with qapp->processEvents(); but it showed me error that qapp is not declared in this scope.


It won't work that way. processEvents() has to be called inside your do_something function inside the loop at each (well... not each as in every but as in sometimes) iteration.
There is no magic here. processEvents() performs a one time scan over pending events and processes them. You have to call it every time you want pending events to be processed.

Thanks now i came to know what actually happens when this function gets called. It checks for any pending event during the execution in do_something(); so that if user clicks any button or does something it will also be executed as:-


Void Square::do_something()
{
for(i=o;i<100000000;i++) {
qapp->processEvents();
...
....}
}


But sir how can i use qapp created in main.cpp in the outer .cpp class? Those are separate files. I have only included its header in sample.cpp where all slots are implemented. qapp is not even detected in Sample.cpp, giving same error. Or do i have to include any file in Square.cpp?


////main.cpp////
#include <QApplication>
#include <QtGui>
#include "sample.h"

int main(int argc, char *argv[])
{
QApplication *qapp(argc, argv);
sample *dialog = new sample;
dialog->show();
qapp->connect( &app, SIGNAL( lastWindowClosed() ), &app, SLOT( quit() ) );
return app.exec();
}


Thanks again & sorry for disturbing you so much.

wysota
8th April 2008, 20:01
I have tried this i mean with qapp->processEvents(); but it showed me error that qapp is not declared in this scope.
You forgot to #include <QApplication>



Thanks now i came to know what actually happens when this function gets called. It checks for any pending event during the execution in do_something(); so that if user clicks any button or does something it will also be executed as:-


Void Square::do_something()
{
for(i=o;i<100000000;i++) {
qapp->processEvents();
...
....}
}

Correct.


But sir how can i use qapp created in main.cpp in the outer .cpp class? Those are separate files. I have only included its header in sample.cpp where all slots are implemented. qapp is not even detected in Sample.cpp, giving same error. Or do i have to include any file in Square.cpp?
As you already noticed processEvents is a static method, so you can use it anywhere you want, just include the class' headers.

Krish
9th April 2008, 13:16
Hey! Thanks Wysota sir its working now:)

Ok but i have other question/ doubt. As now i can execute all other slots even if execution is busy, can't i stop the busy execution if takes really long time say more than 10- 20 mins?

Or do i have to use QThreads in which i can in one thread keep GUI alive and in other thread call this busy function. And if it exceeds the waiting limit of user he can stop it with void QThread::terminate (); as we kill the QProcess with kill(); ?

Thanks again in advance.:)

wysota
9th April 2008, 13:49
If you want to have total control, you should use threads or implement your functionality based on events (divide whole process into smaller chunks, etc.).