Qt-interest Archive, January 2007
[ Qt4.2.2 ] Error logging halts at application close
Message 1 in thread
Hi all,
I quit an application in response to user selection from the file menu; file,
quit. This makes signal/slot calls from a QAction as follows:
connect(quitAct, SIGNAL( triggered() ), qApp, SLOT( quit() );
This appears to work fine - the application quits.
I have a bunch of "qDebug() << "some text here" " statements in the code and
these print to console happily during test runs. I include some of these in
a virtual destructor in a base class. The base class deletes a model & a
view; the derived class adds some table specific detail to the base class
(how to add records etc. - this varies across tables, other stuff, such as
remove row, does not) but does nothing in the destructor except write to
qDebug() << and spit out a signal (see below).
I also have an error logging system intended for deployment with the final
application. This uses a signal (e.g. logEvent(const QString &) to send
messages through a relay which is connected to a logger object which writes
to file. This also works. For example, I've confirmed that the relay
connects to the logger and that the item being destroyed is connecting to the
relay.
I am a little troubled because I see no evidence of my expected log entries
at object destruction. Does qApp / quit() perform a rather rude shut down
which cuts across both "emit" and "qDebug() <<" or should I be looking for
something horribly wrong somewhere? If so some reason the destructors are not
getting called any tips on tracking would be welcome. Or is it a buffering
issue. Bit stumped :-(
Regards,
Amit
--
[ signature omitted ]
Message 2 in thread
> -----Original Message-----
> From: amit [mailto:pom2@xxxxxxxxxxxxxxxx]
> Sent: Wednesday, January 03, 2007 11:31 PM
> To: qt-interest@xxxxxxxxxxxxx
> Subject: [ Qt4.2.2 ] Error logging halts at application close
>
> Hi all,
>
> I quit an application in response to user selection from the file menu;
> file,
> quit. This makes signal/slot calls from a QAction as follows:
>
> connect(quitAct, SIGNAL( triggered() ), qApp, SLOT( quit() );
>
> This appears to work fine - the application quits.
>
> I have a bunch of "qDebug() << "some text here" " statements in the code
> and
> these print to console happily during test runs. I include some of these
> in
> a virtual destructor in a base class. The base class deletes a model & a
> view; the derived class adds some table specific detail to the base class
> (how to add records etc. - this varies across tables, other stuff, such as
> remove row, does not) but does nothing in the destructor except write to
> qDebug() << and spit out a signal (see below).
>
> I also have an error logging system intended for deployment with the final
> application. This uses a signal (e.g. logEvent(const QString &) to send
> messages through a relay which is connected to a logger object which
> writes
> to file. This also works. For example, I've confirmed that the relay
> connects to the logger and that the item being destroyed is connecting to
> the
> relay.
>
> I am a little troubled because I see no evidence of my expected log
> entries
> at object destruction. Does qApp / quit() perform a rather rude shut
> down
> which cuts across both "emit" and "qDebug() <<" or should I be looking
> for
> something horribly wrong somewhere? If so some reason the destructors are
> not
> getting called any tips on tracking would be welcome. Or is it a
> buffering
> issue. Bit stumped :-(
>
> Regards,
>
> Amit
A couple of things could be going on. Make sure that your "base class" parent is the app, or something that eventually is owned by the app. Otherwise, the parent-child QT destructor chain will never get started.
If the base class is static, you run the risk of it being deleted after the qApp and of course you would never know.
Also, but a stop point in your debugger, just to make sure the destructor is getting called.
Scott
--
[ signature omitted ]
Message 3 in thread
On Thursday 04 January 2007 07:48, Scott Aron Bloom wrote:
Scott,
thanks for the reply.
>
> If the base class is static, you run the risk of it being deleted after the
> qApp and of course you would never know.
>
I think I get the timing point here but can you really have an entire class
static and inherit from it? Static members I get (hopefully) but this I've
not seen before; or if I have I was asleep :-) .
A
--
[ signature omitted ]
Message 4 in thread
> Scott,
>
> thanks for the reply.
>
> >
> > If the base class is static, you run the risk of it being deleted
after
> the
> > qApp and of course you would never know.
> >
> I think I get the timing point here but can you really have an entire
> class
> static and inherit from it? Static members I get (hopefully) but this
I've
> not seen before; or if I have I was asleep :-) .
>
> A
You DON'T want it to be static. You want it to be on the heap. This
way you can control its lifespan completely.
Just create it after the QApplication, and make the qapp the parent. I
think you will see the desired results then.
Scott
--
[ signature omitted ]
Message 5 in thread
On Thursday 04 January 2007 08:48, Scott Aron Bloom wrote:
>
> You DON'T want it to be static. You want it to be on the heap. This
> way you can control its lifespan completely.
>
> Just create it after the QApplication, and make the qapp the parent. I
> think you will see the desired results then.
>
Scott,
thanks very much - think I've got it sorted now.
I had rather blindly been creating mainwindow on the heap using "new" and
mainwindow *. When digesting your reply I couldn't see an obvious way of
associating the mainwindow with the QApplication. The parental chain seemed
to need a QWidget * and the QApp is not a QWidget.
In the end I went for the following:
1) Create mainwindow on the stack without the new / *
2) Re-wire some slots to point to mainwindow.close() instead of qApp->quit()
(which makes each of my exit routes point to the same place now - before I
had two routes)
3) Ensure destructors released any resources upstream of the base class e.g.
if( addressTable ){
delete addressTable;
addressTable = 0;
}
Seems to work just fine now. Thanks again.
A
--
[ signature omitted ]
Message 6 in thread
amit wrote:
> Hi all,
>
> I quit an application in response to user selection from the file menu; file,
> quit. This makes signal/slot calls from a QAction as follows:
>
> connect(quitAct, SIGNAL( triggered() ), qApp, SLOT( quit() );
>
> This appears to work fine - the application quits.
>
> I have a bunch of "qDebug() << "some text here" " statements in the code and
> these print to console happily during test runs. I include some of these in
> a virtual destructor in a base class. The base class deletes a model & a
> view; the derived class adds some table specific detail to the base class
> (how to add records etc. - this varies across tables, other stuff, such as
> remove row, does not) but does nothing in the destructor except write to
> qDebug() << and spit out a signal (see below).
>
> I also have an error logging system intended for deployment with the final
> application. This uses a signal (e.g. logEvent(const QString &) to send
> messages through a relay which is connected to a logger object which writes
> to file. This also works. For example, I've confirmed that the relay
> connects to the logger and that the item being destroyed is connecting to the
> relay.
>
> I am a little troubled because I see no evidence of my expected log entries
> at object destruction. Does qApp / quit() perform a rather rude shut down
> which cuts across both "emit" and "qDebug() <<" or should I be looking for
> something horribly wrong somewhere? If so some reason the destructors are not
> getting called any tips on tracking would be welcome. Or is it a buffering
> issue. Bit stumped :-(
>
> Regards,
>
> Amit
Hi,
Static variables are created in a random order, but their destruction is
in the inverse order of their creation. So if at some point you create a
static object - efore the main - that need your logger and instanciates
it, the logger will be destroyed before the static object.
This topic is completly discussed in Alexandrescu's book "Modern C++
Design: Generic Programming and Design Patterns Applied".
I don't know if this can help you because I do not know your exact
software application ;)
Matthieu
--
[ signature omitted ]
Message 7 in thread
On Thursday 04 January 2007 09:14, Matthieu Brucher wrote:
Matthieu
thank you for the reference - I may well add that book to my library. I've
been looking at An Introduction to Qt4 with Design Patterns recently and have
been finding that a very useful book. Previously I thought Design Patterns
sounded a bit too specialised for me, but I'm now quite sure they are
exceedingly useful and worth studying.
For anyone looking for a worth while book, I would recommend the book
mentioned above; authors are Erzust & Erzust, if I recall correctly.
Regards,
Amit
> Hi,
>
> Static variables are created in a random order, but their destruction is
> in the inverse order of their creation. So if at some point you create a
> static object - efore the main - that need your logger and instanciates
> it, the logger will be destroyed before the static object.
> This topic is completly discussed in Alexandrescu's book "Modern C++
> Design: Generic Programming and Design Patterns Applied".
> I don't know if this can help you because I do not know your exact
> software application ;)
>
> Matthieu
>
> --
> To unsubscribe - send a mail to qt-interest-request@xxxxxxxxxxxxx with
> "unsubscribe" in the subject or the body. List archive and information:
> http://lists.trolltech.com/qt-interest/
--
[ signature omitted ]
Message 8 in thread
> Static variables are created in a random order, but their destruction is
> in the inverse order of their creation. So if at some point you create a
> static object - efore the main - that need your logger and instanciates
> it, the logger will be destroyed before the static object.
> This topic is completly discussed in Alexandrescu's book "Modern C++
> Design: Generic Programming and Design Patterns Applied".
> I don't know if this can help you because I do not know your exact
> software application ;)
Static variables are not created in random order -
static variables in the SAME file are allocated/initialized in the
order that they appear in the source file.
The order of initialization of static variables in different source
files is dependent on the order that the linker loads the source code
modules.
Static local variables (to a function) are initialized the first time
the function is executed.
--Alan
--
[ signature omitted ]