Signal exists



  • Hello,

    is it possible to determine weather a signal exists or not? For example i would like to iterate trough all QML-rootObjects and connect a signal to my Cpp slot.

    Declaration
    @QHash<QString, QPointer<QObject> > _objectList;
    QPointer<QObject> _parent;@
    Function
    @if(_parent.isNull())
    return;
    connect(_parent, SIGNAL(changed(QVariant)), this, SIGNAL(componentChanged(QVariant)));
    QList<QObject*> list = _parent.data()->findChildren<QObject*>();
    for(QList<QObject*>::const_iterator it(list.constBegin());it!=list.constEnd();++it)
    {
    if((*it)->objectName() != ""){
    _objectList.insert((*it)->objectName(), *it);
    connect(*it, SIGNAL(changed(QVariant)), this, SIGNAL(componentChanged(QVariant)));
    }
    }@
    But i don't really want/need the console output for "No such signal".



  • You could try to cast to the Class that offers the signal and if the cast fails you know that you can't connect to the signal the class offers.
    @
    MyClass : public QObject
    {
    Q_OBJECT
    signals:
    void mySignal();
    };

    someFunction()
    {
    if (dynamic_cast<MyClass*>(_parent))
    {
    connect(_parent, SIGNAL(changed(QVariant)), this, SLOT(componentChanged(QVariant)));
    }
    }
    @

    Of course that only works if you know the class beforehand.



  • Thanks, i'll give it a try.



  • Little correction. I think for the connect to work you also have to cast there, so the code should be changed to this:
    @
    someFunction()
    {
    MClass* myClass = dynamic_cast<MyClass*>(_parent);
    if (myClass)
    {
    connect(myClass, SIGNAL(changed(QVariant)), this, SLOT(componentChanged(QVariant)));
    }
    }
    @

    Also instead of dynamic_cast you can use qobject_cast


  • Lifetime Qt Champion

    Hi,

    In the absolute you don't need to pass the casted pointer to this version of connect, but in practice it's cleaner to do so and also more readable.

    casting QObject class should always be done using qobject_cast



  • Looks like i am misunderstanding something, doesn't the cast just check whether the object exists or not? Because the objects i am iterating trough obviously exists but there might be or might not be a signal named changed and that is what i want to find out. If the signal exists in the given objects or not.



  • The cast checks if the instance (the QObject pointer) can be casted to another class pointer (eg. QObject* to QWidget*). So if you know that the signal you're looking for is only in the class QWidget and not in the class QObject you can use the cast to test for the signal by implication (class A, the base class, does not have the signal; class B the derived class has the signal).

    Example:
    @
    QObject* a;
    QWidget* b;
    QPushButton* c;
    QObject* d;

    b = new QWidget();
    a = b;
    c = new QPushButton();
    d = c
    if(qobject_cast<QWidget*>(a))
    {
    // this works
    }
    if(qobject_cast<QWidget*>(d ))
    {
    // this never works
    }
    @



  • All the objects are QObjects so im still not sure how this might help me, sorry. I've got just a list of QObjects and i want to check if there is a signal going outwards this QObject or not.

    • Edit -
      I think ill work in, kind of unlogical for me at the moment why a QObject cast should determine weather a custom signal exists or not.

    • Edit 2 -
      I'm not sure if this is what i am searching for, let me discribe my problem a litte bit further:

    • I've got a QML file with several Components.
    • Some of these Components might have a custom changed signal declared.
    • I am iterating trough all Components(or QObjects) which are children of my top-level item.
    • Determine whether this Component has got a signal named changed or not
    • If it has got a changed signal it should connect the signal to a given slot.


  • If you look at "the QObject documentation":http://qt-project.org/doc/qt-4.8/qobject.html#signals you will see that QObject has no signal changed(QVariant). So the only way you can have the signal is to have a QObject derived class that implements the signal, right?

    By casting to this class (or QML component?) you can check if the QObject pointer you have is in fact a pointer to this class you're looking for (which offers the signal).

    I have not used QML yet so maybe I'm missing something.

    --Edit--
    qobject_cast does not check if the pointer is a QObject it tries to cast a pointer to an QObject derived class. If it cannot cast the pointer to a specific QObject derived class it returns a NULL pointer.



  • Well basically each component in QML is a QObject. You can simply write:
    @signal changed()@
    This will create a signal in QML for the given Component. Still it is the same QObject. Isn't there a more "default" way to check for an existing signal, or maybe even catch the "no such signal" exception if it is one.



  • Hmm maybe the name of the component is like the name of the QObject derived class in C++? Just a guess.



  • Well each component from QML is casted to a QObject Pointer. @QList<QObject*> list = _parent.data()->findChildren<QObject*>();@
    But sure the Components derive from QObject. Still the signal is a custom signal and doesn't affect the type of the Component.
    I might be wrong, still i am new to C++, Qt and QML.

    A more specific QML example:
    @import QtQuick 2.0

    Rectangle {
    width: 360
    height: 360
    signal changed()
    Text {
    text: qsTr("Hello World")
    anchors.centerIn: parent
    }
    MouseArea {
    anchors.fill: parent
    onClicked: {
    changed()
    }
    }
    }@

    I've got a signal changed() in my top-level component. On click of the MouseArea it emits the signal. Rectangle and MouseArea are default Qt(QML) Components.



  • Have you tried if casting to Rectangle works?



  • Im not sure if it is possible to cast it to a Rectangle, QML is only interpreted.

    Also please keep in mind that i am new to developement and still in education. Thanks for your time and help.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.