PDA

View Full Version : commitData doesn't seem to be called...



tone
8th September 2008, 17:33
Hello everyone.
This is my first post here and I'm fairly new to C++ and Qt programming.
Here's my problem.
I'm working on an application written in Qt4.4.0 in MS windows.
The application allows only one instance and uses a file that, if present, means an instance is running. So, I create this file on application startup and delete it on application exit.
This works fine when the program ends by user interaction but it's not working when I close a windows session, or by a windows shutdown.

I made a simple testcase to illustrate my problem, so that any willing soul can give it a shot and point me some sort of error that I'm making here....

This is main.cpp

#include <QDebug>
#include "Application.h"

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

return myApp.exec();
}

and here's my app class, subclassed from QApplication, so that I could reimplement commitData():
Application.h:
#ifndef __APPLICATION_H__
#define __APPLICATION_H__
#include <QFile>
#include <QApplication>
#include <QSessionManager>

class Application: public QApplication {
Q_OBJECT
private:
QFile lockFile;
public:
Application( int argc , char *argv[] );
void commitData( QSessionManager &manager);

public slots:
void bailout(QSessionManager &manager);
};

#endif // __APPLICATION_H__

and Application.cpp:

#include <QDebug>
#include <QApplication>
#include <QSessionManager>
#include "Application.h"

Application::Application( int argc , char *argv[] ): QApplication( argc , argv ) {
lockFile.setFileName( QString( "%1/instance.lock" ).arg( qApp->applicationDirPath() ) );
lockFile.open(QIODevice::WriteOnly);

connect(
this , SIGNAL(commitDataRequest(QSessionManager&))
, this , SLOT(bailout(QSessionManager&))
, Qt::DirectConnection
);
}

void Application::commitData(QSessionManager& manager) {
qDebug() << "Commiting data :-)";
lockFile.close();
lockFile.remove();
manager.release();
}

void Application::bailout(QSessionManager &manager) {
qDebug() << "I'm bailing out!";
manager.release();
}

This is the project file, in case it's usefull...

TEMPLATE = app
SOURCES += main.cpp Application.cpp
CONFIG += console warn_on
HEADERS += Application.h

I'm using Qt 4.4.0 on windows with Mingw gcc 3.4.5
Altough I (think that I) reimplemented commitData() as mentioned in the docs, it seems to never be called.
I launched the program in a cmd.exe terminal, and also from the explorer shell, then I close my session, I see the application finishes ( terminal returns to prompt ), but no messages are printed, and the lock file isn't deleted at all. Tested with closeing session and with windows shutdown.

What am I doing wrong here? I suppose it must be some silly mistake, but I'm not experienced enough to detect it. Is commitData() actually reimplemented correctly, or is it not being called at all??

Any help would be very, very apreciated at this point... :crying:

cheers,
--to

lyuts
8th September 2008, 21:17
your commitData is just a regular public function but not a signal. And that your connect doesn't do what you think, because in that connect you treat commitData as a signal when it is not.

Before moving further we need to know, when do you want commitData to be called?

tone
8th September 2008, 21:36
Well.. yes... nothing does what I think it does...
From what I read, commitData() is invoqued when the session is closingn and the application needs to save some stuff, ( eg: save an open file in an editor).

These are the docs from which I've been basing on:
http://doc.trolltech.com/4.4/qapplication.html#commitData
http://doc.trolltech.com/4.4/session.html (see "Getting Session Management to Work with Qt" )

I didn't read anywhere that it needs to be a slot, all I read is that it can be reimplemented to handle the graceful logout or even abort it.

I want my application to detect when it's about to close due to a logout, clean it's internal state normally (without killing timers and thread by brute force) and remove the lock file so that I don't detect a false instance of the application when it starts the next time.

cheers,
--to

NB: I could just handle the application instance using a lock on the file, and checking if I can create/open it to decide if some other instance is using it. But, since this session management thing is documented this way, it seems a more reasonable solution, and I need it to shut down my app gracefully without simply exploding its internals.

tone
8th September 2008, 21:56
your commitData is just a regular public function but not a signal. And that your connect doesn't do what you think, because in that connect you treat commitData as a signal when it is not.

Please have a second look... What I am connecting is the commitDataRequest() *signal*, which is emmited when a logout hapens, according to the docs. This code compiles and executes, and the runtime doesn't throw any complaints about non-existant signals and/or slots...

This signal is inherited from QApplication.
the commitData() [virtual] method is also inherited, but I'm reimplementing it (or trying to) to catch the logout process and do some more internal work before bailing out. It has, however a default implementation, and I wonder if I'm not correctly (or at all) overriding this default implementation with the one I'm providing in my class...

commitData is a virtual method from QApplication, whose default implementation sends close events to all open windows of the application and lets the logout process continue if all windows accept the event.
Maybe I'm just mis-interpretating the docs, I don't know,and because I'm new to Qt, this might be all wrong...

cheers,
--to

lyuts
8th September 2008, 22:01
Yep, that's my fault, i thought you were connecting commitData. One of another solutions is to implement a slot which will commit your data, and connect it to commitDataRequest.

lyuts
8th September 2008, 22:05
Try adding
CONFIG += console warn_on debug
to pro file and run again your first version. What is the output?

tone
9th September 2008, 00:11
One of another solutions is to implement a slot which will commit your data, and connect it to commitDataRequest.
That slot is bailout(...). The connection is made but bailout seems not to be called as well :(


Try adding
CONFIG += console warn_on debug
to pro file and run again your first version. What is the output?
I'll try it out tomorrow. It's late here, and I'm not near the machine where I'm trying this stuff...

Does anyone have experience handling the session logout in Qt under Windows XP/Vista? Looking at the docs this seems to be a fairly trivial matter, but I can't get my code to work. Surely there must be some silly mistake that I need to find...

cheers,
--to

tone
10th September 2008, 15:42
Ok, I found the silly mistake...actually, someone pointed it to me.
The problem is the 'console' keyword in the CONFIG variable of the project file. It causes the session management mechanism to work in some diferent way, or not to work at all.
Removing the 'console' option, everything orks just fine. The code that I used to test it is already diferent from the one posted here, but I think this one will work equally just fine.

cheers,
--to