Bonjour à tous,

J'ai un problème très ennuyeux avec Qt. J'avais l'habitude de passer par des appels statiques dans le syle des suivantes:
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
QString filename = QFileDialog::getOpenFileName(NULL, tr("Load a file"), ".", "*.*");
// ou
QMessageBox::information(this, tr("Error!"), error.what());
Malheureusement, avec ma nouvelle configuration, ces appels provoquent un SEGFAULT. Pour le QFileDialog, j'obtient avec GDB :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#0 0x7ffff57bc12f	??() (/lib/x86_64-linux-gnu/libc.so.6:??)
#1 0x7ffff4d1475c	XSetCommand() (/usr/lib/x86_64-linux-gnu/libX11.so.6:??)
#2 0x7ffff4d194bb	XSetWMProperties() (/usr/lib/x86_64-linux-gnu/libX11.so.6:??)
#3 0x7ffff70aeec5	QWidgetPrivate::create_sys(this=0x6d4f50, window=27263364, initializeWindow=true, destroyOldWindow=118) (kernel/qwidget_x11.cpp:799)
#4 0x7ffff70605e2	QWidget::create(this=0x7c5210, window=0, initializeWindow=true, destroyOldWindow=true) (kernel/qwidget.cpp:1467)
#5 0x7ffff706ae8a	QWidget::setVisible(this=0x7c5210, visible=<optimized out>) (kernel/qwidget.cpp:7596)
#6 0x7ffff74c66ec	QDialog::setVisible(this=0x7c5210, visible=<optimized out>) (dialogs/qdialog.cpp:739)
#7 0x7ffff74c5490	show(this=0x7c5210) (../../include/QtGui/../../src/gui/kernel/qwidget.h:487)
#8 (	QDialog::exec(this=<optimized out>) (dialogs/qdialog.cpp:543)
#9 0x408180	Interface::openFile() () (??:??)
#10 0x4088ef	Interface::loadPipeline() () (??:??)
#11 0x409b24	Interface::qt_metacall(QMetaObject::Call, int, void**) () (??:??)
#12 0x7ffff6aebb1a	QMetaObject::activate(sender=0x685f40, m=<optimized out>, local_signal_index=<optimized out>, argv=0x0) (kernel/qobject.cpp:3278)
#13 0x7ffff73c5f21	QAbstractButtonPrivate::emitReleased(this=<optimized out>) (widgets/qabstractbutton.cpp:574)
#14 0x7ffff73c712c	QAbstractButtonPrivate::click(this=0x779c90) (widgets/qabstractbutton.cpp:537)
#15 0x7ffff73c73ac	QAbstractButton::mouseReleaseEvent(this=0x685f40, e=0x7fffffffda20) (widgets/qabstractbutton.cpp:1121)
#16 0x7ffff7067016	QWidget::event(this=0x685f40, event=0x7fffffffda20) (kernel/qwidget.cpp:8259)
#17 0x7ffff70169f4	notify_helper(e=0x7fffffffda20, receiver=0x685f40, this=0x680c70) (kernel/qapplication.cpp:4467)
#18 (	QApplicationPrivate::notify_helper(this=0x680c70, receiver=0x685f40, e=0x7fffffffda20) (kernel/qapplication.cpp:4439)
#19 0x7ffff701c17b	QApplication::notify(this=<optimized out>, receiver=0x685f40, e=0x7fffffffda20) (kernel/qapplication.cpp:4028)
#20 0x7ffff6ad8fbc	QCoreApplication::notifyInternal(this=0x680c40, receiver=0x685f40, event=0x7fffffffda20) (kernel/qcoreapplication.cpp:731)
#21 0x7ffff70179c2	sendEvent(event=<optimized out>, receiver=<optimized out>) (../../include/QtCore/../../src/corelib/kernel/qcoreapplication.h:215)
#22 (	QApplicationPrivate::sendMouseEvent(receiver=0x685f40, event=0x7fffffffda20, alienWidget=0x0, nativeWidget=0x685f40, buttonDown=0x0, lastMouseReceiver=..., spontaneous=true) (kernel/qapplication.cpp:3127)
#23 0x7ffff7093de8	QETWidget::translateMouseEvent(this=0x685f40, event=<optimized out>) (kernel/qapplication_x11.cpp:4465)
#24 0x7ffff7092bea	QApplication::x11ProcessEvent(this=0x680c40, event=0x7fffffffe140) (kernel/qapplication_x11.cpp:3591)
#25 0x7ffff70bad32	x11EventSourceDispatch(s=0x685eb0, callback=0, user_data=0x0) (kernel/qguieventdispatcher_glib.cpp:146)
#26 0x7ffff45d50cf	g_main_context_dispatch() (/lib/x86_64-linux-gnu/libglib-2.0.so.0:??)
#27 0x7ffff45d58c8	??() (/lib/x86_64-linux-gnu/libglib-2.0.so.0:??)
#28 0x7ffff45d5a99	g_main_context_iteration() (/lib/x86_64-linux-gnu/libglib-2.0.so.0:??)
#29 0x7ffff6b03abf	QEventDispatcherGlib::processEvents(this=0x682210, flags=<optimized out>) (kernel/qeventdispatcher_glib.cpp:422)
La structure de l'application est assez simple : une classe Application dérivant de QApplication et possedant un pointeur vers une classe Interface dérivant de QWidget. Les appels sont réalisés depuis des fonctions "public slots" et appelés par un évènement (QPushButton::released()).

J'ai donc essayé sans les appels statiques avec le code suivant :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
QPointer<QFileDialog> dlg = new QFileDialog(this);
dlg->setFileMode(QFileDialog::ExistingFile);
dlg->setOption(QFileDialog::DontUseNativeDialog, true); //J'ai essayé ce drapeau avec les appels statiques sans plus de succès
dlg->selectNameFilter("*.ppl");
dlg->exec(); //ou dlg->show();
//exploitation...
delete dlg;
Et j'obtiens la même erreur... SAUF quand j'appelle cette fonction sans passer "par un évènement" mais en la lançant à la main directement à la fin du constructeur de Interface par exemple. En fait, tant que je n'ai pas appellé la fonction exec() de QApplication, tout va bien.

Je pense donc, très fortement pour une mauvaise configuration de mon système :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
uname -a
Linux *** 3.1.0-1-amd64 #1 Fri Dec 23 16:37:11 UTC x86_64 GNU/Linux
g++ -v
gcc version 4.6.2 (Debian 4.6.2-11)
make -v
GNU Make 3.81
qmake -v
QMake version 2.01a
Using Qt version 4.7.3 in /usr/lib
dbus-daemon --version
D-Bus Message Bus Daemon 1.2.24
Xorg -version
X.Org X Server 1.11.2.902 (1.11.3 RC 2)
Release Date: 2011-12-09
Le truc c'est que je n'utilise pas Gnome mais seulement un compositeur : Compiz-GTK...

Enfin, un code minimal pour reproduire l'erreur :
Interface.hpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
#ifndef __TEST_INTERFACE__
#define __TEST_INTERFACE__
 
	#include <iostream>
	#include <QApplication>
	#include <QWidget>
	#include <QPushButton>
	#include <QVBoxLayout>
	#include <QFileDialog>
	#include <QMessageBox>
        #include <QPointer>
 
	// Object
		class Interface : public QWidget
		{
			Q_OBJECT
 
			private :
				QVBoxLayout* 	layout;
				QPushButton	*chPpl;
 
			public :
				Interface(void);
 
			public slots :
				void loadFile(void);
				void openFile(void);
		};
 
		class Application : public QApplication
		{
			Q_OBJECT
 
			private :
				Interface	*interface;
 
			public :
				Application(int argc, char** argv);
		};
 
#endif
Interface.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
#include "interface.hpp"
// Src :
	Interface::Interface(void)
	{
		chPpl	= new QPushButton("Load a file", this);
		layout 	= new QVBoxLayout(this);
		layout->addWidget(chPpl);
		QObject::connect(chPpl,		SIGNAL(released()), this, SLOT(openFile()));
		setGeometry(1000, 100, 800, 700);
		show();
                // Si j'appelle ici, openFile() ou loadFile(), les deux fonctionnent!
	}
 
	void Interface::openFile(void)
	{
                // L'appel suivant provoque le SEGFAULT
		QString filename = QFileDialog::getOpenFileName(NULL, tr("Load a file"), ".", "*.*", NULL, QFileDialog::DontUseNativeDialog);
 
		if(!filename.isEmpty())
		{
			std::cout << "Loading : " << filename.toUtf8().constData() << std::endl;
		}
	}
 
	void Interface::loadFile(void)
	{
		std::cout << "Loading GUI..." << std::endl;
		openFile(); // Provoque le SEGFAULT
		std::cout << "...end GUI" << std::endl;
 
                // Loading file
	}
 
	Application::Application(int argc, char** argv)
	 : QApplication(argc,argv)
	{
		interface = new Interface;
                // Si j'appelle d'ici interface->loadFile() ou interface->openFile(), ils fonctionnent!
	}
main.cpp :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
 
#include "interface.hpp"
 
int main(int argc, char** argv)
{
	std::cout << "Test interface..." << std::endl;
 
	Application* a = new Application(argc, argv);
	return a->exec();
}
interface.pro (avec ou sans debug) :
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
CONFIG 		+= 	qt debug
INCLUDEPATH  	+= 	/usr/local/lib
HEADERS      	+= 	interface.hpp
SOURCES      	+= 	main.cpp \
			interface.cpp
Je suis preneur de toutes les idées!

Vous remerciant,