PDA

View Full Version : Closing program when widget is closed.



metdos
29th July 2009, 06:50
I have a program which instantiates and uses another class (subclass of Qwidget) . When I closed the widget, program does not terminate, how can I also terminate main function?

yogeshgokul
29th July 2009, 06:55
how can I also terminate main function?

You never need to terminate main function.

metdos
29th July 2009, 07:00
In main program, I have a infinite loop, and I need to stop infinite loop when widget is closed by user.

wagmare
29th July 2009, 07:02
I have a program which instantiates and uses another class (subclass of Qwidget) . When I closed the widget, program does not terminate, how can I also terminate main function?


means u want to terminate the whole application ...
use qApp->quit();

metdos
29th July 2009, 07:09
But, how will understand that widget is closed? I put qApp->quit(); to destructor of QT class, but it didn't work.

spirit
29th July 2009, 07:12
usually this line


...
QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );
...

is added in main.cpp or you can use QApplication::setQuitOnLastWindowClosed

metdos
29th July 2009, 07:25
Should I rewrite quit() slot?

spirit
29th July 2009, 07:29
why? take a look at QCoreApplication::quit, moreover, you can't do this since this method is not virtual. :)

wagmare
29th July 2009, 07:29
no just use the connect spirit suggest you ..

quit() is a static slot
void QCoreApplication::quit () [static slot]

nish
29th July 2009, 07:29
no need of rewrite.. its like u want to rewrite exit(0) :)

metdos
29th July 2009, 07:31
Then I guess I should try another thing, because it does not work, after widget is closed, my program keeps working.

spirit
29th July 2009, 07:34
so, provide a compilable example which reproduces the problem to us.

metdos
29th July 2009, 07:44
here main function and function which contains infinite loop




int main(int argc, char *argv[])
{

//GUI part
QApplication a(argc, argv);
rovkonInterface w; //subclass of Qwidget
w.show();

QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );

userInterface=&w;

// start the receive thread
ReceiveThread();

return a.exec();

}

void ReceiveThread()
{

rovkonInterface *w=((rovkonInterface *)userInterface);
QApplication *a=((QApplication *)qtApplication);


while ( lMustQuit == 0 )
{
a->processEvents();

}


}

spirit
29th July 2009, 07:48
if you use another thread then tyr to add one more connection in main.cpp


...
QObject::connect( qApp, SIGNAL(lastWindowClosed()), thread, SLOT(quit()) );
QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );
...

spirit
29th July 2009, 07:50
btw, you can use qApp (http://doc.trolltech.com/4.5/qapplication.html#qApp) insted of this QApplication *a=((QApplication *)qtApplication);

metdos
29th July 2009, 08:14
Thanks for the "qApp" tip.

and sorry for the bad names I gave to functions. Actually there is no other thread, there is just a function with infinite loop and I added "a->processEvents();" in order to prevent freezing in widgets as you can see in code above.

Simply ReceiveThread() continues to run infinite loop when widget is closed, I need to stop this infinite loop.

Thanks anyway :)

wagmare
29th July 2009, 08:23
in rovkonInterface class
is it a QDialog or QWidget ..
if QDialog we can receive
void QDialog::rejected ()
with that rejected call we can quit our application like


QObject::connect( w, SIGNAL(rejected()), qApp, SLOT(quit()) );

metdos
29th July 2009, 08:26
It is Qwidget.


rovkonInterface w; //subclass of Qwidget



in rovkonInterface class
is it a QDialog or QWidget ..
if QDialog we can receive
void QDialog::rejected ()
with that rejected call we can quit our application like


QObject::connect( w, SIGNAL(rejected()), qApp, SLOT(quit()) );

wagmare
29th July 2009, 08:29
so u try emit your custom signal on rovkonInterface closeEvent()

reimplement closeEvent() in rovkonInterface() class
emit widgetClosed() // your custom signal
and

QObject::connect( w, SIGNAL(widgetClosed()), qApp, SLOT(quit()) );

spirit
29th July 2009, 08:32
so u try emit your custom signal on rovkonInterface closeEvent()

reimplement closeEvent() in rovkonInterface() class
emit widgetClosed() // your custom signal
and

QObject::connect( w, SIGNAL(widgetClosed()), qApp, SLOT(quit()) );

in that case you don't need to emit a signal, just call qApp->quit(); in closeEvent. :)

metdos
29th July 2009, 09:04
didn't work,

Even I don't understand how closing QT application will terminate main program.

As long as I understand, I using an instance of QT class, and when user closed the widget, this instance will gone, but how it can effect my other function with infinite loop. So if I can find a way which inform me that instance of Qt class is closed, I think that I can solve my problem.

spirit
29th July 2009, 09:12
there is such signal QObject::destroyed.

wagmare
29th July 2009, 09:22
didn't work,

Even I don't understand how closing QT application will terminate main program.

As long as I understand, I using an instance of QT class, and when user closed the widget, this instance will gone, but how it can effect my other function with infinite loop. So if I can find a way which inform me that instance of Qt class is closed, I think that I can solve my problem.

see every Qt application will have QApplication

from docs:
For any GUI application that uses Qt, there is precisely one QApplication object, no matter whether the application has 0, 1, 2 or more windows at any time.

so qApp->quit() will try to close that QApplication .. Tells the application to exit with return code 0 (success).

numbat
29th July 2009, 11:38
QCoreApplication::quit or QCoreApplication::exit simply stop event processing, so that a call to QCoreApplication::exec will return. In your app, you never get to exec because you are in an infinite loop. You are on the right track with your lMustQuit variable, but you never set it to true. One method would be to connect the lastWindowClosed signal to a custom function and set lMustQuit to be true. Fortunately, we can alternatively use QEventLoop which has a method QEventLoop::isRunning which tells us when exit or quit have been called. Here is a simple example:


#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QEventLoop>

void ReceiveThread();

int main(int argc, char *argv[])
{

//GUI part
QApplication a(argc, argv);
QWidget w; //subclass of Qwidget
w.show();

QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );

// start the receive thread
ReceiveThread();

/* We only get here after quit is called. */
return 0;

}

void ReceiveThread()
{
QEventLoop loop;

while (loop.isRunning()) /* Returns false after exit or quit have been called. */
{
loop.processEvents();
}
}

metdos
29th July 2009, 11:52
Yes, these are the magical lines I'm searching.


QEventLoop loop;
loop.isRunning()

and thanks, it helped very much.


QCoreApplication::quit or QCoreApplication::exit simply stop event processing, so that a call to QCoreApplication::exec will return. In your app, you never get to exec because you are in an infinite loop. You are on the right track with your lMustQuit variable, but you never set it to true. One method would be to connect the lastWindowClosed signal to a custom function and set lMustQuit to be true. Fortunately, we can alternatively use QEventLoop which has a method QEventLoop::isRunning which tells us when exit or quit have been called. Here is a simple example:


#include <QtGui/QApplication>
#include "mainwindow.h"
#include <QEventLoop>

void ReceiveThread();

int main(int argc, char *argv[])
{

//GUI part
QApplication a(argc, argv);
QWidget w; //subclass of Qwidget
w.show();

QObject::connect( qApp, SIGNAL(lastWindowClosed()), qApp, SLOT(quit()) );

// start the receive thread
ReceiveThread();

/* We only get here after quit is called. */
return 0;

}

void ReceiveThread()
{
QEventLoop loop;

while (loop.isRunning()) /* Returns false after exit or quit have been called. */
{
loop.processEvents();
}
}

metdos
30th July 2009, 09:10
Again me, yes it helped to stop program, but this time program does not enter infinite loop.
loop.isRunning() is returning false every time.


Yes, these are the magical lines I'm searching.


QEventLoop loop;
loop.isRunning()

and thanks, it helped very much.

wagmare
30th July 2009, 09:47
switch to threads ... QThread is the best option here .. no need for u to use
qApp->processEvents()

refer this documentation
http://doc.trolltech.com/qq/qq27-responsive-guis.html

metdos
30th July 2009, 13:14
Very good and neat article.


refer this documentation
http://doc.trolltech.com/qq/qq27-responsive-guis.html