Trolltech Home | Qt-interest Home | Recent Threads | All Threads | Author | Date
All threads index page 3

Qt-interest Archive, February 2003
destroy never called?


Message 1 in thread

I created a main window with Designer (Qt 3.1.1), and implementing my
code in the header file which pops up as soon as one double-clicks on
the widget being designed.

As mentioned in the automatically generated comment I implemented an
init() and a destroy() method. The init() method is just called fine,
but apparently the destroy() method is never called when I quit my
application. It looks like this:

// in MyApplicationWindow.ui.h:

void MyApplicationWindow::init() {
  qDebug ("This is okay.");
}

void MyApplicationWindow::destroy() {
  qDebug ("This is never called!");
}

What's wrong?

Cheers, Oliver
-- 
 [ signature omitted ] 

Message 2 in thread

On piątek 07 luty 2003 11:41 am, Till Oliver Knoll wrote:
> I created a main window with Designer (Qt 3.1.1), and implementing my
> code in the header file which pops up as soon as one double-clicks on
> the widget being designed.
>
> As mentioned in the automatically generated comment I implemented an
> init() and a destroy() method. The init() method is just called fine,
> but apparently the destroy() method is never called when I quit my
> application. It looks like this:
>
> // in MyApplicationWindow.ui.h:
>
> void MyApplicationWindow::init() {
>   qDebug ("This is okay.");
> }
>
> void MyApplicationWindow::destroy() {
>   qDebug ("This is never called!");
> }
>
> What's wrong?

Apparently, you are never destroying the object in question. Or you didn't 
connect the signal to the slot correctly.

Try explicitly deleting the window object and see what happens.

Cheers, Kuba Ober


Message 3 in thread

Kuba Ober wrote:
> 
> On piątek 07 luty 2003 11:41 am, Till Oliver Knoll wrote:
> > ...
> >
> > // in MyApplicationWindow.ui.h:
> >
> > void MyApplicationWindow::init() {
> >   qDebug ("This is okay.");
> > }
> >
> > void MyApplicationWindow::destroy() {
> >   qDebug ("This is never called!");
> > }
> >
> > What's wrong?
> 
> Apparently, you are never destroying the object in question. Or you didn't
> connect the signal to the slot correctly.
> 
> Try explicitly deleting the window object and see what happens.

(Oh, I *did* get a response on that one :)

I receive a closeEvent in MyApplicationWindow when I close it (like in
File->Quit), and my Main.cpp looks like this:

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

  MyApplicationWindow *myApplicationWindow;
  QApplication myApplication (argc, argv);
	
  myApplicationWindow = new MyApplicationWindow();

  // make window visible
  myApplicationWindow->show();
	
  // connect signals: last window closed -> quit application
  lunchtimeApplication.connect (&lunchtimeApplication, SIGNAL
(lastWindowClosed()),
	                        &lunchtimeApplication, SLOT (quit()));
  return myApplication.exec();

}

Okay, so it's not me who calls 'delete myApplicationWindow', but I guess
as soon as the application quits, at some time it gets deleted (by Qt?
How?), latest when the OS cleans up everything after me... The above is
very much derived from the 'application' example in the Qt directory,
and I've never seen it implemented differently.

So where am I supposed to 'delete myApplicationWindow'? Is this really
the reason why my 'destroy' method is never called? (Now that I think of
it, yes....)

Cheers, Oliver


Message 4 in thread

> > > // in MyApplicationWindow.ui.h:
> > >
> > > void MyApplicationWindow::init() {
> > >   qDebug ("This is okay.");
> > > }
> > >
> > > void MyApplicationWindow::destroy() {
> > >   qDebug ("This is never called!");
> > > }
> > >
> > > What's wrong?
> >
> > Apparently, you are never destroying the object in question. Or you
> > didn't connect the signal to the slot correctly.
> >
> > Try explicitly deleting the window object and see what happens.
>
> (Oh, I *did* get a response on that one :)
>
> I receive a closeEvent in MyApplicationWindow when I close it (like in
> File->Quit), and my Main.cpp looks like this:
>
> int main (int argc, char **argv) {
>
>   MyApplicationWindow *myApplicationWindow;
>   QApplication myApplication (argc, argv);
>
>   myApplicationWindow = new MyApplicationWindow();
>
>   // make window visible
>   myApplicationWindow->show();
>
>   // connect signals: last window closed -> quit application
>   lunchtimeApplication.connect (&lunchtimeApplication, SIGNAL
> (lastWindowClosed()),
> 	                        &lunchtimeApplication, SLOT (quit()));
>   return myApplication.exec();
>
> }
>
> Okay, so it's not me who calls 'delete myApplicationWindow', but I guess
> as soon as the application quits, at some time it gets deleted (by Qt?
> How?), latest when the OS cleans up everything after me... 

The OS doesn't clean up. It discards your process's allocated memory, that's 
all. When your process is done, it's done -- the OS doesn't magically execute 
any code that wasn't explicitly invoked by either you, or the libraries 
you're using.

You're receiving the closeEvent, and that's fine -- your window is closed. But 
nobody will destroy it for you, unless you tell somebody to ;-)

> The above is
> very much derived from the 'application' example in the Qt directory,
> and I've never seen it implemented differently.
>
> So where am I supposed to 'delete myApplicationWindow'? Is this really
> the reason why my 'destroy' method is never called? (Now that I think of
> it, yes....)

Nobody is deleting your object, it seems. Really. Nothing happens 
automatically unless you're sure of it and know why. The reason that your 
object is not deleted is that you didn't tell anything to take its ownership. 
So, you own the object, and it's your task to delete it.

Change this

return myApplication.exec();

to that

int rc;
rc =  myApplication.exec();
delete myApplicationWindow;
return rc;

Even better, let the deletion be done for you automatically by setting the 
WDestructiveClose widget flag in your widget's constructor. That will do what 
it says: closing of the widget will destroy it.

That's what I make of it.

Cheers, Kuba Ober


Message 5 in thread

On Thursday 13 February 2003 19:20, Kuba Ober wrote:

Somewhat easier:
main(...){
	MyApplication app;
	MyMainWnd mWnd;
	mWnd.show();
	app->setMainWidget(&mWnd);
	return app->exec();
}
Widget's destructor will be invoked now.



> > > > // in MyApplicationWindow.ui.h:
> > > >
> > > > void MyApplicationWindow::init() {
> > > >   qDebug ("This is okay.");
> > > > }
> > > >
> > > > void MyApplicationWindow::destroy() {
> > > >   qDebug ("This is never called!");
> > > > }
> > > >
> > > > What's wrong?
> > >
> > > Apparently, you are never destroying the object in question. Or you
> > > didn't connect the signal to the slot correctly.
> > >
> > > Try explicitly deleting the window object and see what happens.
> >
> > (Oh, I *did* get a response on that one :)
> >
> > I receive a closeEvent in MyApplicationWindow when I close it (like in
> > File->Quit), and my Main.cpp looks like this:
> >
> > int main (int argc, char **argv) {
> >
> >   MyApplicationWindow *myApplicationWindow;
> >   QApplication myApplication (argc, argv);
> >
> >   myApplicationWindow = new MyApplicationWindow();
> >
> >   // make window visible
> >   myApplicationWindow->show();
> >
> >   // connect signals: last window closed -> quit application
> >   lunchtimeApplication.connect (&lunchtimeApplication, SIGNAL
> > (lastWindowClosed()),
> > 	                        &lunchtimeApplication, SLOT (quit()));
> >   return myApplication.exec();
> >
> > }
> >
> > Okay, so it's not me who calls 'delete myApplicationWindow', but I guess
> > as soon as the application quits, at some time it gets deleted (by Qt?
> > How?), latest when the OS cleans up everything after me...
>
> The OS doesn't clean up. It discards your process's allocated memory,
> that's all. When your process is done, it's done -- the OS doesn't
> magically execute any code that wasn't explicitly invoked by either you, or
> the libraries you're using.
>
> You're receiving the closeEvent, and that's fine -- your window is closed.
> But nobody will destroy it for you, unless you tell somebody to ;-)
>
> > The above is
> > very much derived from the 'application' example in the Qt directory,
> > and I've never seen it implemented differently.
> >
> > So where am I supposed to 'delete myApplicationWindow'? Is this really
> > the reason why my 'destroy' method is never called? (Now that I think of
> > it, yes....)
>
> Nobody is deleting your object, it seems. Really. Nothing happens
> automatically unless you're sure of it and know why. The reason that your
> object is not deleted is that you didn't tell anything to take its
> ownership. So, you own the object, and it's your task to delete it.
>
> Change this
>
> return myApplication.exec();
>
> to that
>
> int rc;
> rc =  myApplication.exec();
> delete myApplicationWindow;
> return rc;
>
> Even better, let the deletion be done for you automatically by setting the
> WDestructiveClose widget flag in your widget's constructor. That will do
> what it says: closing of the widget will destroy it.
>
> That's what I make of it.
>
> Cheers, Kuba Ober
>
> --
> List archive and information: http://lists.trolltech.com/qt-interest/


Message 6 in thread

On piątek 14 luty 2003 04:19 am, you wrote:
> On Thursday 13 February 2003 19:20, Kuba Ober wrote:
>
> Somewhat easier:
> main(...){
> 	MyApplication app;
> 	MyMainWnd mWnd;
> 	mWnd.show();
> 	app->setMainWidget(&mWnd);
> 	return app->exec();
> }
> Widget's destructor will be invoked now.

And I should point out perhaps, that that's solely because your widget is an 
automatic variable now, rather than one allocated on the heap.

The compiler invokes the destructor just before the function actually returns.

The setMainWidget() thing has nothing to do with it, IIRC. Its only function 
is to make the application quit when the widget gets closed, that's all.

Cheers, Kuba Ober


Message 7 in thread

Hi,

you should pass the 'WDestructiveClose' widget flag in the constructor of 
your window. Otherwise it will not be deleted when it is closed, thus the 
destructor is not called (at least not by Qt).

It will of course be deleted during cleanup, but I suppose that then the 
output channel has already been closed, so you'll not see the debug 
message.

Check out the little test application below. The destructor message won't 
appear there either until you explicitly delete the object.

Bye,
Bernd


#include <qobject.h>

class Test
{
public:
    Test() { qDebug("Constructor"); }
    ~Test() { qDebug("Destructor"); }
};

int main()
{
    Test *test = new Test;
    //delete test;
}


On Thursday 13 February 2003 17:07, Till Oliver Knoll wrote:
> I receive a closeEvent in MyApplicationWindow when I close it (like in
> File->Quit), and my Main.cpp looks like this:
>
> int main (int argc, char **argv) {
>
>   MyApplicationWindow *myApplicationWindow;
>   QApplication myApplication (argc, argv);
>
>   myApplicationWindow = new MyApplicationWindow();
>
>   // make window visible
>   myApplicationWindow->show();
>
>   // connect signals: last window closed -> quit application
>   lunchtimeApplication.connect (&lunchtimeApplication, SIGNAL
> (lastWindowClosed()),
> 	                        &lunchtimeApplication, SLOT (quit()));
>   return myApplication.exec();
>
> }
>
> Okay, so it's not me who calls 'delete myApplicationWindow', but I guess
> as soon as the application quits, at some time it gets deleted (by Qt?
> How?), latest when the OS cleans up everything after me... The above is
> very much derived from the 'application' example in the Qt directory,
> and I've never seen it implemented differently.
>
> So where am I supposed to 'delete myApplicationWindow'? Is this really
> the reason why my 'destroy' method is never called? (Now that I think of
> it, yes....)


Message 8 in thread

From: Till Oliver Knoll [mailto:oliver.knoll@autoform.ch]
> Kuba Ober wrote:
> > On pi±tek 07 luty 2003 11:41 am, Till Oliver Knoll wrote:
> > > // in MyApplicationWindow.ui.h:
> > >
> > > void MyApplicationWindow::init() {
> > >   qDebug ("This is okay.");
> > > }
> > >
> > > void MyApplicationWindow::destroy() {
> > >   qDebug ("This is never called!");
> > > }
> > >
> > > What's wrong?
> > (...)
> (...)
> int main (int argc, char **argv) {
> 
>     MyApplicationWindow *myApplicationWindow;
>     QApplication myApplication (argc, argv);
>	
>     myApplicationWindow = new MyApplicationWindow();
>
>     // make window visible
>     myApplicationWindow->show();
>	
>     // connect signals: last window closed -> quit application
>     lunchtimeApplication.connect (&lunchtimeApplication,
>         SIGNAL (lastWindowClosed()),
>         &lunchtimeApplication, SLOT (quit()));
>     return myApplication.exec();
> }

Three hints:
- you may use
      myApplication.setMainWidget (myApplicationWindow)
  to set the application's main widget
- you may set the
      Qt::WDestructiveClose
  widget flag to your main window
- you may delete it "by hand" after the application returns from exec

I am not sure about the last one. However, I do not think the C++ runtime does a graceful destruction of memory leaks (and nothing else we are talking about). Where should it know the type from (it is not necessarily a class that has RTTI)? On application exit, the used memory is simply given back to the operating system as is. No cleanup, no destructors.


Message 9 in thread

Rainer Wiesenfarth wrote:

> > > > void MyApplicationWindow::destroy() {
> > > >   qDebug ("This is never called!");
> > > > }

> > int main (int argc, char **argv) {
> >
> >     MyApplicationWindow *myApplicationWindow;
> >     QApplication myApplication (argc, argv);
> >
> >     myApplicationWindow = new MyApplicationWindow();
> >
> >     // make window visible
> >     myApplicationWindow->show();
> >
> >     // connect signals: last window closed -> quit application
> >     lunchtimeApplication.connect (&lunchtimeApplication,
> >         SIGNAL (lastWindowClosed()),
> >         &lunchtimeApplication, SLOT (quit()));
> >     return myApplication.exec();
> > }
> 
> Three hints:
> - you may use
>       myApplication.setMainWidget (myApplicationWindow)
>   to set the application's main widget

This only saves me from connecting the signal lastWindowClosed to quit
(From Qt docs: "You need not have a main widget; connecting
lastWindowClosed() to quit() is an alternative."). It does *not* delete
the myApplicationWindow on quit(), my destroy() method is *not* called!
And the Qt docs don't say anything that myApplicationWindow is
re-parented or deleted, either.


> - you may set the
>       Qt::WDestructiveClose
>   widget flag to your main window

This one works, as expected.

> - you may delete it "by hand" after the application returns from exec
> 
> I am not sure about the last one. 

Didn't try it, but should work, too (if the Qt::WDestructiveClose is
*not* set, off course).

> However, I do not think the C++ runtime does a graceful destruction of memory leaks (and nothing else we are talking about). Where should it know the type from (it is not necessarily a class that has RTTI)? On application exit, the used memory is simply given back to the operating system as is. No cleanup, no destructors.

Right.

And regarding the confusion about destroy() or destroy (bool, bool),
I've overwritten destroy() as indicated in the automatically generated
Qt comment (in the *.ui.h) and it works. Everythings fine for me now :)

Cheers, Oliver

-- 
 [ signature omitted ]