SignalMapper bringt Programm zum Absturz

Alles rund um die Programmierung mit Qt
kleineSchildy
Beiträge: 76
Registriert: 16. September 2004 18:29
Wohnort: Dresden

SignalMapper bringt Programm zum Absturz

Beitrag 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
ObeliX
Beiträge: 59
Registriert: 14. November 2007 17:47

Beitrag 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
kleineSchildy
Beiträge: 76
Registriert: 16. September 2004 18:29
Wohnort: Dresden

Beitrag 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
kleineSchildy
Beiträge: 76
Registriert: 16. September 2004 18:29
Wohnort: Dresden

Beitrag von kleineSchildy »

Hallo Elwood,

das ist dabei
signalLineEdits->setMapping(sigmaInnerLineEdit, "sigmaInnerLE");
connect(sigmaInnerLineEdit, SIGNAL(textChanged(QString)), signalLineEdits, SLOT(map()));
Viele Grüße
Jana
ElwoodJ
Beiträge: 50
Registriert: 5. August 2005 09:33
Wohnort: /home/elwood

Beitrag 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ß
ElwoodJ
Beiträge: 50
Registriert: 5. August 2005 09:33
Wohnort: /home/elwood

Beitrag 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.
kleineSchildy
Beiträge: 76
Registriert: 16. September 2004 18:29
Wohnort: Dresden

Beitrag 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
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag von Christian81 »

Dann wird es wohl an was anderen liegen - da ist wohl debuggen angesagt
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kleineSchildy
Beiträge: 76
Registriert: 16. September 2004 18:29
Wohnort: Dresden

Beitrag 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
ObeliX
Beiträge: 59
Registriert: 14. November 2007 17:47

Beitrag 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
upsala
Beiträge: 3946
Registriert: 5. Februar 2006 20:52
Wohnort: Landshut
Kontaktdaten:

Beitrag 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...
Christian81
Beiträge: 7319
Registriert: 26. August 2004 14:11
Wohnort: Bremen
Kontaktdaten:

Beitrag 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'
MfG Christian

'Funktioniert nicht' ist keine Fehlerbeschreibung
kleineSchildy
Beiträge: 76
Registriert: 16. September 2004 18:29
Wohnort: Dresden

Beitrag 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
kleineSchildy
Beiträge: 76
Registriert: 16. September 2004 18:29
Wohnort: Dresden

Beitrag 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
solarix
Beiträge: 1133
Registriert: 7. Juni 2007 19:25

Beitrag 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...
Antworten