Seite 1 von 1

[solved] Qt 4.3.2: QSignalSpy - "no such signal ...&quo

Verfasst: 7. Mai 2008 20:49
von -=Freaky=-
hallo,

ich bin vllt. mal wieder blind, aber habe das so oft gesehen problem, dass mir (zur laufzeit) gemeldet wird "no such signal ...", obwohl keine der bekannten ursachen (Q_OBJECT, qmake ausfuehren usw.) zuzutreffen scheint.
ich nutze Qt 4.3.2 unter x11.

erstmal etwas code:

element.h:

Code: Alles auswählen

#include <QObject>
class Element: public QObject
{
	Q_OBJECT
        public:
// [ ... ]
		enum errType
		{
			INVALID_START_POINT,
			INVALID_END_POINT,
		};
        public slots:
                void setStart( const double &p_start );
                void setEnd( const double &p_end );
// [ ... ]
	signals:
		void error( errType p_err );
// [ ... ]
};
test.h:

Code: Alles auswählen

#include <QObject>
#include <QtTest>
#include <QSignalSpy>
#include <QList>
#include <QVariant>

#include "element.h"

class Test : public QObject
{
	Q_OBJECT
	private slots:
		void testElement();
};
test.cpp:

Code: Alles auswählen

#include "test.h"

void Test::testElement()
{
	Element elem1;
	QVERIFY( elem1.start() == 0.0 );
	QVERIFY( elem1.end() == 1.0 );
	
        //////////// HIER SCHEINT DER FEHLER ZU LIEGEN (??) ///////////
	QSignalSpy spy1( &elem1, SIGNAL( error( Element::errType ) ) );
	elem1.setStart( 4.2 );
	elem1.setEnd( 13.37 );
	QVERIFY( spy1.count() == 2 );
	
	spy1.clear();
	elem1.setStart( 42.0 );
	elem1.setEnd( 1.337 );
	QVERIFY( spy1.count() == 2 );
	QList< QVariant > args1 = spy1.at( 0 );
	QList< QVariant > args2 = spy1.at( 1 );
	QVERIFY( args1.at( 0 ).canConvert< Element::errType >() == true );
	QVERIFY( args1.at( 0 ) == Element::INVALID_START_POINT );
	
	QVERIFY( args1.at( 1 ).canConvert< Element::errType >() == true );
	QVERIFY( args1.at( 1 ) == Element::INVALID_END_POINT );
}

QTEST_MAIN( Test )
zuletzt noch das pro-file fuers testen (testIt.pro):

Code: Alles auswählen

TARGET = bin/testIt
TEMPLATE = app
CONFIG += qtestlib

HEADERS += src/element.h src/test.h
SOURCES += src/element.cpp src/test.cpp

OBJECTS_DIR = tmp
UI_DIR = tmp
MOC_DIR = tmp
RCC_DIR = tmp
fuehre ich nun

Code: Alles auswählen

qmake testIt.pro && make && bin/testIt
aus, bekomme ich ausgegeben

Code: Alles auswählen

********* Start testing of Test *********
Config: Using QTest library 4.3.2, Qt 4.3.2
PASS   : Test::initTestCase()
QWARN  : Test::testElement() QSignalSpy: No such signal: 'error(Element::errType)'
FAIL!  : Test::testElement() 'spy1.count() == 2' returned FALSE. ()
   Loc: [src/test.cpp(12)]
PASS   : ::cleanupTestCase()
Totals: 2 passed, 1 failed, 0 skipped
********* Finished testing of Test *********
bash-3.2$ 
wie gesagt, das problem scheint beim QSignalSpy oder in der Element-klasse zu liegen, ich weiss aber nicht genau, wo.

ich hoffe, mir kann jemand bezueglich des "no such signal ..." helfen.

danke schon einmal im Voraus!

mfg,
julian

Verfasst: 7. Mai 2008 20:56
von Christian81
Element::errType wird nicht als Datentyp erkannt und deshalb geht es nicht. Probiere mal ein int. Und dann gibt es qRegisterMetaType, siehe auch Doku von QObject::connect()

Verfasst: 8. Mai 2008 15:39
von -=Freaky=-
danke fuer die antwort, aber dasselbe kommt raus bei

Code: Alles auswählen

QSignalSpy spy1( &elem1, SIGNAL( error( int ) ) );
dann nur entsprechend "no such signal: 'error( int )'".

nun habe ich es so probiert, was quasi das beispiel aus der doku sein sollte, nur mit meinem datentyp eingesetzt:

Code: Alles auswählen

int errId = qRegisterMetaType< Element::errType >( "Element::errType" );
	QVERIFY( QMetaType::isRegistered( errId ) == true );
	QSignalSpy spy1( &elem1, SIGNAL( error( Element::errType ) ) );
hierbei bleibt die ausgabe gleich, sprich QMetaType::isRegistered( errId ) gibt scheinbar true zurueck ...

habe ich vllt. etwas falsch verstanden in bezug auf die benutzung von qRegisterMetaType()?

// edit: ich habe nun noch Q_ENUMS() ergaenzt:
element.h:

Code: Alles auswählen

#include <QObject>
class Element: public QObject
{
   Q_OBJECT
   Q_ENUMS( errType )
        public:
// [ ... ]
      enum errType
      {
         INVALID_START_POINT,
         INVALID_END_POINT,
      };
        public slots:
                void setStart( const double &p_start );
                void setEnd( const double &p_end );
// [ ... ]
   signals:
      void error( errType p_err );
// [ ... ]
};
test.h:

Code: Alles auswählen

#include <QObject>
#include <QtTest>
#include <QSignalSpy>
#include <QList>
#include <QVariant>

#include "element.h"

class Test : public QObject
{
   Q_OBJECT
   Q_ENUMS( Element::errType )
   private slots:
      void testElement();
};
bzw. in einem 2. versuch de eintrag aus test.h entfernt und in test.cpp eingetragen:

Code: Alles auswählen

Q_ENUMS( Element::errType );
QSignalSpy spy1( &elem1, SIGNAL( error( Element::errType ) ) 
... das kommt aber alles noch auf dasselbe raus.

mfg,
julian

Verfasst: 8. Mai 2008 20:36
von Christian81
Habs, es muss

Code: Alles auswählen

void error( Element2::errType p_err );
heißen. Da das ganze auf Stringvergleiche basiert ist error( errType ) != error( Element2::errType )


/edit: und gleich noch einen Bug in qmake gefunden (und gefixt) wenn qt.conf relative Pfade enthält.

Verfasst: 8. Mai 2008 21:53
von -=Freaky=-
vielen dank Christian, es funktioniert!
da haette man zwar drauf kommen koennen, weil char-pointer als signal-parameter uebergeben werden, ich waer es aber wahrscheinlich nie...

was wuerden leute wie ich bloss ohne leute wie dich machen ... ;)

mfg,
julian