Seite 1 von 2

SignalMapper bringt Programm zum Absturz

Verfasst: 14. Januar 2008 10:48
von kleineSchildy
Hallo alle zusammen,

mein Signalmapper, den ich definert habe, bringt mein Programm zum Absturz und ich weiß nicht so recht warum. Evt. seht ihr ja den Fehler.

Ich definiere in der Header-Datei meinen SignalMapper:

Code: Alles auswählen

...

class QSignalMapper;

class MySourceWindow: public QMdiSubWindow
{
    Q_OBJECT

...

private slots:
	void addToParameterList(QString);

private:
	QSignalMapper* signalLineEdits;

...
danach definier ich im Konstruktor meinen SignalMapper:

Code: Alles auswählen

...

    signalLineEdits = new QSignalMapper(this);
    connect(signalLineEdits, SIGNAL(mapped(QString)), this, SLOT(addToParameterList(QString)));

...
bis dahin hat mein Programm kein Problem. Aber kommen folgende Zeilen hinzu:

Code: Alles auswählen

void MySourceWindow::setSigmaGroupBox(QString illuType){
	qDebug("MySourceWindow::setSigmaGroupBox(%s) - Start", qPrintable(illuType));

	if(sigmaGroupBox){
		qDebug("MySourceWindow::setSigmaGroupBox() - delete sigmaGroupBox & buttonGroupBox");
		sourceMainLayout->removeWidget(sigmaGroupBox);
		sourceMainLayout->removeWidget(buttonGroupBox);
		delete buttonGroupBox;
		delete sigmaGroupBox;
	}
	if(otherGroupBox){
		qDebug("MySourceWindow::setSigmaGroupBox() - delete otherGroupBox");
		sourceMainLayout->removeWidget(otherGroupBox);
		delete otherGroupBox;
	}
	if(parameterList->contains("type")){
	    int index = parameterList->indexOf("type");
		parameterList->removeAt(index);
		parameterList->removeAt(index);								   
    }

	sigmaGroupBox = new QGroupBox(tr("Sigma"));
	sigmaGroupBoxLayout = new QGridLayout();

	if(illuType == "circle"){
		parameterList->append("type");
		parameterList->append("circle");
		sigmaInnerLineEdit = new QLineEdit();
		sigmaGroupBoxLayout->addWidget(sigmaInnerLineEdit);
		sigmaGroupBox->setLayout(sigmaGroupBoxLayout);
		sourceMainLayout->addWidget(sigmaGroupBox);

		signalLineEdits->setMapping(sigmaInnerLineEdit,"sigmaInnerLE");
		connect(sigmaInnerLineEdit, SIGNAL(textChanged(QString)), signalLineEdits, SLOT(map()));
	}
}
Und da bricht das Programm dann ab. Das geht so schnell, dass meine Debug-Nachrichten, die ich überall eingebaut habe, nicht mehr geschrieben werden und ich damit nur vermuten kann, dass der Fehler an dieser Stelle auftritt. Wenn das setMapping und connect auskommentiert ist, läuft das Programm. Die Konsole spuckt auch keinen Fehler aus.

Ich kann keinen Fehler entdecken :shock: Habt ihr eine Idee, woran es liegen könnte?

Viele Grüße
Jana

Verfasst: 14. Januar 2008 14:48
von ObeliX
Qt-doku sagt :
This class collects a set of parameterless signals, and re-emits them with integer, string or widget parameters corresponding to the object that sent the signal.
das stichwort ist "parameterless"

Gruß Obel

Verfasst: 14. Januar 2008 15:04
von kleineSchildy
Hallo Obel,

das glaube ich nicht, da im SIGNAL mehr Parameter sein können, als im SLOT verwendet werden. Aber ich habe es trotzdem mal mit dem parameterlosen SIGNAL "editingFinished ()" versucht.

Der Absturz bleibt bestehen.

Ich kann mich dunkel erinnern, dass es schonmal ging, aber ich weiß nicht, was ich geändert habe, dass sich das Programm jetzt so verhält. Ich habe schon soweit wie möglich alles auskommentiert, um das Problem einzukreisen. Ich seh es einfach nicht :evil:

Achja, im MainWindow, wo sich die SubWindows dann öffnen, befindet sich ebenfalls SignalMapper. Aber das dürfte ja eigentlich egal sein, oder?

Viele Grüße
Jana

Verfasst: 14. Januar 2008 15:13
von kleineSchildy
Hallo Elwood,

das ist dabei
signalLineEdits->setMapping(sigmaInnerLineEdit, "sigmaInnerLE");
connect(sigmaInnerLineEdit, SIGNAL(textChanged(QString)), signalLineEdits, SLOT(map()));
Viele Grüße
Jana

Verfasst: 14. Januar 2008 15:15
von ElwoodJ
Hallo,

sorry, hatte ich zu spät bemerkt. Aber ich würde mal den QString in dem SIGNAL rausnehmen.

signalLineEdits->setMapping(sigmaInnerLineEdit,"sigmaInnerLE");
connect(sigmaInnerLineEdit, SIGNAL(textChanged(QString)), signalLineEdits, SLOT(map()));

Das wird doch über das setMapping gelöst.

Gruß

Verfasst: 14. Januar 2008 15:21
von ElwoodJ
Sorry, bin etwas neben der Spur. Also weglassen kannst du QString natürlich nicht, aber die Zeile aus der Doku
This class collects a set of parameterless signals
sagt ja aus dass es nur Signals sein können ohne Parameter. Und du hast ein Signal mit QString als Parameter, was somit nicht zum Slot map() passt.

Verfasst: 14. Januar 2008 15:32
von kleineSchildy
Wie oben schon geschrieben habe ich es mit dem parameterlosen SIGNAL "editingFinished ()" versucht.

Das Ergebnis ist das gleiche. Sobald das SubWindow erzeugt wird, stürzt das Programm ab.

Viele Grüße
Jana

Verfasst: 14. Januar 2008 15:57
von Christian81
Dann wird es wohl an was anderen liegen - da ist wohl debuggen angesagt

Verfasst: 14. Januar 2008 16:06
von kleineSchildy
das habe ich auch gemerkt. Ich habe das LineEdit mal durch einen Button ersetzt (mit dem SIGNAL clicked() ). Ist genau das gleiche Problem.

Debuggen funktioniert leider nicht :(

Ich benutze dem Dev-C++ und sobald er das Makefile.Debug benutzen soll, jammert er:
cannot find -lQtGuid4
obwohl die lib eingebunden ist :? Es geht doch um die Lib, oder?

Viele Grüße
Jana

Verfasst: 14. Januar 2008 16:29
von ObeliX
ich hab den SignalMapper noch nie benutz, insofern sind das jetzt nur anregungen, die ich nur theoretisch herüberlegt habe. aber mglw. bringts ja neue ansätze für deine tests.

1) der "schlüssel" für deinen mapper ist ja immer der gleiche ("sigmaInnerLE") ... wiederspricht irgendwie der gedachten funktion

2) im doku-beispiel ist die reihenfolge
a) signalmapper anlegen
b) einzelsignale mappen (connect(...,map()) + setMapping())
c) connect(signalmapper to SLOT)
bei dir ist die abfolge (vermutlich) a), c), b).
ev. muß c) der letzte schritt sein.

3) im doku-beispiel erfolgt bei b) erst das connect() und dann das setMapping(), bei dir umgekehrt. ev. ist das ja von bedeutung.


MfG Obel

Verfasst: 14. Januar 2008 16:37
von upsala
1. Ob die Signale Parameter haben oder nicht is egal. Ein Signal kann immer mehr Parameter haben als ein Slot.
2. Die Reihenfolge von setMapping und connect ist beim QSignalMapper egal.
3. Wenn man den Debugger nicht zum laufen bekommt, kann man den Code auch mit qDebug() << "irgendwas"; zupflastern...

Verfasst: 14. Januar 2008 16:39
von Christian81
upsala hat geschrieben: 3. Wenn man den Debugger nicht zum laufen bekommt, kann man den Code auch mit qDebug() << "irgendwas"; zupflastern...
Oder mal die Forum-Suche (oder google) anwerfen - ist ein altbekanntes 'Problem'

Verfasst: 14. Januar 2008 16:55
von kleineSchildy
Hallo,

ich arbeite bereits mit qDebug... leider bringt er keine Meldung. Das Programm scheint zu schnell abzustürzen, oder kann es an etwas anderes liegen?

Hier mein Debugger:

Code: Alles auswählen

void debugOutput(QtMsgType type, const char* msg){
 	
 	//Browser-Fenster für Debugger
    static QTextBrowser* browser = new QTextBrowser();
	browser->setWindowTitle("Debug-Fenster");
	browser->move(0,0);
	browser->show();
	switch(type){
	    case QtDebugMsg:{
			browser->append(QString("Debug : %1").arg(msg));
		    break;
	    }
		case QtWarningMsg:{
			browser->append(QString("Warning : %1").arg(msg)); 
			break;
		}  
		case QtCriticalMsg:{
			browser->append(QString("Critical : %1").arg(msg)); 
			break;
		}
		case QtFatalMsg:{
			browser->append(QString("Fatal : %1").arg(msg)); 
			break;
		}
	}   
}
in der main:

Code: Alles auswählen

	//Debugger
    #ifdef Q_WS_WIN
        qInstallMsgHandler(debugOutput);
    #endif
dann brauch ich nurnoch qDebug(text) benutzen. Geht auch super. Nur an der Stelle leider nicht. Ich habe an jedem Anfang einer Funktion so eine Debugger-Nachricht. Zur Kontrolle, ob er in die Funktion springt.
Diese wird bei diesem Problem nicht geschrieben. Ich weiß aber nicht warum. Wahrscheinlich weil er mit schrieben nicht hinterher kommt?

@Obel
1) Es ist bloß ein Auszug aus meinem Code. Ich habe die anderen Maps auskommentiert, um da Problem einzukreisen. Es existieren mehrere unterschiedliche LineEdits.

Viele Grüße
Jana

Verfasst: 14. Januar 2008 17:16
von kleineSchildy
ok, ich hab jetzt auf der Konsole folgende Meldung erreicht:
QObject::connect: Cannot connect QLineEdit::textChanged(QString) to (null)::map()
Das heißt, dass der SignalMapper scheinbar nicht initialisiert ist. Aber das habe ich doch im Konstruktor mit

Code: Alles auswählen

    signalLineEdits = new QSignalMapper(this);
getan :shock:

und wenn ich es vertausche (wie unten)

Code: Alles auswählen

signalLineEdits->setMapping(profileLineEdit, "profileLE");
	connect(profileLineEdit, SIGNAL(textChanged(QString)), signalLineEdits, SLOT(map()));
dann bringt er garkeine Fehlermeldung und stürzt ab.

Ich versteh es einfach nicht :evil:


Viele Grüße
Jana

Verfasst: 14. Januar 2008 18:21
von solarix
dann bringt er garkeine Fehlermeldung und stürzt ab.
C-Grundlagen.... du schreibst ja selber vorher:
QObject::connect: Cannot connect QLineEdit::textChanged(QString) to (null)::map()
Was geschieht denn, wenn auf ein Null-Pointer eine Funktion aufgerufen wird..
Das heißt, dass der SignalMapper scheinbar nicht initialisiert ist. Aber das habe ich doch im Konstruktor mit
naja.. da haben wir zuwenig code.. entweder
a) du setzt den Pointer innerhalb deiner Klasse "MySourceWindow" wieder auf NULL
b) du ueberschreibst den Heap (oder Stack) durch einen Softwarefehler so, dass du erst hier abschmierst..
c) du ruft "setSigmaGroupBox" extern ueber einen schrottigen Pointer auf

IMHO benoetigen wir also mehr code...