PDA

View Full Version : Can't create an object : initialisation problem ?



Nyphel
8th March 2007, 16:32
Hello,

My application is composed of an "Icone" (Personal class that setup a QSystemTrayIcon with a QMenu).

This Icone creates a "Veilleur" object (Personal class that simulate a service in order to administrate a client side connection to a server).

So the "Veilleur" creates a "MailChecker" (Personal class that checks for new mails on a server).

At the end, the "MailChecker" use a QTcpSocket to connect to the server.

The problem is that today I need to developp the "Veilleur" class, and a strange thing as appeared : I can't add anything !
For example, if I want to add a QAction (private or public) the application will fall down.
The application as no problem to pass the builder : no errors, no warning... Nothing.
But when I launch it, I get a Windows error box saying me that the application as encoutered an error and must be closed...

I can't understand the problem, so I put here my code... As reduced as possible :).

main.cpp

#include <QApplication>
#include <QtGui>

#include "Icone.h"

int main(int argc, char *argv[])
{
QApplication app(argc, argv);
Icone mon_icone;
return app.exec();
}




Icone.h

#ifndef ICONE_H
#define ICONE_H

#include "Veilleur.h"

#include <iostream>
#include <QSystemTrayIcon>
#include <QWidget>

class QAction;
class QMenu;

class Icone : public QWidget
{
Q_OBJECT

public:
Icone();

protected:
[...]

private slots:
[...]

private:
// QActions and QMenus
// [...]

QSystemTrayIcon *trayIcon;

Veilleur mon_veilleur;
};

#endif





Icone.cpp

#include <QtGui>

#include "Icone.h"

Icone::Icone()
{
Creer_actions(); // Initialise the QActions
Creer_menu(); // Initialise the QMenus
Creer_TrayIcon(); // Initialise the trayicon and bind it the QMenus
}





Veilleur.h

#ifndef Veilleur_h
#define Veilleur_h

#include "MailChecker.h"

#include <QTextStream>
#include <QObject>
#include <QTimer>

// Added in order to try to add a QAction
#include <iostream>
#include <QWidget>
class QAction;
class QMenu;

class Veilleur : public QObject
{
Q_OBJECT

public:
Veilleur();
[...]

private slots:
[...]

private:
MailChecker mChecker;
//MailChecker mCheckersecond; // Crash the application if uncommented
//QAction *Act_Tic; // Crash the application if uncommented
//QAction *Act_Ticlol; // Crash the application if uncommented
};
#endif






Veilleur.cpp

#include <iostream>
#include <QApplication>

#include "Veilleur.h"

Veilleur::Veilleur() : QObject()
{
}




MailChecker.h

#ifndef MailChecker_h
#define MailChecker_h

#include <QThread>
#include <QTextStream>
#include <QSettings>
#include <QObject>
#include <QTcpSocket>

class QTcpSocket;

class MailChecker : public QObject
{
Q_OBJECT

public:
MailChecker();
[...]

private slots:
void afficher_erreur_socket(QAbstractSocket::SocketErro r socketError);

private:
[...]

QTcpSocket *socket_r;
};

#endif





MailChecker.cpp

#include <iostream>

#include <QApplication>
#include <QHostAddress>
#include <QTcpSocket>
#include <QStringList>

#include "MailChecker.h"


MailChecker::MailChecker() : QObject()
{
connect(socket_r, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(afficher_erreur_socket(QAbstractSocket::Socke tError)));
}

void MailChecker::afficher_erreur_socket(QAbstractSocke t::SocketError socketError)
{
switch (socketError)
{
case QAbstractSocket::RemoteHostClosedError:
break;
case QAbstractSocket::HostNotFoundError:
std::cout << "\n ERREUR SOCKET : Host not found" << std::endl;
break;
case QAbstractSocket::ConnectionRefusedError:
std::cout << "\n ERREUR SOCKET : Connection refused by peer" << std::endl;
break;
default:
std::cout << "\n ERREUR SOCKET : \n" << socket_r->errorString().toStdString() << std::endl;
}
}




I'm sure I made my nOOb another time... But I'm a nOOb :crying:.
I can't understand what's the problem,
I can't understand why the application crashes if I add an object,
I can't understand why the application has been compile and built but crashes... :(

I think it's a class initialisation problem, but I can't see what.

Perhaps coul you help me ?
Thanks :)

patrik08
8th March 2007, 16:40
Hello,
Perhaps coul you help me ?
Thanks :)

Your problem is

Have a look on line 1386
http://qt-webdav.svn.sourceforge.net/viewvc/qt-webdav/webdavdir/dav_main.cpp?view=markup
delete mTray; && line 164 void Dav_Main::setupTray() the construct of QSystemTrayIcon

if you QSystemTrayIcon is not clean qt freeze an crasch .... at end delete QSystemTrayIcon
otherwise you become many many icons on task ... running on linux && window...

Nyphel
8th March 2007, 16:47
Thanks patrik08, I think that was an error, but it doesn't resolve my problem :(.

It seems that the "Veilleur" class is the only one in wich I can't add objects.

Nyphel
11th March 2007, 12:34
Small UP, I don't find the solution...
So perhaps someone may find it :)

jpn
11th March 2007, 12:51
A good practice is to allocate objects derived from QObject on the heap (with operator "new"). QObjects allocated on the stack in together with a parent-child relationship tend to cause problems (*). I suggest diving into docs; QObject, Object Trees and Object Ownership (http://doc.trolltech.com/4.2/objecttrees.html)..

I'm not sure if this is the problem of yours because I can't see any parent being passed for any object in the example piece of code.. But QObject parent-child relationship (http://www.phptr.com/articles/article.asp?p=667415&seqNum=1&rl=1) sure is a concept a developer must understand while developing with Qt. :)

(*) A QObject deletes all it's children. A child gets destructed twice in case it was allocated on the stack, 1) by the parent 2) when going out of scope => crash.

Nyphel
12th March 2007, 10:07
Hello,

Someone esle gave me the solution on another forum.
My error was to use the QTcpSocket in the constructor of MailChecker while it wasn't initialised :


MailChecker::MailChecker() : QObject()
{
connect(socket_r, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(afficher_erreur_socket(QAbstractSocket::Socke tError)));
}

The good code is :


MailChecker::MailChecker() : QObject()
{
socket_r = new QTcpSocket();

connect(socket_r, SIGNAL(error(QAbstractSocket::SocketError)), this, SLOT(afficher_erreur_socket(QAbstractSocket::Socke tError)));
}

Is was initialising my Socket directly in a function that :
- initialise the socket
- connect to host
- submit a request
- listen the answer
- close the socket
- destroy the socket

Thanks Dudule from developpez.net C++ forums ;)



PS : Thanks jpn, your answer is usefull for me, because I didn't know that :)